From 17d41647b6dbba96fbcef5251b8aeb8cb32de8a4 Mon Sep 17 00:00:00 2001 From: SpoinkyNL Date: Sun, 11 Oct 2020 22:37:39 +0200 Subject: [PATCH] Data models - Added ClearDynamicChildren method Plugins - Added async support for timed updates Plugins - Added dialog host to plugin settings window Data model visualization - Fixed some null references Data model visualization - Added check to ensure parameterless getters are present --- .../Plugins/DataModelExpansions/DataModel.cs | 13 +++++-- src/Artemis.Core/Plugins/Plugin.cs | 38 +++++++++++++++---- .../Plugins/PluginUpdateRegistration.cs | 31 +++++++++++++-- .../Shared/DataModelListViewModel.cs | 2 +- .../Shared/DataModelPropertyViewModel.cs | 4 +- .../Shared/DataModelVisualizationViewModel.cs | 3 ++ .../Plugins/PluginSettingsWindowView.xaml | 21 ++++++---- .../Plugins/PluginSettingsWindowViewModel.cs | 10 ++++- 8 files changed, 96 insertions(+), 26 deletions(-) diff --git a/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs b/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs index 3b0be36e6..bd33eccc2 100644 --- a/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs +++ b/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs @@ -67,10 +67,8 @@ namespace Artemis.Core.DataModelExpansions if (key.Contains('.')) throw new ArtemisCoreException("The provided key contains an illegal character (.)"); if (_dynamicDataModels.ContainsKey(key)) - { throw new ArtemisCoreException($"Cannot add a dynamic data model with key '{key}' " + "because the key is already in use on by another dynamic property this data model."); - } if (_dynamicDataModels.ContainsValue(dynamicDataModel)) { @@ -80,10 +78,8 @@ namespace Artemis.Core.DataModelExpansions } if (GetType().GetProperty(key) != null) - { throw new ArtemisCoreException($"Cannot add a dynamic data model with key '{key}' " + "because the key is already in use by a static property on this data model."); - } dynamicDataModel.PluginInfo = PluginInfo; dynamicDataModel.DataModelDescription = new DataModelPropertyAttribute @@ -125,6 +121,15 @@ namespace Artemis.Core.DataModelExpansions } } + /// + /// Removes all dynamic data models from this data model + /// + public void ClearDynamicChildren() + { + while (_dynamicDataModels.Any()) + RemoveDynamicChildByKey(_dynamicDataModels.First().Key); + } + /// /// Gets a dynamic data model of type by its key /// diff --git a/src/Artemis.Core/Plugins/Plugin.cs b/src/Artemis.Core/Plugins/Plugin.cs index d9020b973..d3ba8b262 100644 --- a/src/Artemis.Core/Plugins/Plugin.cs +++ b/src/Artemis.Core/Plugins/Plugin.cs @@ -23,12 +23,6 @@ namespace Artemis.Core /// public PluginConfigurationDialog ConfigurationDialog { get; protected set; } - /// - public void Dispose() - { - DisablePlugin(); - } - /// /// Called when the plugin is activated /// @@ -40,11 +34,15 @@ namespace Artemis.Core public abstract void DisablePlugin(); /// - /// Registers a timed update that whenever the plugin is enabled calls the provided at the provided + /// Registers a timed update that whenever the plugin is enabled calls the provided at the + /// provided /// /// /// The interval at which the update should occur - /// The action to call every time the interval has passed. The delta time parameter represents the time passed since the last update in seconds + /// + /// The action to call every time the interval has passed. The delta time parameter represents the + /// time passed since the last update in seconds + /// /// The resulting plugin update registration public PluginUpdateRegistration AddTimedUpdate(TimeSpan interval, Action action) { @@ -53,6 +51,24 @@ namespace Artemis.Core return new PluginUpdateRegistration(PluginInfo, interval, action); } + /// + /// Registers a timed update that whenever the plugin is enabled calls the provided at the + /// provided + /// + /// + /// The interval at which the update should occur + /// + /// The async action to call every time the interval has passed. The delta time parameter + /// represents the time passed since the last update in seconds + /// + /// The resulting plugin update registration + public PluginUpdateRegistration AddTimedUpdate(TimeSpan interval, Func asyncAction) + { + if (asyncAction == null) + throw new ArgumentNullException(nameof(asyncAction)); + return new PluginUpdateRegistration(PluginInfo, interval, asyncAction); + } + internal void SetEnabled(bool enable, bool isAutoEnable = false) { if (enable && !Enabled) @@ -123,6 +139,12 @@ namespace Artemis.Core DisablePlugin(); } + /// + public void Dispose() + { + DisablePlugin(); + } + #region Events /// diff --git a/src/Artemis.Core/Plugins/PluginUpdateRegistration.cs b/src/Artemis.Core/Plugins/PluginUpdateRegistration.cs index 7abac0172..9d658556c 100644 --- a/src/Artemis.Core/Plugins/PluginUpdateRegistration.cs +++ b/src/Artemis.Core/Plugins/PluginUpdateRegistration.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using System.Timers; using Artemis.Core.Modules; @@ -24,6 +25,19 @@ namespace Artemis.Core Start(); } + internal PluginUpdateRegistration(PluginInfo pluginInfo, TimeSpan interval, Func asyncAction) + { + PluginInfo = pluginInfo; + Interval = interval; + AsyncAction = asyncAction; + + PluginInfo.Instance.PluginEnabled += InstanceOnPluginEnabled; + PluginInfo.Instance.PluginDisabled += InstanceOnPluginDisabled; + if (PluginInfo.Instance.Enabled) + Start(); + } + + /// /// Gets the plugin info of the plugin this registration is associated with /// @@ -40,7 +54,12 @@ namespace Artemis.Core public Action Action { get; } /// - /// Starts calling the at the configured + /// Gets the task that gets called each time the update event fires + /// + public Func AsyncAction { get; } + + /// + /// Starts calling the or at the configured /// Note: Called automatically when the plugin enables /// public void Start() @@ -61,7 +80,7 @@ namespace Artemis.Core } /// - /// Stops calling the at the configured + /// Stops calling the or at the configured /// Note: Called automatically when the plugin disables /// public void Stop() @@ -90,7 +109,13 @@ namespace Artemis.Core if (PluginInfo.Instance is Module module && !module.IsUpdateAllowed) return; - Action(interval.TotalSeconds); + if (Action != null) + Action(interval.TotalSeconds); + else if (AsyncAction != null) + { + Task task = AsyncAction(interval.TotalSeconds); + task.Wait(); + } } private void InstanceOnPluginEnabled(object sender, EventArgs e) diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListViewModel.cs index a77ffd163..c0eebd90b 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelListViewModel.cs @@ -121,7 +121,7 @@ namespace Artemis.UI.Shared /// public override string ToString() { - return $"[List] {DisplayPath ?? Path} - {List.Count} item(s)"; + return $"[List] {DisplayPath ?? Path} - {List?.Count ?? 0} item(s)"; } } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertyViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertyViewModel.cs index 558e7c54e..24dcd0a6e 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertyViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelPropertyViewModel.cs @@ -57,7 +57,9 @@ namespace Artemis.UI.Shared /// public override string ToString() { - return $"[{DisplayValueType.Name}] {DisplayPath ?? Path} - {DisplayValue}"; + if (DisplayValueType != null) + return $"[{DisplayValueType.Name}] {DisplayPath ?? Path} - {DisplayValue}"; + return $"{DisplayPath ?? Path} - {DisplayValue}"; } } } \ No newline at end of file diff --git a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs index f6bcb010d..9313c0111 100644 --- a/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs +++ b/src/Artemis.UI.Shared/DataModelVisualization/Shared/DataModelVisualizationViewModel.cs @@ -193,6 +193,9 @@ namespace Artemis.UI.Shared continue; if (propertyInfo.GetCustomAttribute() != null) continue; + MethodInfo getMethod = propertyInfo.GetGetMethod(); + if (getMethod == null || getMethod.GetParameters().Any()) + continue; DataModelVisualizationViewModel child = CreateChild(dataModelUIService, childPath, GetChildDepth()); if (child != null) diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowView.xaml index 11a9251f2..c9c7d866a 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowView.xaml +++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowView.xaml @@ -18,13 +18,18 @@ d:DesignWidth="800" d:DataContext="{d:DesignInstance local:PluginSettingsWindowViewModel}" Icon="/Resources/Images/Logo/logo-512.png"> - - - - - - + + + + + + + - - + + + \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowViewModel.cs index cb06d38c4..4693ebba6 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowViewModel.cs @@ -7,12 +7,20 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins { public class PluginSettingsWindowViewModel : Conductor { + private readonly PluginConfigurationViewModel _configurationViewModel; + public PluginSettingsWindowViewModel(PluginConfigurationViewModel configurationViewModel, PackIconKind icon) { + _configurationViewModel = configurationViewModel ?? throw new ArgumentNullException(nameof(configurationViewModel)); Icon = icon; - ActiveItem = configurationViewModel ?? throw new ArgumentNullException(nameof(configurationViewModel)); + } + protected override void OnInitialActivate() + { + ActiveItem = _configurationViewModel; ActiveItem.Closed += ActiveItemOnClosed; + + base.OnInitialActivate(); } public PackIconKind Icon { get; }