From 289a411545d675480f694a30c849fe6c19da66b6 Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 22 Jul 2022 23:25:35 +0200 Subject: [PATCH] Plugins - Don't dispose Plugin when disabling after it has been injected into a feature --- src/Artemis.Core/Ninject/PluginModule.cs | 2 +- .../Controls/DeviceVisualizer.cs | 11 +++++---- src/Artemis.UI.Shared/Styles/Button.axaml | 4 ++++ ...uginPrerequisitesUninstallDialogView.axaml | 17 ++++--------- ...inPrerequisitesUninstallDialogViewModel.cs | 3 ++- .../Screens/Plugins/PluginFeatureView.axaml | 24 ++++++++++++++++--- .../Screens/Plugins/PluginFeatureViewModel.cs | 23 +++++++++++++----- .../Plugins/PluginPrerequisiteViewModel.cs | 5 ++-- .../Settings/Tabs/PluginsTabView.axaml | 2 +- 9 files changed, 58 insertions(+), 33 deletions(-) diff --git a/src/Artemis.Core/Ninject/PluginModule.cs b/src/Artemis.Core/Ninject/PluginModule.cs index f6909993b..8dfed2f48 100644 --- a/src/Artemis.Core/Ninject/PluginModule.cs +++ b/src/Artemis.Core/Ninject/PluginModule.cs @@ -22,7 +22,7 @@ namespace Artemis.Core.Ninject Kernel.Components.Remove(); - Kernel.Bind().ToConstant(Plugin); + Kernel.Bind().ToConstant(Plugin).InTransientScope(); // Bind plugin service interfaces Kernel.Bind(x => diff --git a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs index 1b0c1326b..933781418 100644 --- a/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs +++ b/src/Artemis.UI.Shared/Controls/DeviceVisualizer.cs @@ -97,7 +97,7 @@ namespace Artemis.UI.Shared /// Occurs when a LED of the device has been clicked /// public event EventHandler? LedClicked; - + /// /// Occurs when the device was clicked but not on a LED. /// @@ -259,8 +259,6 @@ namespace Artemis.UI.Shared private void SetupForDevice() { - _deviceImage?.Dispose(); - _deviceImage = null; _highlightedLeds = new List(); _dimmedLeds = new List(); @@ -296,7 +294,11 @@ namespace Artemis.UI.Shared Task.Run(() => { if (device.Layout?.Image == null || !File.Exists(device.Layout.Image.LocalPath)) + { + _deviceImage?.Dispose(); + _deviceImage = null; return; + } try { @@ -312,6 +314,7 @@ namespace Artemis.UI.Shared deviceVisualizerLed.DrawBitmap(context); } + _deviceImage?.Dispose(); _deviceImage = renderTargetBitmap; Dispatcher.UIThread.Post(InvalidateMeasure); @@ -337,7 +340,5 @@ namespace Artemis.UI.Shared } #endregion - - } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/Styles/Button.axaml b/src/Artemis.UI.Shared/Styles/Button.axaml index 3fbe77b7b..2bd8aea06 100644 --- a/src/Artemis.UI.Shared/Styles/Button.axaml +++ b/src/Artemis.UI.Shared/Styles/Button.axaml @@ -44,6 +44,10 @@ + + diff --git a/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogView.axaml b/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogView.axaml index 0cde44af7..d2c15c7fd 100644 --- a/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogView.axaml +++ b/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogView.axaml @@ -35,19 +35,10 @@ IsHitTestVisible="False"> - - - - - - - - - - - - - + + + + diff --git a/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogViewModel.cs b/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogViewModel.cs index baaf5e649..d81f229ca 100644 --- a/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogViewModel.cs +++ b/src/Artemis.UI/Screens/Plugins/Dialogs/PluginPrerequisitesUninstallDialogViewModel.cs @@ -88,7 +88,8 @@ namespace Artemis.UI.Screens.Plugins // Disable all subjects that are features if still required foreach (IPrerequisitesSubject prerequisitesSubject in _subjects) { - if (prerequisitesSubject is not PluginFeatureInfo featureInfo) continue; + if (prerequisitesSubject is not PluginFeatureInfo featureInfo) + continue; // Disable the parent plugin if the feature is AlwaysEnabled if (featureInfo.AlwaysEnabled) diff --git a/src/Artemis.UI/Screens/Plugins/PluginFeatureView.axaml b/src/Artemis.UI/Screens/Plugins/PluginFeatureView.axaml index c39c97888..d9c6efbcb 100644 --- a/src/Artemis.UI/Screens/Plugins/PluginFeatureView.axaml +++ b/src/Artemis.UI/Screens/Plugins/PluginFeatureView.axaml @@ -11,12 +11,12 @@ - + - + @@ -58,12 +58,30 @@ ToolTip.Tip="Plugin requires admin rights" VerticalAlignment="Center" Margin="0 0 5 0" - IsVisible="{Binding ShowShield}" /> + IsVisible="{CompiledBinding ShowShield}" /> Enable feature + + diff --git a/src/Artemis.UI/Screens/Plugins/PluginFeatureViewModel.cs b/src/Artemis.UI/Screens/Plugins/PluginFeatureViewModel.cs index 24ffeb384..ec9f7d627 100644 --- a/src/Artemis.UI/Screens/Plugins/PluginFeatureViewModel.cs +++ b/src/Artemis.UI/Screens/Plugins/PluginFeatureViewModel.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reactive; using System.Reactive.Disposables; using System.Threading.Tasks; using Artemis.Core; @@ -37,6 +38,11 @@ namespace Artemis.UI.Screens.Plugins FeatureInfo = pluginFeatureInfo; ShowShield = FeatureInfo.Plugin.Info.RequiresAdmin && showShield; + ShowLogsFolder = ReactiveCommand.Create(ExecuteShowLogsFolder); + ViewLoadException = ReactiveCommand.Create(ExecuteViewLoadException); + InstallPrerequisites = ReactiveCommand.CreateFromTask(ExecuteInstallPrerequisites); + RemovePrerequisites = ReactiveCommand.CreateFromTask(ExecuteRemovePrerequisites); + this.WhenActivated(d => { _pluginManagementService.PluginFeatureEnabling += OnFeatureEnabling; @@ -58,6 +64,11 @@ namespace Artemis.UI.Screens.Plugins }); } + public ReactiveCommand ShowLogsFolder { get; } + public ReactiveCommand ViewLoadException { get; } + public ReactiveCommand InstallPrerequisites { get; } + public ReactiveCommand RemovePrerequisites { get; } + public PluginFeatureInfo FeatureInfo { get; } public Exception? LoadException => FeatureInfo.LoadException; @@ -80,7 +91,7 @@ namespace Artemis.UI.Screens.Plugins public bool CanRemovePrerequisites => FeatureInfo.PlatformPrerequisites.Any(p => p.UninstallActions.Any()); public bool IsPopupEnabled => CanInstallPrerequisites || CanRemovePrerequisites; - public void ShowLogsFolder() + private void ExecuteShowLogsFolder() { try { @@ -92,19 +103,19 @@ namespace Artemis.UI.Screens.Plugins } } - public void ViewLoadException() + private void ExecuteViewLoadException() { if (LoadException != null) _windowService.ShowExceptionDialog("Feature failed to enable", LoadException); } - public async Task InstallPrerequisites() + private async Task ExecuteInstallPrerequisites() { if (FeatureInfo.PlatformPrerequisites.Any()) await PluginPrerequisitesInstallDialogViewModel.Show(_windowService, new List {FeatureInfo}); } - public async Task RemovePrerequisites() + private async Task ExecuteRemovePrerequisites() { if (FeatureInfo.PlatformPrerequisites.Any(p => p.UninstallActions.Any())) { @@ -126,7 +137,7 @@ namespace Artemis.UI.Screens.Plugins this.RaisePropertyChanged(nameof(IsEnabled)); _notificationService.CreateNotification() .WithMessage($"Feature '{FeatureInfo.Name}' is in a broken state and cannot enable.") - .HavingButton(b => b.WithText("View logs").WithAction(ShowLogsFolder)) + .HavingButton(b => b.WithText("View logs").WithCommand(ShowLogsFolder)) .WithSeverity(NotificationSeverity.Error) .Show(); return; @@ -165,7 +176,7 @@ namespace Artemis.UI.Screens.Plugins { _notificationService.CreateNotification() .WithMessage($"Failed to enable '{FeatureInfo.Name}'.\r\n{e.Message}") - .HavingButton(b => b.WithText("View logs").WithAction(ShowLogsFolder)) + .HavingButton(b => b.WithText("View logs").WithCommand(ShowLogsFolder)) .WithSeverity(NotificationSeverity.Error) .Show(); } diff --git a/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteViewModel.cs b/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteViewModel.cs index ff3034746..492f704fc 100644 --- a/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteViewModel.cs +++ b/src/Artemis.UI/Screens/Plugins/PluginPrerequisiteViewModel.cs @@ -31,9 +31,8 @@ namespace Artemis.UI.Screens.Plugins ? PluginPrerequisite.InstallActions.Select(a => new PluginPrerequisiteActionViewModel(a)) : PluginPrerequisite.UninstallActions.Select(a => new PluginPrerequisiteActionViewModel(a))); - this.WhenAnyValue(x => x.Installing, x => x.Uninstalling, (i, u) => i || u).ToProperty(this, x => x.Busy, out _busy); - this.WhenAnyValue(x => x.ActiveAction, a => Actions.IndexOf(a!)).ToProperty(this, x => x.ActiveStepNumber, out _activeStepNumber); - + _busy = this.WhenAnyValue(x => x.Installing, x => x.Uninstalling, (i, u) => i || u).ToProperty(this, x => x.Busy); + _activeStepNumber = this.WhenAnyValue(x => x.ActiveAction, a => Actions.IndexOf(a!) + 1).ToProperty(this, x => x.ActiveStepNumber); this.WhenActivated(d => { diff --git a/src/Artemis.UI/Screens/Settings/Tabs/PluginsTabView.axaml b/src/Artemis.UI/Screens/Settings/Tabs/PluginsTabView.axaml index 7c2effd7c..e433ced72 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/PluginsTabView.axaml +++ b/src/Artemis.UI/Screens/Settings/Tabs/PluginsTabView.axaml @@ -16,7 +16,7 @@ - +