mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 11:26:27 +00:00
Plugins - Load features by their info before enabling plugins
General - Added missing XML comments
This commit is contained in:
1 parent
fa26e6b7da
commit
d5d1211649
24 files changed
+241
-180
No files matched your search
@@ -29,6 +29,9 @@ namespace Artemis.Core.LayerBrushes
|
||||
/// </summary>
|
||||
public ListLedGroup? LedGroup { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// For internal use only, is public for dependency injection but ignore pl0x
|
||||
/// </summary>
|
||||
[Inject]
|
||||
public IRgbService? RgbService { get; set; }
|
||||
|
||||
@@ -38,35 +41,6 @@ namespace Artemis.Core.LayerBrushes
|
||||
/// <returns>Your RGB.NET effect</returns>
|
||||
public abstract IBrush GetBrush();
|
||||
|
||||
internal void UpdateLedGroup()
|
||||
{
|
||||
if (LedGroup == null)
|
||||
return;
|
||||
|
||||
if (Layer.Parent != null)
|
||||
LedGroup.ZIndex = Layer.Parent.Children.Count - Layer.Parent.Children.IndexOf(Layer);
|
||||
else
|
||||
LedGroup.ZIndex = 1;
|
||||
|
||||
List<Led> missingLeds = Layer.Leds.Where(l => !LedGroup.ContainsLed(l.RgbLed)).Select(l => l.RgbLed).ToList();
|
||||
List<Led> extraLeds = LedGroup.Where(l => Layer.Leds.All(layerLed => layerLed.RgbLed != l)).ToList();
|
||||
LedGroup.AddLeds(missingLeds);
|
||||
LedGroup.RemoveLeds(extraLeds);
|
||||
LedGroup.Brush = GetBrush();
|
||||
}
|
||||
|
||||
internal override void Initialize()
|
||||
{
|
||||
if (RgbService == null)
|
||||
throw new ArtemisCoreException("Cannot initialize RGB.NET layer brush because RgbService is not set");
|
||||
|
||||
LedGroup = new ListLedGroup(RgbService.Surface);
|
||||
Layer.RenderPropertiesUpdated += LayerOnRenderPropertiesUpdated;
|
||||
|
||||
InitializeProperties();
|
||||
UpdateLedGroup();
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -87,6 +61,35 @@ namespace Artemis.Core.LayerBrushes
|
||||
|
||||
#endregion
|
||||
|
||||
internal void UpdateLedGroup()
|
||||
{
|
||||
if (LedGroup == null)
|
||||
return;
|
||||
|
||||
if (Layer.Parent != null)
|
||||
LedGroup.ZIndex = Layer.Parent.Children.Count - Layer.Parent.Children.IndexOf(Layer);
|
||||
else
|
||||
LedGroup.ZIndex = 1;
|
||||
|
||||
List<Led> missingLeds = Layer.Leds.Where(l => !LedGroup.ContainsLed(l.RgbLed)).Select(l => l.RgbLed).ToList();
|
||||
List<Led> extraLeds = LedGroup.Where(l => Layer.Leds.All(layerLed => layerLed.RgbLed != l)).ToList();
|
||||
LedGroup.AddLeds(missingLeds);
|
||||
LedGroup.RemoveLeds(extraLeds);
|
||||
LedGroup.Brush = GetBrush();
|
||||
}
|
||||
|
||||
internal override void Initialize()
|
||||
{
|
||||
if (RgbService == null)
|
||||
throw new ArtemisCoreException("Cannot initialize RGB.NET layer brush because RgbService is not set");
|
||||
|
||||
LedGroup = new ListLedGroup(RgbService.Surface);
|
||||
Layer.RenderPropertiesUpdated += LayerOnRenderPropertiesUpdated;
|
||||
|
||||
InitializeProperties();
|
||||
UpdateLedGroup();
|
||||
}
|
||||
|
||||
// Not used in this effect type
|
||||
internal override void InternalRender(SKCanvas canvas, SKRect bounds, SKPaint paint)
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public class Plugin : CorePropertyChanged, IDisposable
|
||||
{
|
||||
private readonly List<PluginFeature> _features;
|
||||
private readonly List<PluginFeatureInfo> _features;
|
||||
|
||||
private bool _isEnabled;
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Artemis.Core
|
||||
Directory = directory;
|
||||
Entity = pluginEntity ?? new PluginEntity {Id = Guid, IsEnabled = true};
|
||||
|
||||
_features = new List<PluginFeature>();
|
||||
_features = new List<PluginFeatureInfo>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -61,7 +61,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets a read-only collection of all features this plugin provides
|
||||
/// </summary>
|
||||
public ReadOnlyCollection<PluginFeature> Features => _features.AsReadOnly();
|
||||
public ReadOnlyCollection<PluginFeatureInfo> Features => _features.AsReadOnly();
|
||||
|
||||
/// <summary>
|
||||
/// The assembly the plugin code lives in
|
||||
@@ -107,7 +107,7 @@ namespace Artemis.Core
|
||||
/// <returns>If found, the instance of the feature</returns>
|
||||
public T? GetFeature<T>() where T : PluginFeature
|
||||
{
|
||||
return _features.FirstOrDefault(i => i is T) as T;
|
||||
return _features.FirstOrDefault(i => i.Instance is T) as T;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -122,31 +122,32 @@ namespace Artemis.Core
|
||||
Entity.IsEnabled = IsEnabled;
|
||||
}
|
||||
|
||||
internal void AddFeature(PluginFeature feature)
|
||||
internal void AddFeature(PluginFeatureInfo featureInfo)
|
||||
{
|
||||
feature.Plugin = this;
|
||||
_features.Add(feature);
|
||||
if (featureInfo.Plugin != this)
|
||||
throw new ArtemisCoreException("Feature is not associated with this plugin");
|
||||
_features.Add(featureInfo);
|
||||
|
||||
OnFeatureAdded(new PluginFeatureEventArgs(feature));
|
||||
OnFeatureAdded(new PluginFeatureInfoEventArgs(featureInfo));
|
||||
}
|
||||
|
||||
internal void RemoveFeature(PluginFeature feature)
|
||||
internal void RemoveFeature(PluginFeatureInfo featureInfo)
|
||||
{
|
||||
if (feature.IsEnabled)
|
||||
if (featureInfo.Instance != null && featureInfo.Instance.IsEnabled)
|
||||
throw new ArtemisCoreException("Cannot remove an enabled feature from a plugin");
|
||||
|
||||
_features.Remove(feature);
|
||||
feature.Dispose();
|
||||
|
||||
OnFeatureRemoved(new PluginFeatureEventArgs(feature));
|
||||
_features.Remove(featureInfo);
|
||||
featureInfo.Instance?.Dispose();
|
||||
|
||||
OnFeatureRemoved(new PluginFeatureInfoEventArgs(featureInfo));
|
||||
}
|
||||
|
||||
|
||||
internal void SetEnabled(bool enable)
|
||||
{
|
||||
if (IsEnabled == enable)
|
||||
return;
|
||||
|
||||
if (!enable && Features.Any(e => e.IsEnabled))
|
||||
if (!enable && Features.Any(e => e.Instance != null && e.Instance.IsEnabled))
|
||||
throw new ArtemisCoreException("Cannot disable this plugin because it still has enabled features");
|
||||
|
||||
IsEnabled = enable;
|
||||
@@ -176,8 +177,8 @@ namespace Artemis.Core
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
foreach (PluginFeature feature in Features)
|
||||
feature.Dispose();
|
||||
foreach (PluginFeatureInfo feature in Features)
|
||||
feature.Instance?.Dispose();
|
||||
SetEnabled(false);
|
||||
|
||||
Kernel?.Dispose();
|
||||
@@ -189,7 +190,7 @@ namespace Artemis.Core
|
||||
_features.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -198,7 +199,7 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
@@ -214,12 +215,12 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Occurs when an feature is loaded and added to the plugin
|
||||
/// </summary>
|
||||
public event EventHandler<PluginFeatureEventArgs>? FeatureAdded;
|
||||
public event EventHandler<PluginFeatureInfoEventArgs>? FeatureAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when an feature is disabled and removed from the plugin
|
||||
/// </summary>
|
||||
public event EventHandler<PluginFeatureEventArgs>? FeatureRemoved;
|
||||
public event EventHandler<PluginFeatureInfoEventArgs>? FeatureRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the Enabled event
|
||||
@@ -240,7 +241,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Invokes the FeatureAdded event
|
||||
/// </summary>
|
||||
protected virtual void OnFeatureAdded(PluginFeatureEventArgs e)
|
||||
protected virtual void OnFeatureAdded(PluginFeatureInfoEventArgs e)
|
||||
{
|
||||
FeatureAdded?.Invoke(this, e);
|
||||
}
|
||||
@@ -248,7 +249,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Invokes the FeatureRemoved event
|
||||
/// </summary>
|
||||
protected virtual void OnFeatureRemoved(PluginFeatureEventArgs e)
|
||||
protected virtual void OnFeatureRemoved(PluginFeatureInfoEventArgs e)
|
||||
{
|
||||
FeatureRemoved?.Invoke(this, e);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using System;
|
||||
using Artemis.Core.DataModelExpansions;
|
||||
using Artemis.Core.DeviceProviders;
|
||||
using Artemis.Core.LayerBrushes;
|
||||
using Artemis.Core.LayerEffects;
|
||||
@@ -16,22 +17,48 @@ namespace Artemis.Core
|
||||
{
|
||||
private string? _description;
|
||||
private string? _icon;
|
||||
private PluginFeature? _instance;
|
||||
private string _name = null!;
|
||||
private PluginFeature _pluginFeature = null!;
|
||||
|
||||
internal PluginFeatureInfo()
|
||||
internal PluginFeatureInfo(Plugin plugin, Type featureType, PluginFeatureAttribute? attribute)
|
||||
{
|
||||
Plugin = plugin ?? throw new ArgumentNullException(nameof(plugin));
|
||||
FeatureType = featureType ?? throw new ArgumentNullException(nameof(featureType));
|
||||
|
||||
Name = attribute?.Name ?? featureType.Name.Humanize(LetterCasing.Title);
|
||||
Description = attribute?.Description;
|
||||
Icon = attribute?.Icon;
|
||||
|
||||
if (Icon != null) return;
|
||||
if (typeof(BaseDataModelExpansion).IsAssignableFrom(featureType))
|
||||
Icon = "TableAdd";
|
||||
else if (typeof(DeviceProvider).IsAssignableFrom(featureType))
|
||||
Icon = "Devices";
|
||||
else if (typeof(ProfileModule).IsAssignableFrom(featureType))
|
||||
Icon = "VectorRectangle";
|
||||
else if (typeof(Module).IsAssignableFrom(featureType))
|
||||
Icon = "GearBox";
|
||||
else if (typeof(LayerBrushProvider).IsAssignableFrom(featureType))
|
||||
Icon = "Brush";
|
||||
else if (typeof(LayerEffectProvider).IsAssignableFrom(featureType))
|
||||
Icon = "AutoAwesome";
|
||||
else
|
||||
Icon = "Plugin";
|
||||
}
|
||||
|
||||
internal PluginFeatureInfo(PluginFeature instance, PluginFeatureAttribute? attribute)
|
||||
internal PluginFeatureInfo(Plugin plugin, PluginFeatureAttribute? attribute, PluginFeature instance)
|
||||
{
|
||||
if (instance == null) throw new ArgumentNullException(nameof(instance));
|
||||
Plugin = plugin ?? throw new ArgumentNullException(nameof(plugin));
|
||||
FeatureType = instance.GetType();
|
||||
|
||||
Name = attribute?.Name ?? instance.GetType().Name.Humanize(LetterCasing.Title);
|
||||
Description = attribute?.Description;
|
||||
Icon = attribute?.Icon;
|
||||
PluginFeature = instance;
|
||||
Instance = instance;
|
||||
|
||||
if (Icon != null) return;
|
||||
Icon = PluginFeature switch
|
||||
Icon = Instance switch
|
||||
{
|
||||
BaseDataModelExpansion => "TableAdd",
|
||||
DeviceProvider => "Devices",
|
||||
@@ -43,6 +70,16 @@ namespace Artemis.Core
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin this feature info is associated with
|
||||
/// </summary>
|
||||
public Plugin Plugin { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the feature
|
||||
/// </summary>
|
||||
public Type FeatureType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The name of the plugin
|
||||
/// </summary>
|
||||
@@ -75,18 +112,18 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin this info is associated with
|
||||
/// Gets the feature this info is associated with
|
||||
/// </summary>
|
||||
public PluginFeature PluginFeature
|
||||
public PluginFeature? Instance
|
||||
{
|
||||
get => _pluginFeature;
|
||||
internal set => SetAndNotify(ref _pluginFeature, value);
|
||||
get => _instance;
|
||||
internal set => SetAndNotify(ref _instance, value);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return PluginFeature.Id;
|
||||
return Instance?.Id ?? "Uninitialized feature";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user