1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2026-01-02 10:43:31 +00:00

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
This commit is contained in:
SpoinkyNL 2020-10-11 22:37:39 +02:00
parent c095f329c4
commit 17d41647b6
8 changed files with 96 additions and 26 deletions

View File

@ -67,10 +67,8 @@ namespace Artemis.Core.DataModelExpansions
if (key.Contains('.')) if (key.Contains('.'))
throw new ArtemisCoreException("The provided key contains an illegal character (.)"); throw new ArtemisCoreException("The provided key contains an illegal character (.)");
if (_dynamicDataModels.ContainsKey(key)) if (_dynamicDataModels.ContainsKey(key))
{
throw new ArtemisCoreException($"Cannot add a dynamic data model with key '{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."); "because the key is already in use on by another dynamic property this data model.");
}
if (_dynamicDataModels.ContainsValue(dynamicDataModel)) if (_dynamicDataModels.ContainsValue(dynamicDataModel))
{ {
@ -80,10 +78,8 @@ namespace Artemis.Core.DataModelExpansions
} }
if (GetType().GetProperty(key) != null) if (GetType().GetProperty(key) != null)
{
throw new ArtemisCoreException($"Cannot add a dynamic data model with key '{key}' " + 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."); "because the key is already in use by a static property on this data model.");
}
dynamicDataModel.PluginInfo = PluginInfo; dynamicDataModel.PluginInfo = PluginInfo;
dynamicDataModel.DataModelDescription = new DataModelPropertyAttribute dynamicDataModel.DataModelDescription = new DataModelPropertyAttribute
@ -125,6 +121,15 @@ namespace Artemis.Core.DataModelExpansions
} }
} }
/// <summary>
/// Removes all dynamic data models from this data model
/// </summary>
public void ClearDynamicChildren()
{
while (_dynamicDataModels.Any())
RemoveDynamicChildByKey(_dynamicDataModels.First().Key);
}
/// <summary> /// <summary>
/// Gets a dynamic data model of type <typeparamref name="T" /> by its key /// Gets a dynamic data model of type <typeparamref name="T" /> by its key
/// </summary> /// </summary>

View File

@ -23,12 +23,6 @@ namespace Artemis.Core
/// </summary> /// </summary>
public PluginConfigurationDialog ConfigurationDialog { get; protected set; } public PluginConfigurationDialog ConfigurationDialog { get; protected set; }
/// <inheritdoc />
public void Dispose()
{
DisablePlugin();
}
/// <summary> /// <summary>
/// Called when the plugin is activated /// Called when the plugin is activated
/// </summary> /// </summary>
@ -40,11 +34,15 @@ namespace Artemis.Core
public abstract void DisablePlugin(); public abstract void DisablePlugin();
/// <summary> /// <summary>
/// Registers a timed update that whenever the plugin is enabled calls the provided <paramref name="action" /> at the provided /// Registers a timed update that whenever the plugin is enabled calls the provided <paramref name="action" /> at the
/// provided
/// <paramref name="interval" /> /// <paramref name="interval" />
/// </summary> /// </summary>
/// <param name="interval">The interval at which the update should occur</param> /// <param name="interval">The interval at which the update should occur</param>
/// <param name="action">The action to call every time the interval has passed. The delta time parameter represents the time passed since the last update in seconds</param> /// <param name="action">
/// The action to call every time the interval has passed. The delta time parameter represents the
/// time passed since the last update in seconds
/// </param>
/// <returns>The resulting plugin update registration</returns> /// <returns>The resulting plugin update registration</returns>
public PluginUpdateRegistration AddTimedUpdate(TimeSpan interval, Action<double> action) public PluginUpdateRegistration AddTimedUpdate(TimeSpan interval, Action<double> action)
{ {
@ -53,6 +51,24 @@ namespace Artemis.Core
return new PluginUpdateRegistration(PluginInfo, interval, action); return new PluginUpdateRegistration(PluginInfo, interval, action);
} }
/// <summary>
/// Registers a timed update that whenever the plugin is enabled calls the provided <paramref name="action" /> at the
/// provided
/// <paramref name="interval" />
/// </summary>
/// <param name="interval">The interval at which the update should occur</param>
/// <param name="asyncAction">
/// 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
/// </param>
/// <returns>The resulting plugin update registration</returns>
public PluginUpdateRegistration AddTimedUpdate(TimeSpan interval, Func<double, Task> asyncAction)
{
if (asyncAction == null)
throw new ArgumentNullException(nameof(asyncAction));
return new PluginUpdateRegistration(PluginInfo, interval, asyncAction);
}
internal void SetEnabled(bool enable, bool isAutoEnable = false) internal void SetEnabled(bool enable, bool isAutoEnable = false)
{ {
if (enable && !Enabled) if (enable && !Enabled)
@ -123,6 +139,12 @@ namespace Artemis.Core
DisablePlugin(); DisablePlugin();
} }
/// <inheritdoc />
public void Dispose()
{
DisablePlugin();
}
#region Events #region Events
/// <summary> /// <summary>

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Threading.Tasks;
using System.Timers; using System.Timers;
using Artemis.Core.Modules; using Artemis.Core.Modules;
@ -24,6 +25,19 @@ namespace Artemis.Core
Start(); Start();
} }
internal PluginUpdateRegistration(PluginInfo pluginInfo, TimeSpan interval, Func<double, Task> asyncAction)
{
PluginInfo = pluginInfo;
Interval = interval;
AsyncAction = asyncAction;
PluginInfo.Instance.PluginEnabled += InstanceOnPluginEnabled;
PluginInfo.Instance.PluginDisabled += InstanceOnPluginDisabled;
if (PluginInfo.Instance.Enabled)
Start();
}
/// <summary> /// <summary>
/// Gets the plugin info of the plugin this registration is associated with /// Gets the plugin info of the plugin this registration is associated with
/// </summary> /// </summary>
@ -40,7 +54,12 @@ namespace Artemis.Core
public Action<double> Action { get; } public Action<double> Action { get; }
/// <summary> /// <summary>
/// Starts calling the <see cref="Action" /> at the configured <see cref="Interval" /> /// Gets the task that gets called each time the update event fires
/// </summary>
public Func<double, Task> AsyncAction { get; }
/// <summary>
/// Starts calling the <see cref="Action" /> or <see cref="AsyncAction"/> at the configured <see cref="Interval" />
/// <para>Note: Called automatically when the plugin enables</para> /// <para>Note: Called automatically when the plugin enables</para>
/// </summary> /// </summary>
public void Start() public void Start()
@ -61,7 +80,7 @@ namespace Artemis.Core
} }
/// <summary> /// <summary>
/// Stops calling the <see cref="Action" /> at the configured <see cref="Interval" /> /// Stops calling the <see cref="Action" /> or <see cref="AsyncAction"/> at the configured <see cref="Interval" />
/// <para>Note: Called automatically when the plugin disables</para> /// <para>Note: Called automatically when the plugin disables</para>
/// </summary> /// </summary>
public void Stop() public void Stop()
@ -90,7 +109,13 @@ namespace Artemis.Core
if (PluginInfo.Instance is Module module && !module.IsUpdateAllowed) if (PluginInfo.Instance is Module module && !module.IsUpdateAllowed)
return; return;
if (Action != null)
Action(interval.TotalSeconds); Action(interval.TotalSeconds);
else if (AsyncAction != null)
{
Task task = AsyncAction(interval.TotalSeconds);
task.Wait();
}
} }
private void InstanceOnPluginEnabled(object sender, EventArgs e) private void InstanceOnPluginEnabled(object sender, EventArgs e)

View File

@ -121,7 +121,7 @@ namespace Artemis.UI.Shared
/// <inheritdoc /> /// <inheritdoc />
public override string ToString() public override string ToString()
{ {
return $"[List] {DisplayPath ?? Path} - {List.Count} item(s)"; return $"[List] {DisplayPath ?? Path} - {List?.Count ?? 0} item(s)";
} }
} }
} }

View File

@ -57,7 +57,9 @@ namespace Artemis.UI.Shared
/// <inheritdoc /> /// <inheritdoc />
public override string ToString() public override string ToString()
{ {
if (DisplayValueType != null)
return $"[{DisplayValueType.Name}] {DisplayPath ?? Path} - {DisplayValue}"; return $"[{DisplayValueType.Name}] {DisplayPath ?? Path} - {DisplayValue}";
return $"{DisplayPath ?? Path} - {DisplayValue}";
} }
} }
} }

View File

@ -193,6 +193,9 @@ namespace Artemis.UI.Shared
continue; continue;
if (propertyInfo.GetCustomAttribute<DataModelIgnoreAttribute>() != null) if (propertyInfo.GetCustomAttribute<DataModelIgnoreAttribute>() != null)
continue; continue;
MethodInfo getMethod = propertyInfo.GetGetMethod();
if (getMethod == null || getMethod.GetParameters().Any())
continue;
DataModelVisualizationViewModel child = CreateChild(dataModelUIService, childPath, GetChildDepth()); DataModelVisualizationViewModel child = CreateChild(dataModelUIService, childPath, GetChildDepth());
if (child != null) if (child != null)

View File

@ -18,6 +18,10 @@
d:DesignWidth="800" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:PluginSettingsWindowViewModel}" d:DataContext="{d:DesignInstance local:PluginSettingsWindowViewModel}"
Icon="/Resources/Images/Logo/logo-512.png"> Icon="/Resources/Images/Logo/logo-512.png">
<materialDesign:DialogHost IsTabStop="False"
Focusable="False"
Identifier="PluginSettingsDialog"
DialogTheme="Inherit">
<DockPanel> <DockPanel>
<controls:AppBar Type="Dense" Title="{Binding ActiveItem.Plugin.PluginInfo.Name}" DockPanel.Dock="Top" Margin="-18 0 0 0" ShowShadow="False"> <controls:AppBar Type="Dense" Title="{Binding ActiveItem.Plugin.PluginInfo.Name}" DockPanel.Dock="Top" Margin="-18 0 0 0" ShowShadow="False">
<controls:AppBar.AppIcon> <controls:AppBar.AppIcon>
@ -27,4 +31,5 @@
<ContentControl s:View.Model="{Binding ActiveItem}" /> <ContentControl s:View.Model="{Binding ActiveItem}" />
</DockPanel> </DockPanel>
</materialDesign:DialogHost>
</controls:MaterialWindow> </controls:MaterialWindow>

View File

@ -7,12 +7,20 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
{ {
public class PluginSettingsWindowViewModel : Conductor<PluginConfigurationViewModel> public class PluginSettingsWindowViewModel : Conductor<PluginConfigurationViewModel>
{ {
private readonly PluginConfigurationViewModel _configurationViewModel;
public PluginSettingsWindowViewModel(PluginConfigurationViewModel configurationViewModel, PackIconKind icon) public PluginSettingsWindowViewModel(PluginConfigurationViewModel configurationViewModel, PackIconKind icon)
{ {
_configurationViewModel = configurationViewModel ?? throw new ArgumentNullException(nameof(configurationViewModel));
Icon = icon; Icon = icon;
ActiveItem = configurationViewModel ?? throw new ArgumentNullException(nameof(configurationViewModel)); }
protected override void OnInitialActivate()
{
ActiveItem = _configurationViewModel;
ActiveItem.Closed += ActiveItemOnClosed; ActiveItem.Closed += ActiveItemOnClosed;
base.OnInitialActivate();
} }
public PackIconKind Icon { get; } public PackIconKind Icon { get; }