diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/Timeline/IParallelCommandsViewModel.cs b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/Timeline/IParallelCommandsViewModel.cs index 251cede..48e040d 100644 --- a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/Timeline/IParallelCommandsViewModel.cs +++ b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/Timeline/IParallelCommandsViewModel.cs @@ -1,8 +1,8 @@ -using FileTime.Core.Models; +using System.Collections.ObjectModel; namespace FileTime.App.Core.ViewModels.Timeline; public interface IParallelCommandsViewModel { - BindedCollection Commands { get; } + ObservableCollection Commands { get; } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/Timeline/ITimelineViewModel.cs b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/Timeline/ITimelineViewModel.cs index bb242ca..0f00f33 100644 --- a/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/Timeline/ITimelineViewModel.cs +++ b/src/AppCommon/FileTime.App.Core.Abstraction/ViewModels/Timeline/ITimelineViewModel.cs @@ -1,8 +1,8 @@ -using FileTime.Core.Models; +using System.Collections.ObjectModel; namespace FileTime.App.Core.ViewModels.Timeline; public interface ITimelineViewModel { - BindedCollection ParallelCommandsGroups { get; } + ObservableCollection ParallelCommandsGroups { get; } } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/ViewModels/Timeline/ParallelCommandsViewModel.cs b/src/AppCommon/FileTime.App.Core/ViewModels/Timeline/ParallelCommandsViewModel.cs index e2567a6..711c4f0 100644 --- a/src/AppCommon/FileTime.App.Core/ViewModels/Timeline/ParallelCommandsViewModel.cs +++ b/src/AppCommon/FileTime.App.Core/ViewModels/Timeline/ParallelCommandsViewModel.cs @@ -1,19 +1,21 @@ -using DynamicData.Alias; -using FileTime.Core.Extensions; -using FileTime.Core.Models; +using System.Collections.ObjectModel; using FileTime.Core.Timeline; +using ObservableComputations; namespace FileTime.App.Core.ViewModels.Timeline; -public class ParallelCommandsViewModel : IParallelCommandsViewModel +public class ParallelCommandsViewModel : IParallelCommandsViewModel, IDisposable { - public BindedCollection Commands { get; } + private readonly OcConsumer _ocConsumer = new(); + public ObservableCollection Commands { get; } public ParallelCommandsViewModel(ParallelCommands parallelCommands) { Commands = parallelCommands .Commands - .Select(c => new CommandTimeStateViewModel(c) as ICommandTimeStateViewModel) - .ToBindedCollection(); + .Selecting(c => new CommandTimeStateViewModel(c) as ICommandTimeStateViewModel) + .For(_ocConsumer); } + + public void Dispose() => _ocConsumer.Dispose(); } \ No newline at end of file diff --git a/src/AppCommon/FileTime.App.Core/ViewModels/Timeline/TimelineViewModel.cs b/src/AppCommon/FileTime.App.Core/ViewModels/Timeline/TimelineViewModel.cs index 88c16ae..fadec3a 100644 --- a/src/AppCommon/FileTime.App.Core/ViewModels/Timeline/TimelineViewModel.cs +++ b/src/AppCommon/FileTime.App.Core/ViewModels/Timeline/TimelineViewModel.cs @@ -1,20 +1,22 @@ -using DynamicData.Alias; -using FileTime.Core.Extensions; -using FileTime.Core.Models; +using System.Collections.ObjectModel; using FileTime.Core.Timeline; +using ObservableComputations; namespace FileTime.App.Core.ViewModels.Timeline; -public class TimelineViewModel : ITimelineViewModel +public class TimelineViewModel : ITimelineViewModel, IDisposable { - public BindedCollection ParallelCommandsGroups { get; } + private readonly OcConsumer _ocConsumer = new(); + public ObservableCollection ParallelCommandsGroups { get; } public TimelineViewModel(ICommandScheduler commandScheduler) { ParallelCommandsGroups = commandScheduler .CommandsToRun - .Select(p => new ParallelCommandsViewModel(p) as IParallelCommandsViewModel) - .ToBindedCollection(); + .Selecting(p => new ParallelCommandsViewModel(p) as IParallelCommandsViewModel) + .For(_ocConsumer); } + + public void Dispose() => _ocConsumer.Dispose(); } \ No newline at end of file diff --git a/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Styling/ITheme.cs b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Styling/ITheme.cs index 9eb3f77..327e000 100644 --- a/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Styling/ITheme.cs +++ b/src/ConsoleApp/FileTime.ConsoleUI.App.Abstractions/Styling/ITheme.cs @@ -15,5 +15,7 @@ public interface ITheme IColor? MarkedSelectedItemBackgroundColor { get; } IColor? SelectedItemColor { get; } IColor? SelectedTabBackgroundColor { get; } + IColor? WarningForegroundColor { get; } + IColor? ErrorForegroundColor { get; } ListViewItemTheme ListViewItemTheme { get; } } \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Extensions/BindedCollectionExtensions.cs b/src/Core/FileTime.Core.Abstraction/Extensions/BindedCollectionExtensions.cs deleted file mode 100644 index 24d0eef..0000000 --- a/src/Core/FileTime.Core.Abstraction/Extensions/BindedCollectionExtensions.cs +++ /dev/null @@ -1,27 +0,0 @@ -using DynamicData; -using FileTime.Core.Models; - -namespace FileTime.Core.Extensions; - -public static class BindedCollectionExtensions -{ - public static BindedCollection ToBindedCollection(this IObservable> source) - { - return new BindedCollection(source); - } - - public static BindedCollection ToBindedCollection(this IObservable>?> source) - { - return new BindedCollection(source); - } - - public static BindedCollection ToBindedCollection(this IObservable> source) where TKey : notnull - { - return new BindedCollection(source); - } - - public static BindedCollection ToBindedCollection(this IObservable>?> source) where TKey : notnull - { - return new BindedCollection(source); - } -} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Models/BindedCollection.cs b/src/Core/FileTime.Core.Abstraction/Models/BindedCollection.cs deleted file mode 100644 index cadc1b7..0000000 --- a/src/Core/FileTime.Core.Abstraction/Models/BindedCollection.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System.Collections.ObjectModel; -using System.ComponentModel; -using DynamicData; -using PropertyChanged.SourceGenerator; - -namespace FileTime.Core.Models; - -public partial class BindedCollection : IDisposable, INotifyPropertyChanged -{ - private readonly IDisposable? _disposable; - private IDisposable? _innerDisposable; - - [Notify] private ReadOnlyObservableCollection? _collection; - - public BindedCollection() - { - } - - public BindedCollection(IObservable> dynamicList) - { - _disposable = dynamicList - .Bind(out var collection) - .DisposeMany() - .Subscribe(); - - _collection = collection; - } - - public BindedCollection(IObservable>?> dynamicListSource) - { - _disposable = dynamicListSource.Subscribe(dynamicList => - { - _innerDisposable?.Dispose(); - if (dynamicList is not null) - { - _innerDisposable = dynamicList - .Bind(out var collection) - .DisposeMany() - .Subscribe(); - - Collection = collection; - } - else - { - Collection = null; - } - }); - } - - public void Dispose() - { - _disposable?.Dispose(); - _innerDisposable?.Dispose(); - GC.SuppressFinalize(this); - } -} - -public partial class BindedCollection : IDisposable, INotifyPropertyChanged where TKey : notnull -{ - private readonly IDisposable? _disposable; - private IDisposable? _innerDisposable; - - [Notify] private ReadOnlyObservableCollection? _collection; - - public BindedCollection() - { - } - - public BindedCollection(IObservable> dynamicList) - { - _disposable = dynamicList - .Bind(out var collection) - .DisposeMany() - .Subscribe(); - - _collection = collection; - } - - public BindedCollection(IObservable>?> dynamicListSource) - { - _disposable = dynamicListSource.Subscribe(dynamicList => - { - _innerDisposable?.Dispose(); - if (dynamicList is not null) - { - _innerDisposable = dynamicList - .Bind(out var collection) - .DisposeMany() - .Subscribe(); - - Collection = collection; - } - else - { - Collection = null; - } - }); - } - - public void Dispose() - { - _disposable?.Dispose(); - _innerDisposable?.Dispose(); - GC.SuppressFinalize(this); - } -} \ No newline at end of file diff --git a/src/Core/FileTime.Core.Abstraction/Timeline/ICommandScheduler.cs b/src/Core/FileTime.Core.Abstraction/Timeline/ICommandScheduler.cs index 84c2249..1a78912 100644 --- a/src/Core/FileTime.Core.Abstraction/Timeline/ICommandScheduler.cs +++ b/src/Core/FileTime.Core.Abstraction/Timeline/ICommandScheduler.cs @@ -1,4 +1,4 @@ -using DynamicData; +using System.Collections.ObjectModel; using FileTime.Core.Command; using FileTime.Core.Models; @@ -8,7 +8,7 @@ public interface ICommandScheduler { Task AddCommand(ICommand command, int? batchId = null, bool toNewBatch = false); IObservable ContainerToRefresh { get; } - IObservable> CommandsToRun { get; } + ReadOnlyObservableCollection CommandsToRun { get; } bool IsRunningEnabled { get; } void RefreshContainer(FullName container); Task SetRunningEnabledAsync(bool value); diff --git a/src/Core/FileTime.Core.Abstraction/Timeline/ParallelCommands.cs b/src/Core/FileTime.Core.Abstraction/Timeline/ParallelCommands.cs index bba72dd..6b7c1da 100644 --- a/src/Core/FileTime.Core.Abstraction/Timeline/ParallelCommands.cs +++ b/src/Core/FileTime.Core.Abstraction/Timeline/ParallelCommands.cs @@ -1,21 +1,17 @@ -using DynamicData; +using System.Collections.ObjectModel; using FileTime.Core.Command; -using FileTime.Core.Extensions; -using FileTime.Core.Models; namespace FileTime.Core.Timeline; -public class ParallelCommands : IDisposable +public class ParallelCommands { private static ushort _idCounter; - private readonly SourceList _commands; + private readonly ObservableCollection _commands; private PointInTime? _startTime; public ushort Id { get; } - public IObservable> Commands { get; } - - public BindedCollection CommandsCollection { get; } + public ReadOnlyObservableCollection Commands { get; } public int CommandCount => _commands.Count; public PointInTime? Result { get; private set; } @@ -37,10 +33,8 @@ public class ParallelCommands : IDisposable { Id = _idCounter++; - _commands = new SourceList(); - _commands.Edit((innerList) => innerList.AddRange(commands)); - Commands = _commands.Connect(); - CommandsCollection = Commands.ToBindedCollection(); + _commands = new ObservableCollection(commands); + Commands = new(_commands); Result = result; } @@ -85,7 +79,7 @@ public class ParallelCommands : IDisposable public async Task RemoveCommand(ICommand command) { - var commandTimeState = _commands.Items.First(c => c.Command == command); + var commandTimeState = _commands.First(c => c.Command == command); _commands.Remove(commandTimeState); await RefreshResult(); } @@ -93,7 +87,7 @@ public class ParallelCommands : IDisposable public async Task RefreshResult() { var result = StartTime; - foreach (var commandTimeState in _commands.Items) + foreach (var commandTimeState in _commands) { await commandTimeState.UpdateStateAsync(result); if (result != null) @@ -113,9 +107,4 @@ public class ParallelCommands : IDisposable Result = result; return Result; } - - public void Dispose() - { - CommandsCollection.Dispose(); - } } \ No newline at end of file diff --git a/src/Core/FileTime.Core.Timeline/CommandScheduler.cs b/src/Core/FileTime.Core.Timeline/CommandScheduler.cs index cc9bc73..372e4d9 100644 --- a/src/Core/FileTime.Core.Timeline/CommandScheduler.cs +++ b/src/Core/FileTime.Core.Timeline/CommandScheduler.cs @@ -1,6 +1,6 @@ +using System.Collections.ObjectModel; using System.Reactive.Linq; using System.Reactive.Subjects; -using DynamicData; using FileTime.Core.Command; using FileTime.Core.Models; @@ -8,7 +8,7 @@ namespace FileTime.Core.Timeline; public class CommandScheduler : ICommandScheduler { - private readonly SourceList _commandsToRun = new(); + private readonly ObservableCollection _commandsToRun = new(); private readonly List _commandExecutors = new(); private readonly Subject _containerToRefresh = new(); @@ -29,11 +29,11 @@ public class CommandScheduler : ICommandScheduler } } - public IObservable> CommandsToRun { get; } + public ReadOnlyObservableCollection CommandsToRun { get; } public CommandScheduler(ILocalCommandExecutor localExecutor) { - CommandsToRun = _commandsToRun.Connect(); + CommandsToRun = new(_commandsToRun); ContainerToRefresh = _containerToRefresh.AsObservable(); @@ -55,16 +55,16 @@ public class CommandScheduler : ICommandScheduler } else if (toNewBatch) { - batchToAdd = new ParallelCommands(_commandsToRun.Items.Last().Result); + batchToAdd = new ParallelCommands(_commandsToRun.Last().Result); _commandsToRun.Add(batchToAdd); } - else if (batchId != null && _commandsToRun.Items.First(b => b.Id == batchId) is { } parallelCommands) + else if (batchId != null && _commandsToRun.First(b => b.Id == batchId) is { } parallelCommands) { batchToAdd = parallelCommands; } else { - batchToAdd = _commandsToRun.Items.First(); + batchToAdd = _commandsToRun.First(); } await batchToAdd.AddCommand(command); @@ -88,13 +88,13 @@ public class CommandScheduler : ICommandScheduler { if (!_isRunningEnabled) return; - var commandsToExecute = _commandsToRun.Items.FirstOrDefault()?.CommandsCollection.Collection; + var commandsToExecute = _commandsToRun.FirstOrDefault()?.Commands; if (commandsToExecute is null || commandsToExecute.All(c => c.ExecutionState != ExecutionState.Initializing && c.ExecutionState != ExecutionState.Waiting)) return; foreach (var commandToExecute in commandsToExecute) { if (commandToExecute.ExecutionState != ExecutionState.Waiting - && commandToExecute.ExecutionState != ExecutionState.Initializing ) + && commandToExecute.ExecutionState != ExecutionState.Initializing) { continue; } @@ -113,17 +113,14 @@ public class CommandScheduler : ICommandScheduler return _commandExecutors[0]; } - private async void ExecutorOnCommandFinished(object? sender, ICommand command) - { + private async void ExecutorOnCommandFinished(object? sender, ICommand command) => await RunWithLockAsync(async () => { var firstCommandBlock = _commandsToRun - .Items .FirstOrDefault(); var state = firstCommandBlock - ?.CommandsCollection - .Collection - ?.FirstOrDefault(c => c.Command == command); + ?.Commands + .FirstOrDefault(c => c.Command == command); if (state is null) return; @@ -137,13 +134,12 @@ public class CommandScheduler : ICommandScheduler } } }); - } private async Task RefreshCommands() { var currentTime = PointInTime.CreateEmpty(); - foreach (var batch in _commandsToRun.Items) + foreach (var batch in _commandsToRun) { currentTime = await batch.SetStartTimeAsync(currentTime); } diff --git a/src/GuiApp/Avalonia/FileTime.GuiApp.App/Views/MainWindow.axaml b/src/GuiApp/Avalonia/FileTime.GuiApp.App/Views/MainWindow.axaml index 7491ffc..a2ecc99 100644 --- a/src/GuiApp/Avalonia/FileTime.GuiApp.App/Views/MainWindow.axaml +++ b/src/GuiApp/Avalonia/FileTime.GuiApp.App/Views/MainWindow.axaml @@ -321,7 +321,7 @@ @@ -333,7 +333,7 @@ - +