mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Editor - Fixed a bunch of memory leaks
This commit is contained in:
parent
84b394fc51
commit
9da71f7b97
@ -60,12 +60,7 @@ public interface IProfileEditorService : IArtemisSharedUIService
|
||||
/// Gets an observable of the suspended keybindings state.
|
||||
/// </summary>
|
||||
IObservable<ProfileEditorFocusMode> FocusMode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an observable read only collection of all available editor tools.
|
||||
/// </summary>
|
||||
ReadOnlyObservableCollection<IToolViewModel> Tools { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets an observable read only collection of selected keyframes.
|
||||
/// </summary>
|
||||
@ -209,16 +204,4 @@ public interface IProfileEditorService : IArtemisSharedUIService
|
||||
/// Pauses profile preview playback.
|
||||
/// </summary>
|
||||
void Pause();
|
||||
|
||||
/// <summary>
|
||||
/// Adds a profile editor tool by it's view model.
|
||||
/// </summary>
|
||||
/// <param name="toolViewModel">The view model of the tool to add.</param>
|
||||
void AddTool(IToolViewModel toolViewModel);
|
||||
|
||||
/// <summary>
|
||||
/// Removes a profile editor tool by it's view model.
|
||||
/// </summary>
|
||||
/// <param name="toolViewModel">The view model of the tool to remove.</param>
|
||||
void RemoveTool(IToolViewModel toolViewModel);
|
||||
}
|
||||
@ -33,7 +33,6 @@ internal class ProfileEditorService : IProfileEditorService
|
||||
private readonly BehaviorSubject<bool> _suspendedKeybindingsSubject = new(false);
|
||||
private readonly BehaviorSubject<ProfileEditorFocusMode> _focusModeSubject = new(ProfileEditorFocusMode.None);
|
||||
private readonly BehaviorSubject<TimeSpan> _timeSubject = new(TimeSpan.Zero);
|
||||
private readonly SourceList<IToolViewModel> _tools;
|
||||
private readonly SourceList<ILayerPropertyKeyframe> _selectedKeyframes;
|
||||
private readonly IWindowService _windowService;
|
||||
private ProfileEditorCommandScope? _profileEditorHistoryScope;
|
||||
@ -53,10 +52,7 @@ internal class ProfileEditorService : IProfileEditorService
|
||||
_layerBrushService = layerBrushService;
|
||||
_windowService = windowService;
|
||||
|
||||
_tools = new SourceList<IToolViewModel>();
|
||||
_selectedKeyframes = new SourceList<ILayerPropertyKeyframe>();
|
||||
_tools.Connect().AutoRefreshOnObservable(t => t.WhenAnyValue(vm => vm.IsSelected)).Subscribe(OnToolSelected);
|
||||
_tools.Connect().Bind(out ReadOnlyObservableCollection<IToolViewModel> tools).Subscribe();
|
||||
_selectedKeyframes.Connect().Bind(out ReadOnlyObservableCollection<ILayerPropertyKeyframe> selectedKeyframes).Subscribe();
|
||||
|
||||
ProfileConfiguration = _profileConfigurationSubject.AsObservable();
|
||||
@ -69,8 +65,6 @@ internal class ProfileEditorService : IProfileEditorService
|
||||
SuspendedKeybindings = _suspendedKeybindingsSubject.AsObservable();
|
||||
PixelsPerSecond = _pixelsPerSecondSubject.AsObservable();
|
||||
FocusMode = _focusModeSubject.AsObservable();
|
||||
|
||||
Tools = tools;
|
||||
SelectedKeyframes = selectedKeyframes;
|
||||
|
||||
// Observe executing, undoing and redoing commands and run the auto-save after 1 second
|
||||
@ -100,7 +94,6 @@ internal class ProfileEditorService : IProfileEditorService
|
||||
public IObservable<bool> Playing { get; }
|
||||
public IObservable<int> PixelsPerSecond { get; }
|
||||
public IObservable<ProfileEditorFocusMode> FocusMode { get; }
|
||||
public ReadOnlyObservableCollection<IToolViewModel> Tools { get; }
|
||||
public ReadOnlyObservableCollection<ILayerPropertyKeyframe> SelectedKeyframes { get; }
|
||||
|
||||
public void ChangeCurrentProfileConfiguration(ProfileConfiguration? profileConfiguration)
|
||||
@ -384,19 +377,7 @@ internal class ProfileEditorService : IProfileEditorService
|
||||
if (_playingSubject.Value)
|
||||
_playingSubject.OnNext(false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void AddTool(IToolViewModel toolViewModel)
|
||||
{
|
||||
_tools.Add(toolViewModel);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void RemoveTool(IToolViewModel toolViewModel)
|
||||
{
|
||||
_tools.Remove(toolViewModel);
|
||||
}
|
||||
|
||||
|
||||
#region Commands
|
||||
|
||||
public void ExecuteCommand(IProfileEditorCommand command)
|
||||
@ -451,22 +432,7 @@ internal class ProfileEditorService : IProfileEditorService
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void OnToolSelected(IChangeSet<IToolViewModel> changeSet)
|
||||
{
|
||||
IToolViewModel? changed = changeSet.FirstOrDefault()?.Item.Current;
|
||||
if (changed == null)
|
||||
return;
|
||||
|
||||
// Disable all others if the changed one is selected and exclusive
|
||||
if (changed.IsSelected && changed.IsExclusive)
|
||||
_tools.Edit(list =>
|
||||
{
|
||||
foreach (IToolViewModel toolViewModel in list.Where(t => t.IsExclusive && t != changed))
|
||||
toolViewModel.IsSelected = false;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private ProfileEditorHistory? GetHistory(ProfileConfiguration? profileConfiguration)
|
||||
{
|
||||
if (profileConfiguration == null)
|
||||
|
||||
@ -62,7 +62,8 @@ public abstract class TreeItemViewModel : ActivatableViewModelBase
|
||||
_isFocused = ProfileEditorService.FocusMode
|
||||
.CombineLatest(ProfileEditorService.ProfileElement)
|
||||
.Select(tuple => GetIsFocused(tuple.First, tuple.Second))
|
||||
.ToProperty(this, vm => vm.IsFocused);
|
||||
.ToProperty(this, vm => vm.IsFocused)
|
||||
.DisposeWith(d);
|
||||
|
||||
ProfileEditorService.Time.Subscribe(t => _time = t).DisposeWith(d);
|
||||
ProfileEditorService.ProfileElement.Subscribe(element => _currentProfileElement = element).DisposeWith(d);
|
||||
|
||||
@ -43,15 +43,6 @@ public class VisualEditorViewModel : ActivatableViewModelBase
|
||||
_suspendedEditing = profileEditorService.SuspendedEditing.ToProperty(this, vm => vm.SuspendedEditing).DisposeWith(d);
|
||||
profileEditorService.ProfileConfiguration.Subscribe(CreateVisualizers).DisposeWith(d);
|
||||
|
||||
profileEditorService.Tools
|
||||
.ToObservableChangeSet()
|
||||
.AutoRefreshOnObservable(t => t.WhenAnyValue(vm => vm.IsSelected))
|
||||
.Filter(t => t.IsSelected)
|
||||
.Bind(out ReadOnlyObservableCollection<IToolViewModel> tools)
|
||||
.Subscribe()
|
||||
.DisposeWith(d);
|
||||
Tools = tools;
|
||||
|
||||
this.WhenAnyValue(vm => vm.ProfileConfiguration)
|
||||
.Select(p => p?.Profile)
|
||||
.Select(p => p != null
|
||||
@ -74,15 +65,15 @@ public class VisualEditorViewModel : ActivatableViewModelBase
|
||||
public ProfileConfiguration? ProfileConfiguration => _profileConfiguration?.Value;
|
||||
public bool SuspendedEditing => _suspendedEditing?.Value ?? false;
|
||||
|
||||
public ObservableCollection<ArtemisDevice> Devices { get; }
|
||||
public ReadOnlyObservableCollection<IVisualizerViewModel> Visualizers { get; }
|
||||
|
||||
public ReadOnlyObservableCollection<IToolViewModel>? Tools
|
||||
{
|
||||
get => _tools;
|
||||
set => RaiseAndSetIfChanged(ref _tools, value);
|
||||
}
|
||||
|
||||
public ReadOnlyObservableCollection<IVisualizerViewModel> Visualizers { get; }
|
||||
public ObservableCollection<ArtemisDevice> Devices { get; }
|
||||
|
||||
private void RemoveElement(EventPattern<ProfileElementEventArgs> eventPattern)
|
||||
{
|
||||
List<IVisualizerViewModel> visualizers = Visualizers.Where(v => v.ProfileElement == eventPattern.EventArgs.ProfileElement).ToList();
|
||||
@ -113,7 +104,17 @@ public class VisualEditorViewModel : ActivatableViewModelBase
|
||||
visualizerViewModels.Add(_vmFactory.LayerShapeVisualizerViewModel(layer));
|
||||
visualizerViewModels.Add(_vmFactory.LayerVisualizerViewModel(layer));
|
||||
}
|
||||
|
||||
|
||||
public void SetTools(SourceList<IToolViewModel> tools)
|
||||
{
|
||||
tools.Connect()
|
||||
.AutoRefreshOnObservable(t => t.WhenAnyValue(vm => vm.IsSelected))
|
||||
.Filter(t => t.IsSelected)
|
||||
.Bind(out ReadOnlyObservableCollection<IToolViewModel> selectedTools)
|
||||
.Subscribe();
|
||||
Tools = selectedTools;
|
||||
}
|
||||
|
||||
public void RequestAutoFit()
|
||||
{
|
||||
AutoFitRequested?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Disposables;
|
||||
using Artemis.Core;
|
||||
@ -21,10 +23,10 @@ public class ProfileEditorViewModel : MainScreenViewModel
|
||||
{
|
||||
private readonly IProfileEditorService _profileEditorService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly SourceList<IToolViewModel> _tools;
|
||||
private ObservableAsPropertyHelper<ProfileEditorHistory?>? _history;
|
||||
private ObservableAsPropertyHelper<ProfileConfiguration?>? _profileConfiguration;
|
||||
private ObservableAsPropertyHelper<bool>? _suspendedEditing;
|
||||
private ReadOnlyObservableCollection<IToolViewModel>? _tools;
|
||||
private StatusBarViewModel _statusBarViewModel;
|
||||
private DisplayConditionScriptViewModel _displayConditionScriptViewModel;
|
||||
private PropertiesViewModel _propertiesViewModel;
|
||||
@ -40,26 +42,30 @@ public class ProfileEditorViewModel : MainScreenViewModel
|
||||
ProfileEditorTitleBarViewModel profileEditorTitleBarViewModel,
|
||||
PropertiesViewModel propertiesViewModel,
|
||||
DisplayConditionScriptViewModel displayConditionScriptViewModel,
|
||||
StatusBarViewModel statusBarViewModel)
|
||||
StatusBarViewModel statusBarViewModel,
|
||||
IEnumerable<IToolViewModel> toolViewModels)
|
||||
: base(hostScreen, "profile-editor")
|
||||
{
|
||||
_profileEditorService = profileEditorService;
|
||||
_settingsService = settingsService;
|
||||
|
||||
_tools = new SourceList<IToolViewModel>();
|
||||
_tools.AddRange(toolViewModels);
|
||||
_tools.Connect().AutoRefreshOnObservable(t => t.WhenAnyValue(vm => vm.IsSelected)).Subscribe(OnToolSelected);
|
||||
_tools.Connect()
|
||||
.Filter(t => t.ShowInToolbar)
|
||||
.Sort(SortExpressionComparer<IToolViewModel>.Ascending(vm => vm.Order))
|
||||
.Bind(out ReadOnlyObservableCollection<IToolViewModel> tools)
|
||||
.Subscribe();
|
||||
Tools = tools;
|
||||
visualEditorViewModel.SetTools(_tools);
|
||||
|
||||
this.WhenActivated(d =>
|
||||
{
|
||||
_profileConfiguration = profileEditorService.ProfileConfiguration.ToProperty(this, vm => vm.ProfileConfiguration).DisposeWith(d);
|
||||
_history = profileEditorService.History.ToProperty(this, vm => vm.History).DisposeWith(d);
|
||||
_suspendedEditing = profileEditorService.SuspendedEditing.ToProperty(this, vm => vm.SuspendedEditing).DisposeWith(d);
|
||||
profileEditorService.Tools
|
||||
.ToObservableChangeSet()
|
||||
.Filter(t => t.ShowInToolbar)
|
||||
.Sort(SortExpressionComparer<IToolViewModel>.Ascending(vm => vm.Order))
|
||||
.Bind(out ReadOnlyObservableCollection<IToolViewModel> tools)
|
||||
.Subscribe()
|
||||
.DisposeWith(d);
|
||||
Tools = tools;
|
||||
|
||||
|
||||
// Slow and steady wins the race (and doesn't lock up the entire UI)
|
||||
Dispatcher.UIThread.Post(() => StatusBarViewModel = statusBarViewModel, DispatcherPriority.Loaded);
|
||||
Dispatcher.UIThread.Post(() => VisualEditorViewModel = visualEditorViewModel, DispatcherPriority.Loaded);
|
||||
@ -103,12 +109,7 @@ public class ProfileEditorViewModel : MainScreenViewModel
|
||||
set => RaiseAndSetIfChanged(ref _statusBarViewModel, value);
|
||||
}
|
||||
|
||||
public ReadOnlyObservableCollection<IToolViewModel>? Tools
|
||||
{
|
||||
get => _tools;
|
||||
set => RaiseAndSetIfChanged(ref _tools, value);
|
||||
}
|
||||
|
||||
public ReadOnlyObservableCollection<IToolViewModel> Tools { get; }
|
||||
public ProfileConfiguration? ProfileConfiguration => _profileConfiguration?.Value;
|
||||
public ProfileEditorHistory? History => _history?.Value;
|
||||
public bool SuspendedEditing => _suspendedEditing?.Value ?? false;
|
||||
@ -134,4 +135,21 @@ public class ProfileEditorViewModel : MainScreenViewModel
|
||||
setting.Value = !setting.Value;
|
||||
setting.Save();
|
||||
}
|
||||
|
||||
private void OnToolSelected(IChangeSet<IToolViewModel> changeSet)
|
||||
{
|
||||
IToolViewModel? changed = changeSet.FirstOrDefault()?.Item.Current;
|
||||
if (changed == null)
|
||||
return;
|
||||
|
||||
if (!changed.IsSelected || !changed.IsExclusive)
|
||||
return;
|
||||
|
||||
// Disable all others if the changed one is selected and exclusive
|
||||
_tools.Edit(list =>
|
||||
{
|
||||
foreach (IToolViewModel toolViewModel in list.Where(t => t.IsExclusive && t != changed))
|
||||
toolViewModel.IsSelected = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -27,14 +27,14 @@ public class RegistrationService : IRegistrationService
|
||||
private readonly IDataModelUIService _dataModelUIService;
|
||||
private bool _registeredBuiltInPropertyEditors;
|
||||
|
||||
public RegistrationService(IKernel kernel,
|
||||
IInputService inputService,
|
||||
public RegistrationService(IKernel kernel,
|
||||
IInputService inputService,
|
||||
IPropertyInputService propertyInputService,
|
||||
IProfileEditorService profileEditorService,
|
||||
INodeService nodeService,
|
||||
INodeService nodeService,
|
||||
IDataModelUIService dataModelUIService,
|
||||
IDeviceLayoutService deviceLayoutService, // here to make sure it is instantiated
|
||||
IEnumerable<IToolViewModel> toolViewModels)
|
||||
IDeviceLayoutService deviceLayoutService // here to make sure it is instantiated
|
||||
)
|
||||
{
|
||||
_kernel = kernel;
|
||||
_inputService = inputService;
|
||||
@ -42,8 +42,6 @@ public class RegistrationService : IRegistrationService
|
||||
_nodeService = nodeService;
|
||||
_dataModelUIService = dataModelUIService;
|
||||
|
||||
foreach (IToolViewModel toolViewModel in toolViewModels)
|
||||
profileEditorService.AddTool(toolViewModel);
|
||||
CreateCursorResources();
|
||||
}
|
||||
|
||||
@ -90,7 +88,7 @@ public class RegistrationService : IRegistrationService
|
||||
public void RegisterControllers()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public void RegisterBuiltInNodeTypes()
|
||||
{
|
||||
_nodeService.RegisterTypeColor(Constants.CorePlugin, typeof(bool), new SKColor(0xFFCD3232));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user