1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-12 21:38:38 +00:00

Fixed VM disposal issues

This commit is contained in:
Robert 2023-05-12 23:27:27 +02:00
parent 5adc837673
commit e783dcaa58
8 changed files with 17 additions and 36 deletions

View File

@ -11,10 +11,9 @@ public static class LinuxInputDeviceFinder
public static IEnumerable<LinuxInputDevice> Find()
{
var lineGroups = File.ReadAllLines(DEVICES_FILE)
.PartitionBy(s => s?.Length == 0); //split on empty lines
IEnumerable<IEnumerable<string>> lineGroups = File.ReadAllLines(DEVICES_FILE).PartitionBy(s => s?.Length == 0); //split on empty lines
foreach (var lineGroup in lineGroups)
foreach (IEnumerable<string> lineGroup in lineGroups)
{
LinuxInputDevice device;

View File

@ -54,7 +54,7 @@ internal class PropertyInputService : IPropertyInputService
return existing;
}
_container.Register(viewModelType);
_container.Register(viewModelType, setup: Setup.With(preventDisposal: true));
PropertyInputRegistration registration = new(this, plugin, supportedType, viewModelType);
_registeredPropertyEditors.Add(registration);
return registration;

View File

@ -220,7 +220,7 @@ public abstract class PropertyInputViewModel<T> : PropertyInputViewModel
/// <summary>
/// For internal use only, implement <see cref="PropertyInputViewModel" /> instead.
/// </summary>
public abstract class PropertyInputViewModel : ReactiveValidationObject, IActivatableViewModel, IDisposable
public abstract class PropertyInputViewModel : ReactiveValidationObject, IActivatableViewModel
{
/// <summary>
/// Prevents this type being implemented directly, implement
@ -228,29 +228,7 @@ public abstract class PropertyInputViewModel : ReactiveValidationObject, IActiva
/// </summary>
// ReSharper disable once UnusedMember.Global
internal abstract object InternalGuard { get; }
/// <summary>
/// Releases the unmanaged resources used by the object and optionally releases the managed resources.
/// </summary>
/// <param name="disposing">
/// <see langword="true" /> to release both managed and unmanaged resources;
/// <see langword="false" /> to release only unmanaged resources.
/// </param>
protected virtual void Dispose(bool disposing)
{
}
#region Implementation of IActivatableViewModel
/// <inheritdoc />
public ViewModelActivator Activator { get; } = new();
#endregion
/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}

View File

@ -25,7 +25,7 @@ public static class ContainerExtensions
Assembly[] thisAssembly = {typeof(ContainerExtensions).Assembly};
container.RegisterMany(thisAssembly, type => type.IsAssignableTo<ViewModelBase>(), setup: Setup.With(preventDisposal: true));
container.RegisterMany(thisAssembly, type => type.IsAssignableTo<IToolViewModel>() && type.IsInterface);
container.RegisterMany(thisAssembly, type => type.IsAssignableTo<IToolViewModel>() && type.IsInterface, setup: Setup.With(preventDisposal: true));
container.RegisterMany(thisAssembly, type => type.IsAssignableTo<IVmFactory>() && type != typeof(PropertyVmFactory));
container.Register<NodeScriptWindowViewModelBase, NodeScriptWindowViewModel>(Reuse.Singleton);

View File

@ -13,7 +13,8 @@
VerticalAlignment="Top"
Source="/Assets/Images/home-banner.png"
Height="200"
Stretch="UniformToFill" />
Stretch="UniformToFill"
RenderOptions.BitmapInterpolationMode="HighQuality"/>
<!-- TODO: Replace with a shadow when available -->
<TextBlock Grid.Row="0"

View File

@ -17,9 +17,13 @@ public partial class TreePropertyView : ReactiveUserControl<ITreePropertyViewMod
InitializeComponent();
this.WhenActivated(d =>
{
Observable.FromEventPattern<LayerPropertyEventArgs>(e => ViewModel!.BaseLayerProperty.CurrentValueSet += e, e => ViewModel!.BaseLayerProperty.CurrentValueSet -= e)
.Subscribe(_ => this.BringIntoView())
.DisposeWith(d);
ITreePropertyViewModel? viewModel = ViewModel;
if (viewModel != null)
{
Observable.FromEventPattern<LayerPropertyEventArgs>(e => viewModel.BaseLayerProperty.CurrentValueSet += e, e => viewModel.BaseLayerProperty.CurrentValueSet -= e)
.Subscribe(_ => this.BringIntoView())
.DisposeWith(d);
}
});
}

View File

@ -32,7 +32,6 @@ internal class TreePropertyViewModel<T> : ActivatableViewModelBase, ITreePropert
_profileEditorService.Time.Subscribe(t => _time = t).DisposeWith(d);
_isCurrentlySelected = _profileEditorService.LayerProperty.Select(l => l == LayerProperty).ToProperty(this, vm => vm.IsCurrentlySelected).DisposeWith(d);
_dataBindingEnabled = LayerProperty.BaseDataBinding.AsObservable().Select(b => b.IsEnabled).ToProperty(this, vm => vm.DataBindingEnabled).DisposeWith(d);
this.WhenAnyValue(vm => vm.LayerProperty.KeyframesEnabled).Subscribe(_ => this.RaisePropertyChanged(nameof(KeyframesEnabled))).DisposeWith(d);
});

View File

@ -22,7 +22,6 @@ namespace Artemis.UI.Screens.ProfileEditor;
public class ProfileEditorViewModel : MainScreenViewModel
{
private readonly IMainWindowService _mainWindowService;
private readonly IProfileEditorService _profileEditorService;
private readonly ISettingsService _settingsService;
private readonly SourceList<IToolViewModel> _tools;
@ -51,7 +50,6 @@ public class ProfileEditorViewModel : MainScreenViewModel
{
_profileEditorService = profileEditorService;
_settingsService = settingsService;
_mainWindowService = mainWindowService;
_tools = new SourceList<IToolViewModel>();
_tools.AddRange(toolViewModels);
@ -77,6 +75,8 @@ public class ProfileEditorViewModel : MainScreenViewModel
{
mainWindowService.MainWindowFocused -= MainWindowServiceOnMainWindowFocused;
mainWindowService.MainWindowUnfocused -= MainWindowServiceOnMainWindowUnfocused;
foreach (IToolViewModel toolViewModel in _tools.Items)
toolViewModel.Dispose();
}).DisposeWith(d);
// Slow and steady wins the race (and doesn't lock up the entire UI)