mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Plugins - Separated plugins and implementations as different principles
This commit is contained in:
parent
c0d0e421c7
commit
1e0dc1894d
@ -34,10 +34,10 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public static readonly PluginInfo CorePluginInfo = new PluginInfo
|
||||
{
|
||||
Guid = Guid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff"), Name = "Artemis Core", Enabled = true
|
||||
Guid = Guid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff"), Name = "Artemis Core", IsEnabled = true
|
||||
};
|
||||
|
||||
internal static readonly CorePlugin CorePlugin = new CorePlugin {PluginInfo = CorePluginInfo};
|
||||
internal static readonly CorePluginImplementation CorePluginImplementation = new CorePluginImplementation {PluginInfo = CorePluginInfo};
|
||||
internal static readonly EffectPlaceholderPlugin EffectPlaceholderPlugin = new EffectPlaceholderPlugin {PluginInfo = CorePluginInfo};
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -16,7 +16,7 @@ namespace Artemis.Core
|
||||
{
|
||||
internal EventPredicateWrapperDataModel()
|
||||
{
|
||||
PluginInfo = Constants.CorePluginInfo;
|
||||
Implementation = Constants.CorePluginInfo;
|
||||
}
|
||||
|
||||
[DataModelIgnore]
|
||||
|
||||
@ -16,7 +16,7 @@ namespace Artemis.Core
|
||||
{
|
||||
internal ListPredicateWrapperDataModel()
|
||||
{
|
||||
PluginInfo = Constants.CorePluginInfo;
|
||||
Implementation = Constants.CorePluginInfo;
|
||||
}
|
||||
|
||||
[DataModelIgnore]
|
||||
|
||||
@ -93,7 +93,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets the data model GUID of the <see cref="Target" /> if it is a <see cref="DataModel" />
|
||||
/// </summary>
|
||||
public Guid? DataModelGuid => Target?.PluginInfo.Guid;
|
||||
public Guid? DataModelGuid => Target?.Implementation.Guid;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the point-separated path associated with this <see cref="DataModelPath" />
|
||||
@ -295,7 +295,7 @@ namespace Artemis.Core
|
||||
|
||||
private void DataModelStoreOnDataModelAdded(object? sender, DataModelStoreEvent e)
|
||||
{
|
||||
if (e.Registration.DataModel.PluginInfo.Guid != Entity.DataModelGuid)
|
||||
if (e.Registration.DataModel.Implementation.Guid != Entity.DataModelGuid)
|
||||
return;
|
||||
|
||||
Target = e.Registration.DataModel;
|
||||
@ -304,7 +304,7 @@ namespace Artemis.Core
|
||||
|
||||
private void DataModelStoreOnDataModelRemoved(object? sender, DataModelStoreEvent e)
|
||||
{
|
||||
if (e.Registration.DataModel.PluginInfo.Guid != Entity.DataModelGuid)
|
||||
if (e.Registration.DataModel.Implementation.Guid != Entity.DataModelGuid)
|
||||
return;
|
||||
|
||||
Target = null;
|
||||
|
||||
@ -662,7 +662,7 @@ namespace Artemis.Core
|
||||
return;
|
||||
|
||||
LayerBrushReference current = General.BrushReference.CurrentValue;
|
||||
if (e.Registration.Plugin.PluginInfo.Guid == current.BrushPluginGuid &&
|
||||
if (e.Registration.PluginImplementation.PluginInfo.Guid == current.BrushPluginGuid &&
|
||||
e.Registration.LayerBrushDescriptor.LayerBrushType.Name == current.BrushType)
|
||||
ActivateLayerBrush();
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ namespace Artemis.Core
|
||||
{
|
||||
// If effects provided by the plugin are on the element, replace them with placeholders
|
||||
List<BaseLayerEffect> pluginEffects = _layerEffects.Where(ef => ef.Descriptor.LayerEffectProvider != null &&
|
||||
ef.PluginInfo.Guid == e.Registration.Plugin.PluginInfo.Guid).ToList();
|
||||
ef.PluginInfo.Guid == e.Registration.PluginImplementation.PluginInfo.Guid).ToList();
|
||||
foreach (BaseLayerEffect pluginEffect in pluginEffects)
|
||||
{
|
||||
LayerEffectEntity entity = RenderElementEntity.LayerEffects.First(en => en.Id == pluginEffect.EntityId);
|
||||
@ -268,7 +268,7 @@ namespace Artemis.Core
|
||||
|
||||
private void LayerEffectStoreOnLayerEffectAdded(object sender, LayerEffectStoreEvent e)
|
||||
{
|
||||
if (RenderElementEntity.LayerEffects.Any(ef => ef.PluginGuid == e.Registration.Plugin.PluginInfo.Guid))
|
||||
if (RenderElementEntity.LayerEffects.Any(ef => ef.PluginGuid == e.Registration.PluginImplementation.PluginInfo.Guid))
|
||||
ActivateEffects();
|
||||
}
|
||||
|
||||
|
||||
@ -14,10 +14,10 @@ namespace Artemis.Core
|
||||
private SKPath _renderPath;
|
||||
private SKRect _renderRectangle;
|
||||
|
||||
internal ArtemisDevice(IRGBDevice rgbDevice, Plugin plugin, ArtemisSurface surface)
|
||||
internal ArtemisDevice(IRGBDevice rgbDevice, PluginImplementation pluginImplementation, ArtemisSurface surface)
|
||||
{
|
||||
RgbDevice = rgbDevice;
|
||||
Plugin = plugin;
|
||||
PluginImplementation = pluginImplementation;
|
||||
Surface = surface;
|
||||
DeviceEntity = new DeviceEntity();
|
||||
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
||||
@ -30,10 +30,10 @@ namespace Artemis.Core
|
||||
CalculateRenderProperties();
|
||||
}
|
||||
|
||||
internal ArtemisDevice(IRGBDevice rgbDevice, Plugin plugin, ArtemisSurface surface, DeviceEntity deviceEntity)
|
||||
internal ArtemisDevice(IRGBDevice rgbDevice, PluginImplementation pluginImplementation, ArtemisSurface surface, DeviceEntity deviceEntity)
|
||||
{
|
||||
RgbDevice = rgbDevice;
|
||||
Plugin = plugin;
|
||||
PluginImplementation = pluginImplementation;
|
||||
Surface = surface;
|
||||
DeviceEntity = deviceEntity;
|
||||
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
||||
@ -52,7 +52,7 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
public IRGBDevice RgbDevice { get; }
|
||||
public Plugin Plugin { get; }
|
||||
public PluginImplementation PluginImplementation { get; }
|
||||
public ArtemisSurface Surface { get; }
|
||||
public DeviceEntity DeviceEntity { get; }
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ namespace Artemis.Core.Ninject
|
||||
protected override ISettingsService CreateInstance(IContext context)
|
||||
{
|
||||
IRequest parentRequest = context.Request.ParentRequest;
|
||||
if (parentRequest == null || typeof(Plugin).IsAssignableFrom(parentRequest.Service))
|
||||
if (parentRequest == null || typeof(PluginImplementation).IsAssignableFrom(parentRequest.Service))
|
||||
throw new ArtemisPluginException($"SettingsService can not be injected into a plugin. Inject {nameof(PluginSettings)} instead.");
|
||||
|
||||
return _instance;
|
||||
|
||||
@ -14,10 +14,10 @@ namespace Artemis.Core.DataModelExpansions
|
||||
private readonly Dictionary<string, DataModel> _dynamicDataModels = new Dictionary<string, DataModel>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin info this data model belongs to
|
||||
/// Gets the plugin implementation this data model belongs to
|
||||
/// </summary>
|
||||
[DataModelIgnore]
|
||||
public PluginInfo PluginInfo { get; internal set; }
|
||||
public DataModelPluginImplementation Implementation { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DataModelPropertyAttribute" /> describing this data model
|
||||
@ -43,9 +43,9 @@ namespace Artemis.Core.DataModelExpansions
|
||||
/// <returns></returns>
|
||||
public ReadOnlyCollection<PropertyInfo> GetHiddenProperties()
|
||||
{
|
||||
if (PluginInfo.Instance is ProfileModule profileModule)
|
||||
if (Implementation is ProfileModule profileModule)
|
||||
return profileModule.HiddenProperties;
|
||||
if (PluginInfo.Instance is BaseDataModelExpansion dataModelExpansion)
|
||||
if (Implementation is BaseDataModelExpansion dataModelExpansion)
|
||||
return dataModelExpansion.HiddenProperties;
|
||||
|
||||
return new List<PropertyInfo>().AsReadOnly();
|
||||
@ -81,7 +81,7 @@ namespace Artemis.Core.DataModelExpansions
|
||||
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.Implementation = Implementation;
|
||||
dynamicDataModel.DataModelDescription = new DataModelPropertyAttribute
|
||||
{
|
||||
Name = string.IsNullOrWhiteSpace(name) ? key.Humanize() : name,
|
||||
|
||||
@ -42,18 +42,18 @@ namespace Artemis.Core.DataModelExpansions
|
||||
HiddenPropertiesList.RemoveAll(p => p.Equals(propertyInfo));
|
||||
}
|
||||
|
||||
internal override void InternalEnablePlugin()
|
||||
internal override void InternalEnable()
|
||||
{
|
||||
DataModel = Activator.CreateInstance<T>();
|
||||
DataModel.PluginInfo = PluginInfo;
|
||||
DataModel.Implementation = PluginInfo;
|
||||
DataModel.DataModelDescription = GetDataModelDescription();
|
||||
base.InternalEnablePlugin();
|
||||
base.InternalEnable();
|
||||
}
|
||||
|
||||
internal override void InternalDisablePlugin()
|
||||
internal override void InternalDisable()
|
||||
{
|
||||
DataModel = null;
|
||||
base.InternalDisablePlugin();
|
||||
base.InternalDisable();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,7 +8,7 @@ namespace Artemis.Core.DataModelExpansions
|
||||
/// For internal use only, to implement your own layer property type, extend <see cref="DataModelExpansion{T}" />
|
||||
/// instead.
|
||||
/// </summary>
|
||||
public abstract class BaseDataModelExpansion : Plugin
|
||||
public abstract class BaseDataModelExpansion : DataModelPluginImplementation
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a list of all properties ignored at runtime using <c>IgnoreProperty(x => x.y)</c>
|
||||
|
||||
47
src/Artemis.Core/Plugins/DataModelPluginImplementation.cs
Normal file
47
src/Artemis.Core/Plugins/DataModelPluginImplementation.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an implementation of a certain type provided by a plugin with support for data models
|
||||
/// </summary>
|
||||
public abstract class DataModelPluginImplementation : PluginImplementation
|
||||
{
|
||||
/// <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="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 which can be used to stop the update</returns>
|
||||
public TimedUpdateRegistration AddTimedUpdate(TimeSpan interval, Action<double> action)
|
||||
{
|
||||
if (action == null)
|
||||
throw new ArgumentNullException(nameof(action));
|
||||
return new TimedUpdateRegistration(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 TimedUpdateRegistration AddTimedUpdate(TimeSpan interval, Func<double, Task> asyncAction)
|
||||
{
|
||||
if (asyncAction == null)
|
||||
throw new ArgumentNullException(nameof(asyncAction));
|
||||
return new TimedUpdateRegistration(PluginInfo, interval, asyncAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -10,7 +10,7 @@ namespace Artemis.Core.DeviceProviders
|
||||
/// <summary>
|
||||
/// Allows you to implement and register your own device provider
|
||||
/// </summary>
|
||||
public abstract class DeviceProvider : Plugin
|
||||
public abstract class DeviceProvider : PluginImplementation
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="DeviceProvider" /> class
|
||||
@ -34,7 +34,7 @@ namespace Artemis.Core.DeviceProviders
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void DisablePlugin()
|
||||
public override void Disable()
|
||||
{
|
||||
// Does not happen with device providers, they require Artemis to restart
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ namespace Artemis.Core.LayerBrushes
|
||||
/// <summary>
|
||||
/// Allows you to create one or more <see cref="LayerBrush{T}" />s usable by profile layers.
|
||||
/// </summary>
|
||||
public abstract class LayerBrushProvider : Plugin
|
||||
public abstract class LayerBrushProvider : PluginImplementation
|
||||
{
|
||||
private readonly List<LayerBrushDescriptor> _layerBrushDescriptors;
|
||||
|
||||
@ -17,7 +17,7 @@ namespace Artemis.Core.LayerBrushes
|
||||
protected LayerBrushProvider()
|
||||
{
|
||||
_layerBrushDescriptors = new List<LayerBrushDescriptor>();
|
||||
PluginDisabled += OnPluginDisabled;
|
||||
Disabled += OnDisabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -38,7 +38,7 @@ namespace Artemis.Core.LayerBrushes
|
||||
/// </param>
|
||||
protected void RegisterLayerBrushDescriptor<T>(string displayName, string description, string icon) where T : BaseLayerBrush
|
||||
{
|
||||
if (!Enabled)
|
||||
if (!IsEnabled)
|
||||
throw new ArtemisPluginException(PluginInfo, "Can only add a layer brush descriptor when the plugin is enabled");
|
||||
|
||||
LayerBrushDescriptor descriptor = new LayerBrushDescriptor(displayName, description, icon, typeof(T), this);
|
||||
@ -46,7 +46,7 @@ namespace Artemis.Core.LayerBrushes
|
||||
LayerBrushStore.Add(descriptor);
|
||||
}
|
||||
|
||||
private void OnPluginDisabled(object sender, EventArgs e)
|
||||
private void OnDisabled(object sender, EventArgs e)
|
||||
{
|
||||
// The store will clean up the registrations by itself, the plugin just needs to clear its own list
|
||||
_layerBrushDescriptors.Clear();
|
||||
|
||||
@ -7,7 +7,7 @@ namespace Artemis.Core.LayerEffects
|
||||
/// <summary>
|
||||
/// Allows you to register one or more <see cref="LayerEffect{T}" />s usable by profile layers.
|
||||
/// </summary>
|
||||
public abstract class LayerEffectProvider : Plugin
|
||||
public abstract class LayerEffectProvider : PluginImplementation
|
||||
{
|
||||
private readonly List<LayerEffectDescriptor> _layerEffectDescriptors;
|
||||
|
||||
@ -17,7 +17,7 @@ namespace Artemis.Core.LayerEffects
|
||||
protected LayerEffectProvider()
|
||||
{
|
||||
_layerEffectDescriptors = new List<LayerEffectDescriptor>();
|
||||
PluginDisabled += OnPluginDisabled;
|
||||
Disabled += OnDisabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -38,7 +38,7 @@ namespace Artemis.Core.LayerEffects
|
||||
/// </param>
|
||||
protected void RegisterLayerEffectDescriptor<T>(string displayName, string description, string icon) where T : BaseLayerEffect
|
||||
{
|
||||
if (!Enabled)
|
||||
if (!IsEnabled)
|
||||
throw new ArtemisPluginException(PluginInfo, "Can only add a layer effect descriptor when the plugin is enabled");
|
||||
|
||||
LayerEffectDescriptor descriptor = new LayerEffectDescriptor(displayName, description, icon, typeof(T), this);
|
||||
@ -46,7 +46,7 @@ namespace Artemis.Core.LayerEffects
|
||||
LayerEffectStore.Add(descriptor);
|
||||
}
|
||||
|
||||
private void OnPluginDisabled(object sender, EventArgs e)
|
||||
private void OnDisabled(object sender, EventArgs e)
|
||||
{
|
||||
// The store will clean up the registrations by itself, the plugin just needs to clear its own list
|
||||
_layerEffectDescriptors.Clear();
|
||||
|
||||
@ -45,18 +45,18 @@ namespace Artemis.Core.Modules
|
||||
return new DataModelPropertyAttribute {Name = PluginInfo.Name, Description = PluginInfo.Description};
|
||||
}
|
||||
|
||||
internal override void InternalEnablePlugin()
|
||||
internal override void InternalEnable()
|
||||
{
|
||||
DataModel = Activator.CreateInstance<T>();
|
||||
DataModel.PluginInfo = PluginInfo;
|
||||
DataModel.Implementation = PluginInfo;
|
||||
DataModel.DataModelDescription = GetDataModelDescription();
|
||||
base.InternalEnablePlugin();
|
||||
base.InternalEnable();
|
||||
}
|
||||
|
||||
internal override void InternalDisablePlugin()
|
||||
internal override void InternalDisable()
|
||||
{
|
||||
DataModel = null;
|
||||
base.InternalDisablePlugin();
|
||||
base.InternalDisable();
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ namespace Artemis.Core.Modules
|
||||
/// <summary>
|
||||
/// Allows you to add support for new games/applications
|
||||
/// </summary>
|
||||
public abstract class Module : Plugin
|
||||
public abstract class Module : DataModelPluginImplementation
|
||||
{
|
||||
/// <summary>
|
||||
/// The modules display name that's shown in the menu
|
||||
|
||||
@ -71,18 +71,18 @@ namespace Artemis.Core.Modules
|
||||
HiddenPropertiesList.RemoveAll(p => p.Equals(propertyInfo));
|
||||
}
|
||||
|
||||
internal override void InternalEnablePlugin()
|
||||
internal override void InternalEnable()
|
||||
{
|
||||
DataModel = Activator.CreateInstance<T>();
|
||||
DataModel.PluginInfo = PluginInfo;
|
||||
DataModel.Implementation = PluginInfo;
|
||||
DataModel.DataModelDescription = GetDataModelDescription();
|
||||
base.InternalEnablePlugin();
|
||||
base.InternalEnable();
|
||||
}
|
||||
|
||||
internal override void InternalDisablePlugin()
|
||||
internal override void InternalDisable()
|
||||
{
|
||||
Deactivate(true);
|
||||
base.InternalDisablePlugin();
|
||||
base.InternalDisable();
|
||||
DataModel = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,178 +1,18 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Artemis.Core
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// This is the base plugin type, use the other interfaces such as Module to create plugins
|
||||
/// Represents a plugin
|
||||
/// </summary>
|
||||
public abstract class Plugin : IDisposable
|
||||
public abstract class Plugin
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the plugin info related to this plugin
|
||||
/// </summary>
|
||||
public PluginInfo PluginInfo { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the plugin is enabled
|
||||
/// </summary>
|
||||
public bool Enabled { get; internal set; }
|
||||
public PluginInfo Info { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a configuration dialog for this plugin that is accessible in the UI under Settings > Plugins
|
||||
/// </summary>
|
||||
public PluginConfigurationDialog ConfigurationDialog { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the plugin is activated
|
||||
/// </summary>
|
||||
public abstract void EnablePlugin();
|
||||
|
||||
/// <summary>
|
||||
/// Called when the plugin is deactivated or when Artemis shuts down
|
||||
/// </summary>
|
||||
public abstract void DisablePlugin();
|
||||
|
||||
/// <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="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 which can be used to stop the update</returns>
|
||||
public PluginUpdateRegistration AddTimedUpdate(TimeSpan interval, Action<double> action)
|
||||
{
|
||||
if (action == null)
|
||||
throw new ArgumentNullException(nameof(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)
|
||||
{
|
||||
if (enable && !Enabled)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (isAutoEnable && PluginInfo.GetLockFileCreated())
|
||||
{
|
||||
// Don't wrap existing lock exceptions, simply rethrow them
|
||||
if (PluginInfo.LoadException is ArtemisPluginLockException)
|
||||
throw PluginInfo.LoadException;
|
||||
|
||||
throw new ArtemisPluginLockException(PluginInfo.LoadException);
|
||||
}
|
||||
|
||||
Enabled = true;
|
||||
PluginInfo.Enabled = true;
|
||||
PluginInfo.CreateLockFile();
|
||||
|
||||
// Allow up to 15 seconds for plugins to activate.
|
||||
// This means plugins that need more time should do their long running tasks in a background thread, which is intentional
|
||||
// Little meh: Running this from a different thread could cause deadlocks
|
||||
Task enableTask = Task.Run(InternalEnablePlugin);
|
||||
if (!enableTask.Wait(TimeSpan.FromSeconds(15)))
|
||||
throw new ArtemisPluginException(PluginInfo, "Plugin load timeout");
|
||||
|
||||
PluginInfo.LoadException = null;
|
||||
OnPluginEnabled();
|
||||
}
|
||||
// If enable failed, put it back in a disabled state
|
||||
catch (Exception e)
|
||||
{
|
||||
Enabled = false;
|
||||
PluginInfo.Enabled = false;
|
||||
PluginInfo.LoadException = e;
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!(PluginInfo.LoadException is ArtemisPluginLockException))
|
||||
PluginInfo.DeleteLockFile();
|
||||
}
|
||||
}
|
||||
else if (!enable && Enabled)
|
||||
{
|
||||
Enabled = false;
|
||||
PluginInfo.Enabled = false;
|
||||
|
||||
// Even if disable failed, still leave it in a disabled state to avoid more issues
|
||||
InternalDisablePlugin();
|
||||
OnPluginDisabled();
|
||||
}
|
||||
// A failed load is still enabled in plugin info (to avoid disabling it permanently after a fail)
|
||||
// update even that when manually disabling
|
||||
else if (!enable && !Enabled)
|
||||
{
|
||||
PluginInfo.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual void InternalEnablePlugin()
|
||||
{
|
||||
EnablePlugin();
|
||||
}
|
||||
|
||||
internal virtual void InternalDisablePlugin()
|
||||
{
|
||||
DisablePlugin();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
DisablePlugin();
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the plugin is enabled
|
||||
/// </summary>
|
||||
public event EventHandler PluginEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the plugin is disabled
|
||||
/// </summary>
|
||||
public event EventHandler PluginDisabled;
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the PluginEnabled event
|
||||
/// </summary>
|
||||
protected virtual void OnPluginEnabled()
|
||||
{
|
||||
PluginEnabled?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the PluginDisabled event
|
||||
/// </summary>
|
||||
protected virtual void OnPluginDisabled()
|
||||
{
|
||||
PluginDisabled?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -17,7 +17,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// The layer brush this dialog belongs to
|
||||
/// </summary>
|
||||
internal Plugin Plugin { get; set; }
|
||||
internal PluginImplementation PluginImplementation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of view model the tab contains
|
||||
|
||||
@ -10,25 +10,25 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="PluginConfigurationViewModel" /> class
|
||||
/// </summary>
|
||||
/// <param name="plugin"></param>
|
||||
protected PluginConfigurationViewModel(Plugin plugin)
|
||||
/// <param name="pluginImplementation"></param>
|
||||
protected PluginConfigurationViewModel(PluginImplementation pluginImplementation)
|
||||
{
|
||||
Plugin = plugin;
|
||||
PluginImplementation = pluginImplementation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="PluginConfigurationViewModel" /> class with a validator
|
||||
/// </summary>
|
||||
/// <param name="plugin"></param>
|
||||
/// <param name="pluginImplementation"></param>
|
||||
/// <param name="validator"></param>
|
||||
protected PluginConfigurationViewModel(Plugin plugin, IModelValidator validator) : base(validator)
|
||||
protected PluginConfigurationViewModel(PluginImplementation pluginImplementation, IModelValidator validator) : base(validator)
|
||||
{
|
||||
Plugin = plugin;
|
||||
PluginImplementation = pluginImplementation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin this configuration view model is associated with
|
||||
/// </summary>
|
||||
public Plugin Plugin { get; }
|
||||
public PluginImplementation PluginImplementation { get; }
|
||||
}
|
||||
}
|
||||
142
src/Artemis.Core/Plugins/PluginImplementation.cs
Normal file
142
src/Artemis.Core/Plugins/PluginImplementation.cs
Normal file
@ -0,0 +1,142 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an implementation of a certain type provided by a plugin
|
||||
/// </summary>
|
||||
public abstract class PluginImplementation : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the plugin that provides this implementation
|
||||
/// </summary>
|
||||
public Plugin Plugin { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin info related to this plugin
|
||||
/// </summary>
|
||||
public PluginInfo PluginInfo { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the plugin is enabled
|
||||
/// </summary>
|
||||
public bool IsEnabled { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Called when the implementation is activated
|
||||
/// </summary>
|
||||
public abstract void Enable();
|
||||
|
||||
/// <summary>
|
||||
/// Called when the implementation is deactivated or when Artemis shuts down
|
||||
/// </summary>
|
||||
public abstract void Disable();
|
||||
|
||||
internal void SetEnabled(bool enable, bool isAutoEnable = false)
|
||||
{
|
||||
if (enable && !IsEnabled)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (isAutoEnable && PluginInfo.GetLockFileCreated())
|
||||
{
|
||||
// Don't wrap existing lock exceptions, simply rethrow them
|
||||
if (PluginInfo.LoadException is ArtemisPluginLockException)
|
||||
throw PluginInfo.LoadException;
|
||||
|
||||
throw new ArtemisPluginLockException(PluginInfo.LoadException);
|
||||
}
|
||||
|
||||
IsEnabled = true;
|
||||
PluginInfo.IsEnabled = true;
|
||||
PluginInfo.CreateLockFile();
|
||||
|
||||
// Allow up to 15 seconds for plugins to activate.
|
||||
// This means plugins that need more time should do their long running tasks in a background thread, which is intentional
|
||||
// Little meh: Running this from a different thread could cause deadlocks
|
||||
Task enableTask = Task.Run(InternalEnable);
|
||||
if (!enableTask.Wait(TimeSpan.FromSeconds(15)))
|
||||
throw new ArtemisPluginException(PluginInfo, "Plugin load timeout");
|
||||
|
||||
PluginInfo.LoadException = null;
|
||||
OnEnabled();
|
||||
}
|
||||
// If enable failed, put it back in a disabled state
|
||||
catch (Exception e)
|
||||
{
|
||||
IsEnabled = false;
|
||||
PluginInfo.IsEnabled = false;
|
||||
PluginInfo.LoadException = e;
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!(PluginInfo.LoadException is ArtemisPluginLockException))
|
||||
PluginInfo.DeleteLockFile();
|
||||
}
|
||||
}
|
||||
else if (!enable && IsEnabled)
|
||||
{
|
||||
IsEnabled = false;
|
||||
PluginInfo.IsEnabled = false;
|
||||
|
||||
// Even if disable failed, still leave it in a disabled state to avoid more issues
|
||||
InternalDisable();
|
||||
OnDisabled();
|
||||
}
|
||||
// A failed load is still enabled in plugin info (to avoid disabling it permanently after a fail)
|
||||
// update even that when manually disabling
|
||||
else if (!enable && !IsEnabled)
|
||||
{
|
||||
PluginInfo.IsEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual void InternalEnable()
|
||||
{
|
||||
Enable();
|
||||
}
|
||||
|
||||
internal virtual void InternalDisable()
|
||||
{
|
||||
Disable();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
Disable();
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the implementation is enabled
|
||||
/// </summary>
|
||||
public event EventHandler? Enabled;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the implementation is disabled
|
||||
/// </summary>
|
||||
public event EventHandler? Disabled;
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the PluginEnabled event
|
||||
/// </summary>
|
||||
protected virtual void OnEnabled()
|
||||
{
|
||||
Enabled?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Triggers the PluginDisabled event
|
||||
/// </summary>
|
||||
protected virtual void OnDisabled()
|
||||
{
|
||||
Disabled?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,6 @@ using Artemis.Storage.Entities.Plugins;
|
||||
using McMaster.NETCore.Plugins;
|
||||
using Newtonsoft.Json;
|
||||
using Ninject;
|
||||
using Ninject.Extensions.ChildKernel;
|
||||
using Stylet;
|
||||
|
||||
namespace Artemis.Core
|
||||
@ -18,10 +17,10 @@ namespace Artemis.Core
|
||||
{
|
||||
private string _description;
|
||||
private DirectoryInfo _directory;
|
||||
private bool _enabled;
|
||||
private Guid _guid;
|
||||
private string _icon;
|
||||
private Plugin _instance;
|
||||
private bool _isEnabled;
|
||||
private Exception _loadException;
|
||||
private string _main;
|
||||
private string _name;
|
||||
@ -103,7 +102,7 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A reference to the type implementing Plugin, available after successful load
|
||||
/// Gets the plugin this info is associated with
|
||||
/// </summary>
|
||||
public Plugin Instance
|
||||
{
|
||||
@ -114,10 +113,10 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Indicates whether the user enabled the plugin or not
|
||||
/// </summary>
|
||||
public bool Enabled
|
||||
public bool IsEnabled
|
||||
{
|
||||
get => _enabled;
|
||||
internal set => SetAndNotify(ref _enabled, value);
|
||||
get => _isEnabled;
|
||||
internal set => SetAndNotify(ref _isEnabled, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -129,36 +128,41 @@ namespace Artemis.Core
|
||||
internal set => SetAndNotify(ref _loadException, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The PluginLoader backing this plugin
|
||||
/// </summary>
|
||||
internal PluginLoader PluginLoader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The assembly the plugin code lives in
|
||||
/// </summary>
|
||||
public Assembly Assembly { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Ninject kernel of the plugin
|
||||
/// The Ninject kernel of the plugin
|
||||
/// </summary>
|
||||
public IKernel Kernel { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// The PluginLoader backing this plugin
|
||||
/// </summary>
|
||||
internal PluginLoader PluginLoader { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The entity representing the plugin
|
||||
/// </summary>
|
||||
internal PluginEntity PluginEntity { get; set; }
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Name} v{Version} - {Guid}";
|
||||
}
|
||||
|
||||
public string? ResolveRelativePath(string path)
|
||||
{
|
||||
return path == null ? null : Path.Combine(Directory.FullName, path);
|
||||
}
|
||||
|
||||
internal void ApplyToEntity()
|
||||
{
|
||||
PluginEntity.Id = Guid;
|
||||
PluginEntity.IsEnabled = Enabled;
|
||||
PluginEntity.IsEnabled = IsEnabled;
|
||||
}
|
||||
|
||||
internal void CreateLockFile()
|
||||
@ -176,10 +180,5 @@ namespace Artemis.Core
|
||||
{
|
||||
return File.Exists(Path.Combine(Directory.FullName, "artemis.lock"));
|
||||
}
|
||||
|
||||
public string? ResolveRelativePath(string path)
|
||||
{
|
||||
return path == null ? null : Path.Combine(Directory.FullName, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,32 +8,32 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Represents a registration for a timed plugin update
|
||||
/// </summary>
|
||||
public class PluginUpdateRegistration
|
||||
public class TimedUpdateRegistration
|
||||
{
|
||||
private DateTime _lastEvent;
|
||||
private Timer _timer;
|
||||
|
||||
internal PluginUpdateRegistration(PluginInfo pluginInfo, TimeSpan interval, Action<double> action)
|
||||
internal TimedUpdateRegistration(PluginInfo pluginInfo, TimeSpan interval, Action<double> action)
|
||||
{
|
||||
PluginInfo = pluginInfo;
|
||||
Interval = interval;
|
||||
Action = action;
|
||||
|
||||
PluginInfo.Instance.PluginEnabled += InstanceOnPluginEnabled;
|
||||
PluginInfo.Instance.PluginDisabled += InstanceOnPluginDisabled;
|
||||
if (PluginInfo.Instance.Enabled)
|
||||
PluginInfo.Instance.Enabled += InstanceOnEnabled;
|
||||
PluginInfo.Instance.Disabled += InstanceOnDisabled;
|
||||
if (PluginInfo.Instance.IsEnabled)
|
||||
Start();
|
||||
}
|
||||
|
||||
internal PluginUpdateRegistration(PluginInfo pluginInfo, TimeSpan interval, Func<double, Task> asyncAction)
|
||||
internal TimedUpdateRegistration(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)
|
||||
PluginInfo.Instance.Enabled += InstanceOnEnabled;
|
||||
PluginInfo.Instance.Disabled += InstanceOnDisabled;
|
||||
if (PluginInfo.Instance.IsEnabled)
|
||||
Start();
|
||||
}
|
||||
|
||||
@ -66,7 +66,7 @@ namespace Artemis.Core
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (!PluginInfo.Instance.Enabled)
|
||||
if (!PluginInfo.Instance.IsEnabled)
|
||||
throw new ArtemisPluginException("Cannot start a timed update for a disabled plugin");
|
||||
|
||||
if (_timer != null)
|
||||
@ -99,7 +99,7 @@ namespace Artemis.Core
|
||||
|
||||
private void TimerOnElapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
if (!PluginInfo.Instance.Enabled)
|
||||
if (!PluginInfo.Instance.IsEnabled)
|
||||
return;
|
||||
|
||||
lock (this)
|
||||
@ -121,12 +121,12 @@ namespace Artemis.Core
|
||||
}
|
||||
}
|
||||
|
||||
private void InstanceOnPluginEnabled(object sender, EventArgs e)
|
||||
private void InstanceOnEnabled(object sender, EventArgs e)
|
||||
{
|
||||
Start();
|
||||
}
|
||||
|
||||
private void InstanceOnPluginDisabled(object sender, EventArgs e)
|
||||
private void InstanceOnDisabled(object sender, EventArgs e)
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
@ -133,8 +133,8 @@ namespace Artemis.Core.Services
|
||||
|
||||
private void UpdatePluginCache()
|
||||
{
|
||||
_modules = _pluginService.GetPluginsOfType<Module>().Where(p => p.Enabled).ToList();
|
||||
_dataModelExpansions = _pluginService.GetPluginsOfType<BaseDataModelExpansion>().Where(p => p.Enabled).ToList();
|
||||
_modules = _pluginService.GetPluginsOfType<Module>().Where(p => p.IsEnabled).ToList();
|
||||
_dataModelExpansions = _pluginService.GetPluginsOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled).ToList();
|
||||
}
|
||||
|
||||
private void ConfigureJsonConvert()
|
||||
@ -162,7 +162,7 @@ namespace Artemis.Core.Services
|
||||
lock (_dataModelExpansions)
|
||||
{
|
||||
// Update all active modules, check Enabled status because it may go false before before the _dataModelExpansions list is updated
|
||||
foreach (BaseDataModelExpansion dataModelExpansion in _dataModelExpansions.Where(e => e.Enabled))
|
||||
foreach (BaseDataModelExpansion dataModelExpansion in _dataModelExpansions.Where(e => e.IsEnabled))
|
||||
dataModelExpansion.Update(args.DeltaTime);
|
||||
}
|
||||
|
||||
|
||||
@ -46,22 +46,22 @@ namespace Artemis.Core.Services
|
||||
/// <summary>
|
||||
/// Enables the provided plugin
|
||||
/// </summary>
|
||||
/// <param name="plugin"></param>
|
||||
/// <param name="pluginImplementation"></param>
|
||||
/// <param name="isAutoEnable">If true, fails if there is a lock file present</param>
|
||||
void EnablePlugin(Plugin plugin, bool isAutoEnable = false);
|
||||
void EnablePlugin(PluginImplementation pluginImplementation, bool isAutoEnable = false);
|
||||
|
||||
/// <summary>
|
||||
/// Disables the provided plugin
|
||||
/// </summary>
|
||||
/// <param name="plugin"></param>
|
||||
void DisablePlugin(Plugin plugin);
|
||||
/// <param name="pluginImplementation"></param>
|
||||
void DisablePlugin(PluginImplementation pluginImplementation);
|
||||
|
||||
/// <summary>
|
||||
/// Finds the plugin info related to the plugin
|
||||
/// </summary>
|
||||
/// <param name="plugin">The plugin you want to find the plugin info for</param>
|
||||
/// <param name="pluginImplementation">The plugin you want to find the plugin info for</param>
|
||||
/// <returns>The plugins PluginInfo</returns>
|
||||
PluginInfo GetPluginInfo(Plugin plugin);
|
||||
PluginInfo GetPluginInfo(PluginImplementation pluginImplementation);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin info of all loaded plugins
|
||||
@ -70,31 +70,31 @@ namespace Artemis.Core.Services
|
||||
List<PluginInfo> GetAllPluginInfo();
|
||||
|
||||
/// <summary>
|
||||
/// Finds all enabled <see cref="Plugin" /> instances of <typeparamref name="T" />
|
||||
/// Finds all enabled <see cref="PluginImplementation" /> instances of <typeparamref name="T" />
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Either <see cref="Plugin" /> or a plugin type implementing <see cref="Plugin" /></typeparam>
|
||||
/// <typeparam name="T">Either <see cref="PluginImplementation" /> or a plugin type implementing <see cref="PluginImplementation" /></typeparam>
|
||||
/// <returns>Returns a list of plugin instances of <typeparamref name="T" /></returns>
|
||||
List<T> GetPluginsOfType<T>() where T : Plugin;
|
||||
List<T> GetPluginsOfType<T>() where T : PluginImplementation;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin that provided the specified assembly
|
||||
/// </summary>
|
||||
/// <param name="assembly"></param>
|
||||
/// <returns></returns>
|
||||
Plugin GetPluginByAssembly(Assembly assembly);
|
||||
PluginImplementation GetPluginByAssembly(Assembly assembly);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin that defined the specified device
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
/// <returns></returns>
|
||||
Plugin GetPluginByDevice(IRGBDevice device);
|
||||
PluginImplementation GetPluginByDevice(IRGBDevice device);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the plugin info of the current call stack
|
||||
/// </summary>
|
||||
/// <returns>If the current call stack contains a plugin, the plugin. Otherwise null</returns>
|
||||
Plugin GetCallingPlugin();
|
||||
PluginImplementation GetCallingPlugin();
|
||||
|
||||
#region Events
|
||||
|
||||
|
||||
@ -103,7 +103,7 @@ namespace Artemis.Core.Services
|
||||
{
|
||||
lock (module)
|
||||
{
|
||||
bool shouldBeActivated = module.EvaluateActivationRequirements() && module.Enabled;
|
||||
bool shouldBeActivated = module.EvaluateActivationRequirements() && module.IsEnabled;
|
||||
if (shouldBeActivated && !module.IsActivated)
|
||||
tasks.Add(ActivateModule(module));
|
||||
else if (!shouldBeActivated && module.IsActivated)
|
||||
|
||||
@ -136,7 +136,7 @@ namespace Artemis.Core.Services
|
||||
}
|
||||
|
||||
// Activate plugins after they are all loaded
|
||||
foreach (PluginInfo pluginInfo in _plugins.Where(p => p.Enabled))
|
||||
foreach (PluginInfo pluginInfo in _plugins.Where(p => p.IsEnabled))
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -180,7 +180,7 @@ namespace Artemis.Core.Services
|
||||
pluginEntity = new PluginEntity {Id = pluginInfo.Guid, IsEnabled = true};
|
||||
|
||||
pluginInfo.PluginEntity = pluginEntity;
|
||||
pluginInfo.Enabled = pluginEntity.IsEnabled;
|
||||
pluginInfo.IsEnabled = pluginEntity.IsEnabled;
|
||||
|
||||
string mainFile = Path.Combine(pluginInfo.Directory.FullName, pluginInfo.Main);
|
||||
if (!File.Exists(mainFile))
|
||||
@ -206,7 +206,7 @@ namespace Artemis.Core.Services
|
||||
List<Type> pluginTypes;
|
||||
try
|
||||
{
|
||||
pluginTypes = pluginInfo.Assembly.GetTypes().Where(t => typeof(Plugin).IsAssignableFrom(t)).ToList();
|
||||
pluginTypes = pluginInfo.Assembly.GetTypes().Where(t => typeof(PluginImplementation).IsAssignableFrom(t)).ToList();
|
||||
}
|
||||
catch (ReflectionTypeLoadException e)
|
||||
{
|
||||
@ -226,7 +226,7 @@ namespace Artemis.Core.Services
|
||||
};
|
||||
pluginInfo.Kernel = new ChildKernel(_kernel);
|
||||
pluginInfo.Kernel.Load(new PluginModule(pluginInfo));
|
||||
pluginInfo.Instance = (Plugin) pluginInfo.Kernel.Get(pluginType, constraint: null, parameters: parameters);
|
||||
pluginInfo.Instance = (PluginImplementation) pluginInfo.Kernel.Get(pluginType, constraint: null, parameters: parameters);
|
||||
pluginInfo.Instance.PluginInfo = pluginInfo;
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -266,29 +266,29 @@ namespace Artemis.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public void EnablePlugin(Plugin plugin, bool isAutoEnable = false)
|
||||
public void EnablePlugin(PluginImplementation pluginImplementation, bool isAutoEnable = false)
|
||||
{
|
||||
_logger.Debug("Enabling plugin {pluginInfo}", plugin.PluginInfo);
|
||||
OnPluginEnabling(new PluginEventArgs(plugin.PluginInfo));
|
||||
_logger.Debug("Enabling plugin {pluginInfo}", pluginImplementation.PluginInfo);
|
||||
OnPluginEnabling(new PluginEventArgs(pluginImplementation.PluginInfo));
|
||||
|
||||
lock (_plugins)
|
||||
{
|
||||
try
|
||||
{
|
||||
// A device provider may be queued for disable on next restart, this undoes that
|
||||
if (plugin is DeviceProvider && plugin.Enabled && !plugin.PluginInfo.Enabled)
|
||||
if (pluginImplementation is DeviceProvider && pluginImplementation.IsEnabled && !pluginImplementation.PluginInfo.IsEnabled)
|
||||
{
|
||||
plugin.PluginInfo.Enabled = true;
|
||||
plugin.PluginInfo.ApplyToEntity();
|
||||
_pluginRepository.SavePlugin(plugin.PluginInfo.PluginEntity);
|
||||
pluginImplementation.PluginInfo.IsEnabled = true;
|
||||
pluginImplementation.PluginInfo.ApplyToEntity();
|
||||
_pluginRepository.SavePlugin(pluginImplementation.PluginInfo.PluginEntity);
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.SetEnabled(true, isAutoEnable);
|
||||
pluginImplementation.SetEnabled(true, isAutoEnable);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Warning(new ArtemisPluginException(plugin.PluginInfo, "Exception during SetEnabled(true)", e), "Failed to enable plugin");
|
||||
_logger.Warning(new ArtemisPluginException(pluginImplementation.PluginInfo, "Exception during SetEnabled(true)", e), "Failed to enable plugin");
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
@ -296,48 +296,48 @@ namespace Artemis.Core.Services
|
||||
// On an auto-enable, ensure PluginInfo.Enabled is true even if enable failed, that way a failure on auto-enable does
|
||||
// not affect the user's settings
|
||||
if (isAutoEnable)
|
||||
plugin.PluginInfo.Enabled = true;
|
||||
pluginImplementation.PluginInfo.IsEnabled = true;
|
||||
|
||||
plugin.PluginInfo.ApplyToEntity();
|
||||
_pluginRepository.SavePlugin(plugin.PluginInfo.PluginEntity);
|
||||
pluginImplementation.PluginInfo.ApplyToEntity();
|
||||
_pluginRepository.SavePlugin(pluginImplementation.PluginInfo.PluginEntity);
|
||||
|
||||
if (plugin.PluginInfo.Enabled)
|
||||
_logger.Debug("Successfully enabled plugin {pluginInfo}", plugin.PluginInfo);
|
||||
if (pluginImplementation.PluginInfo.IsEnabled)
|
||||
_logger.Debug("Successfully enabled plugin {pluginInfo}", pluginImplementation.PluginInfo);
|
||||
}
|
||||
}
|
||||
|
||||
OnPluginEnabled(new PluginEventArgs(plugin.PluginInfo));
|
||||
OnPluginEnabled(new PluginEventArgs(pluginImplementation.PluginInfo));
|
||||
}
|
||||
|
||||
public void DisablePlugin(Plugin plugin)
|
||||
public void DisablePlugin(PluginImplementation pluginImplementation)
|
||||
{
|
||||
lock (_plugins)
|
||||
{
|
||||
_logger.Debug("Disabling plugin {pluginInfo}", plugin.PluginInfo);
|
||||
_logger.Debug("Disabling plugin {pluginInfo}", pluginImplementation.PluginInfo);
|
||||
|
||||
// Device providers cannot be disabled at runtime simply queue a disable for next restart
|
||||
if (plugin is DeviceProvider)
|
||||
if (pluginImplementation is DeviceProvider)
|
||||
{
|
||||
// Don't call SetEnabled(false) but simply update enabled state and save it
|
||||
plugin.PluginInfo.Enabled = false;
|
||||
plugin.PluginInfo.ApplyToEntity();
|
||||
_pluginRepository.SavePlugin(plugin.PluginInfo.PluginEntity);
|
||||
pluginImplementation.PluginInfo.IsEnabled = false;
|
||||
pluginImplementation.PluginInfo.ApplyToEntity();
|
||||
_pluginRepository.SavePlugin(pluginImplementation.PluginInfo.PluginEntity);
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.SetEnabled(false);
|
||||
plugin.PluginInfo.ApplyToEntity();
|
||||
_pluginRepository.SavePlugin(plugin.PluginInfo.PluginEntity);
|
||||
pluginImplementation.SetEnabled(false);
|
||||
pluginImplementation.PluginInfo.ApplyToEntity();
|
||||
_pluginRepository.SavePlugin(pluginImplementation.PluginInfo.PluginEntity);
|
||||
|
||||
_logger.Debug("Successfully disabled plugin {pluginInfo}", plugin.PluginInfo);
|
||||
_logger.Debug("Successfully disabled plugin {pluginInfo}", pluginImplementation.PluginInfo);
|
||||
}
|
||||
|
||||
OnPluginDisabled(new PluginEventArgs(plugin.PluginInfo));
|
||||
OnPluginDisabled(new PluginEventArgs(pluginImplementation.PluginInfo));
|
||||
}
|
||||
|
||||
public PluginInfo GetPluginInfo(Plugin plugin)
|
||||
public PluginInfo GetPluginInfo(PluginImplementation pluginImplementation)
|
||||
{
|
||||
return _plugins.FirstOrDefault(p => p.Instance == plugin);
|
||||
return _plugins.FirstOrDefault(p => p.Instance == pluginImplementation);
|
||||
}
|
||||
|
||||
public List<PluginInfo> GetAllPluginInfo()
|
||||
@ -345,22 +345,22 @@ namespace Artemis.Core.Services
|
||||
return new List<PluginInfo>(_plugins);
|
||||
}
|
||||
|
||||
public List<T> GetPluginsOfType<T>() where T : Plugin
|
||||
public List<T> GetPluginsOfType<T>() where T : PluginImplementation
|
||||
{
|
||||
return _plugins.Where(p => p.Enabled && p.Instance is T).Select(p => (T) p.Instance).ToList();
|
||||
return _plugins.Where(p => p.IsEnabled && p.Instance is T).Select(p => (T) p.Instance).ToList();
|
||||
}
|
||||
|
||||
public Plugin GetPluginByAssembly(Assembly assembly)
|
||||
public PluginImplementation GetPluginByAssembly(Assembly assembly)
|
||||
{
|
||||
return _plugins.FirstOrDefault(p => p.Assembly == assembly)?.Instance;
|
||||
}
|
||||
|
||||
public Plugin GetPluginByDevice(IRGBDevice rgbDevice)
|
||||
public PluginImplementation GetPluginByDevice(IRGBDevice rgbDevice)
|
||||
{
|
||||
return GetPluginsOfType<DeviceProvider>().First(d => d.RgbDeviceProvider.Devices != null && d.RgbDeviceProvider.Devices.Contains(rgbDevice));
|
||||
}
|
||||
|
||||
public Plugin GetCallingPlugin()
|
||||
public PluginImplementation GetCallingPlugin()
|
||||
{
|
||||
StackTrace stackTrace = new StackTrace(); // get call stack
|
||||
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
|
||||
@ -368,9 +368,9 @@ namespace Artemis.Core.Services
|
||||
foreach (StackFrame stackFrame in stackFrames)
|
||||
{
|
||||
Assembly assembly = stackFrame.GetMethod().DeclaringType.Assembly;
|
||||
Plugin plugin = GetPluginByAssembly(assembly);
|
||||
if (plugin != null)
|
||||
return plugin;
|
||||
PluginImplementation pluginImplementation = GetPluginByAssembly(assembly);
|
||||
if (pluginImplementation != null)
|
||||
return pluginImplementation;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@ -11,9 +11,9 @@ namespace Artemis.Core.Services
|
||||
public DataModelService(IPluginService pluginService)
|
||||
{
|
||||
// Add data models of already loaded plugins
|
||||
foreach (Module module in pluginService.GetPluginsOfType<Module>().Where(p => p.Enabled))
|
||||
foreach (Module module in pluginService.GetPluginsOfType<Module>().Where(p => p.IsEnabled))
|
||||
AddModuleDataModel(module);
|
||||
foreach (BaseDataModelExpansion dataModelExpansion in pluginService.GetPluginsOfType<BaseDataModelExpansion>().Where(p => p.Enabled))
|
||||
foreach (BaseDataModelExpansion dataModelExpansion in pluginService.GetPluginsOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled))
|
||||
AddDataModelExpansionDataModel(dataModelExpansion);
|
||||
|
||||
// Add data models of new plugins when they get enabled
|
||||
@ -44,9 +44,9 @@ namespace Artemis.Core.Services
|
||||
return (T) DataModelStore.GetAll().FirstOrDefault(d => d.DataModel is T)?.DataModel;
|
||||
}
|
||||
|
||||
public DataModel GetPluginDataModel(Plugin plugin)
|
||||
public DataModel GetPluginDataModel(PluginImplementation pluginImplementation)
|
||||
{
|
||||
return DataModelStore.Get(plugin.PluginInfo.Guid)?.DataModel;
|
||||
return DataModelStore.Get(pluginImplementation.PluginInfo.Guid)?.DataModel;
|
||||
}
|
||||
|
||||
public DataModel GetPluginDataModel(Guid pluginGuid)
|
||||
|
||||
@ -34,8 +34,8 @@ namespace Artemis.Core.Services
|
||||
/// <summary>
|
||||
/// If found, returns the data model of the provided plugin
|
||||
/// </summary>
|
||||
/// <param name="plugin">The plugin to find the data model of</param>
|
||||
DataModel GetPluginDataModel(Plugin plugin);
|
||||
/// <param name="pluginImplementation">The plugin to find the data model of</param>
|
||||
DataModel GetPluginDataModel(PluginImplementation pluginImplementation);
|
||||
|
||||
/// <summary>
|
||||
/// If found, returns the data model of the provided plugin GUID
|
||||
|
||||
@ -44,8 +44,8 @@ namespace Artemis.Core.Services
|
||||
// Add all current devices
|
||||
foreach (IRGBDevice rgbDevice in _rgbService.LoadedDevices)
|
||||
{
|
||||
Plugin plugin = _pluginService.GetPluginByDevice(rgbDevice);
|
||||
configuration.Devices.Add(new ArtemisDevice(rgbDevice, plugin, configuration));
|
||||
PluginImplementation pluginImplementation = _pluginService.GetPluginByDevice(rgbDevice);
|
||||
configuration.Devices.Add(new ArtemisDevice(rgbDevice, pluginImplementation, configuration));
|
||||
}
|
||||
|
||||
lock (_surfaceConfigurations)
|
||||
@ -136,8 +136,8 @@ namespace Artemis.Core.Services
|
||||
IRGBDevice device = _rgbService.Surface.Devices.FirstOrDefault(d => d.GetDeviceIdentifier() == position.DeviceIdentifier);
|
||||
if (device != null)
|
||||
{
|
||||
Plugin plugin = _pluginService.GetPluginByDevice(device);
|
||||
surfaceConfiguration.Devices.Add(new ArtemisDevice(device, plugin, surfaceConfiguration, position));
|
||||
PluginImplementation pluginImplementation = _pluginService.GetPluginByDevice(device);
|
||||
surfaceConfiguration.Devices.Add(new ArtemisDevice(device, pluginImplementation, surfaceConfiguration, position));
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,8 +178,8 @@ namespace Artemis.Core.Services
|
||||
DeviceEntity existingDeviceConfig = surface.SurfaceEntity.DeviceEntities.FirstOrDefault(d => d.DeviceIdentifier == deviceIdentifier);
|
||||
if (existingDeviceConfig != null)
|
||||
{
|
||||
Plugin plugin = _pluginService.GetPluginByDevice(rgbDevice);
|
||||
device = new ArtemisDevice(rgbDevice, plugin, surface, existingDeviceConfig);
|
||||
PluginImplementation pluginImplementation = _pluginService.GetPluginByDevice(rgbDevice);
|
||||
device = new ArtemisDevice(rgbDevice, pluginImplementation, surface, existingDeviceConfig);
|
||||
}
|
||||
// Fall back on creating a new device
|
||||
else
|
||||
@ -189,8 +189,8 @@ namespace Artemis.Core.Services
|
||||
rgbDevice.DeviceInfo,
|
||||
deviceIdentifier
|
||||
);
|
||||
Plugin plugin = _pluginService.GetPluginByDevice(rgbDevice);
|
||||
device = new ArtemisDevice(rgbDevice, plugin, surface);
|
||||
PluginImplementation pluginImplementation = _pluginService.GetPluginByDevice(rgbDevice);
|
||||
device = new ArtemisDevice(rgbDevice, pluginImplementation, surface);
|
||||
}
|
||||
|
||||
surface.Devices.Add(device);
|
||||
|
||||
@ -42,7 +42,7 @@ namespace Artemis.Core
|
||||
{
|
||||
lock (Registrations)
|
||||
{
|
||||
return Registrations.FirstOrDefault(r => r.Plugin.PluginInfo.Guid == pluginGuid && r.ConditionOperator.GetType().Name == type);
|
||||
return Registrations.FirstOrDefault(r => r.PluginImplementation.PluginInfo.Guid == pluginGuid && r.ConditionOperator.GetType().Name == type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ namespace Artemis.Core
|
||||
{
|
||||
lock (Registrations)
|
||||
{
|
||||
return Registrations.FirstOrDefault(r => r.Plugin.PluginInfo.Guid == pluginGuid && r.DataBindingModifierType.GetType().Name == type);
|
||||
return Registrations.FirstOrDefault(r => r.PluginImplementation.PluginInfo.Guid == pluginGuid && r.DataBindingModifierType.GetType().Name == type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ namespace Artemis.Core
|
||||
if (Registrations.Any(r => r.DataModel == dataModel))
|
||||
throw new ArtemisCoreException($"Data model store already contains data model '{dataModel.DataModelDescription}'");
|
||||
|
||||
registration = new DataModelRegistration(dataModel, dataModel.PluginInfo.Instance) {IsInStore = true};
|
||||
registration = new DataModelRegistration(dataModel, dataModel.Implementation.Instance) {IsInStore = true};
|
||||
Registrations.Add(registration);
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ namespace Artemis.Core
|
||||
{
|
||||
lock (Registrations)
|
||||
{
|
||||
return Registrations.FirstOrDefault(d => d.Plugin.PluginInfo.Guid == pluginGuid);
|
||||
return Registrations.FirstOrDefault(d => d.PluginImplementation.PluginInfo.Guid == pluginGuid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ namespace Artemis.Core
|
||||
{
|
||||
lock (Registrations)
|
||||
{
|
||||
return Registrations.FirstOrDefault(d => d.Plugin.PluginInfo.Guid == pluginGuid &&
|
||||
return Registrations.FirstOrDefault(d => d.PluginImplementation.PluginInfo.Guid == pluginGuid &&
|
||||
d.LayerBrushDescriptor.LayerBrushType.Name == typeName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ namespace Artemis.Core
|
||||
{
|
||||
lock (Registrations)
|
||||
{
|
||||
return Registrations.FirstOrDefault(d => d.Plugin.PluginInfo.Guid == pluginGuid && d.LayerEffectDescriptor.LayerEffectType.Name == typeName);
|
||||
return Registrations.FirstOrDefault(d => d.PluginImplementation.PluginInfo.Guid == pluginGuid && d.LayerEffectDescriptor.LayerEffectType.Name == typeName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7,12 +7,12 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public class ConditionOperatorRegistration
|
||||
{
|
||||
internal ConditionOperatorRegistration(BaseConditionOperator conditionOperator, Plugin plugin)
|
||||
internal ConditionOperatorRegistration(BaseConditionOperator conditionOperator, PluginImplementation pluginImplementation)
|
||||
{
|
||||
ConditionOperator = conditionOperator;
|
||||
Plugin = plugin;
|
||||
PluginImplementation = pluginImplementation;
|
||||
|
||||
Plugin.PluginDisabled += PluginOnPluginDisabled;
|
||||
PluginImplementation.Disabled += OnDisabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -23,16 +23,16 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets the plugin the condition operator is associated with
|
||||
/// </summary>
|
||||
public Plugin Plugin { get; }
|
||||
public PluginImplementation PluginImplementation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the registration is in the internal Core store
|
||||
/// </summary>
|
||||
public bool IsInStore { get; internal set; }
|
||||
|
||||
private void PluginOnPluginDisabled(object sender, EventArgs e)
|
||||
private void OnDisabled(object sender, EventArgs e)
|
||||
{
|
||||
Plugin.PluginDisabled -= PluginOnPluginDisabled;
|
||||
PluginImplementation.Disabled -= OnDisabled;
|
||||
if (IsInStore)
|
||||
ConditionOperatorStore.Remove(this);
|
||||
}
|
||||
|
||||
@ -7,12 +7,12 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public class DataBindingModifierTypeRegistration
|
||||
{
|
||||
internal DataBindingModifierTypeRegistration(BaseDataBindingModifierType dataBindingModifierType, Plugin plugin)
|
||||
internal DataBindingModifierTypeRegistration(BaseDataBindingModifierType dataBindingModifierType, PluginImplementation pluginImplementation)
|
||||
{
|
||||
DataBindingModifierType = dataBindingModifierType;
|
||||
Plugin = plugin;
|
||||
PluginImplementation = pluginImplementation;
|
||||
|
||||
Plugin.PluginDisabled += PluginOnPluginDisabled;
|
||||
PluginImplementation.Disabled += OnDisabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -23,16 +23,16 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets the plugin the data binding modifier is associated with
|
||||
/// </summary>
|
||||
public Plugin Plugin { get; }
|
||||
public PluginImplementation PluginImplementation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the registration is in the internal Core store
|
||||
/// </summary>
|
||||
public bool IsInStore { get; internal set; }
|
||||
|
||||
private void PluginOnPluginDisabled(object sender, EventArgs e)
|
||||
private void OnDisabled(object sender, EventArgs e)
|
||||
{
|
||||
Plugin.PluginDisabled -= PluginOnPluginDisabled;
|
||||
PluginImplementation.Disabled -= OnDisabled;
|
||||
if (IsInStore)
|
||||
DataBindingModifierTypeStore.Remove(this);
|
||||
}
|
||||
|
||||
@ -8,12 +8,12 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public class DataModelRegistration
|
||||
{
|
||||
internal DataModelRegistration(DataModel dataModel, Plugin plugin)
|
||||
internal DataModelRegistration(DataModel dataModel, PluginImplementation pluginImplementation)
|
||||
{
|
||||
DataModel = dataModel;
|
||||
Plugin = plugin;
|
||||
PluginImplementation = pluginImplementation;
|
||||
|
||||
Plugin.PluginDisabled += PluginOnPluginDisabled;
|
||||
PluginImplementation.Disabled += OnDisabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -24,16 +24,16 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets the plugin the data model is associated with
|
||||
/// </summary>
|
||||
public Plugin Plugin { get; }
|
||||
public PluginImplementation PluginImplementation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the registration is in the internal Core store
|
||||
/// </summary>
|
||||
public bool IsInStore { get; internal set; }
|
||||
|
||||
private void PluginOnPluginDisabled(object sender, EventArgs e)
|
||||
private void OnDisabled(object sender, EventArgs e)
|
||||
{
|
||||
Plugin.PluginDisabled -= PluginOnPluginDisabled;
|
||||
PluginImplementation.Disabled -= OnDisabled;
|
||||
if (IsInStore)
|
||||
DataModelStore.Remove(this);
|
||||
}
|
||||
|
||||
@ -8,12 +8,12 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public class LayerBrushRegistration
|
||||
{
|
||||
internal LayerBrushRegistration(LayerBrushDescriptor descriptor, Plugin plugin)
|
||||
internal LayerBrushRegistration(LayerBrushDescriptor descriptor, PluginImplementation pluginImplementation)
|
||||
{
|
||||
LayerBrushDescriptor = descriptor;
|
||||
Plugin = plugin;
|
||||
PluginImplementation = pluginImplementation;
|
||||
|
||||
Plugin.PluginDisabled += PluginOnPluginDisabled;
|
||||
PluginImplementation.Disabled += OnDisabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -24,16 +24,16 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets the plugin the layer brush is associated with
|
||||
/// </summary>
|
||||
public Plugin Plugin { get; }
|
||||
public PluginImplementation PluginImplementation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the registration is in the internal Core store
|
||||
/// </summary>
|
||||
public bool IsInStore { get; internal set; }
|
||||
|
||||
private void PluginOnPluginDisabled(object sender, EventArgs e)
|
||||
private void OnDisabled(object sender, EventArgs e)
|
||||
{
|
||||
Plugin.PluginDisabled -= PluginOnPluginDisabled;
|
||||
PluginImplementation.Disabled -= OnDisabled;
|
||||
if (IsInStore)
|
||||
LayerBrushStore.Remove(this);
|
||||
}
|
||||
|
||||
@ -8,12 +8,12 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
public class LayerEffectRegistration
|
||||
{
|
||||
internal LayerEffectRegistration(LayerEffectDescriptor descriptor, Plugin plugin)
|
||||
internal LayerEffectRegistration(LayerEffectDescriptor descriptor, PluginImplementation pluginImplementation)
|
||||
{
|
||||
LayerEffectDescriptor = descriptor;
|
||||
Plugin = plugin;
|
||||
PluginImplementation = pluginImplementation;
|
||||
|
||||
Plugin.PluginDisabled += PluginOnPluginDisabled;
|
||||
PluginImplementation.Disabled += OnDisabled;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -24,16 +24,16 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets the plugin the layer effect is associated with
|
||||
/// </summary>
|
||||
public Plugin Plugin { get; }
|
||||
public PluginImplementation PluginImplementation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the registration is in the internal Core store
|
||||
/// </summary>
|
||||
public bool IsInStore { get; internal set; }
|
||||
|
||||
private void PluginOnPluginDisabled(object sender, EventArgs e)
|
||||
private void OnDisabled(object sender, EventArgs e)
|
||||
{
|
||||
Plugin.PluginDisabled -= PluginOnPluginDisabled;
|
||||
PluginImplementation.Disabled -= OnDisabled;
|
||||
if (IsInStore)
|
||||
LayerEffectStore.Remove(this);
|
||||
}
|
||||
|
||||
@ -5,19 +5,19 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// An empty plugin used by <see cref="Constants.CorePluginInfo"/>
|
||||
/// </summary>
|
||||
internal class CorePlugin : Plugin
|
||||
internal class CorePluginImplementation : PluginImplementation
|
||||
{
|
||||
public CorePlugin()
|
||||
public CorePluginImplementation()
|
||||
{
|
||||
Constants.CorePluginInfo.Instance = this;
|
||||
Enabled = true;
|
||||
IsEnabled = true;
|
||||
}
|
||||
|
||||
public override void EnablePlugin()
|
||||
public override void Enable()
|
||||
{
|
||||
}
|
||||
|
||||
public override void DisablePlugin()
|
||||
public override void Disable()
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -26,14 +26,14 @@ namespace Artemis.Core
|
||||
{
|
||||
public EffectPlaceholderPlugin()
|
||||
{
|
||||
Enabled = true;
|
||||
IsEnabled = true;
|
||||
}
|
||||
|
||||
public override void EnablePlugin()
|
||||
public override void Enable()
|
||||
{
|
||||
}
|
||||
|
||||
public override void DisablePlugin()
|
||||
public override void Disable()
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -67,12 +67,12 @@ namespace Artemis.Core
|
||||
|
||||
internal class DummyModule : ProfileModule
|
||||
{
|
||||
public override void EnablePlugin()
|
||||
public override void Enable()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override void DisablePlugin()
|
||||
public override void Disable()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ namespace Artemis.UI.Shared
|
||||
ViewModelType = viewModelType;
|
||||
|
||||
if (PluginInfo != Constants.CorePluginInfo)
|
||||
PluginInfo.Instance.PluginDisabled += InstanceOnPluginDisabled;
|
||||
PluginInfo.Instance.Disabled += InstanceOnDisabled;
|
||||
}
|
||||
|
||||
public RegistrationType RegistrationType { get; }
|
||||
@ -35,10 +35,10 @@ namespace Artemis.UI.Shared
|
||||
internal void Unsubscribe()
|
||||
{
|
||||
if (PluginInfo != Constants.CorePluginInfo)
|
||||
PluginInfo.Instance.PluginDisabled -= InstanceOnPluginDisabled;
|
||||
PluginInfo.Instance.Disabled -= InstanceOnDisabled;
|
||||
}
|
||||
|
||||
private void InstanceOnPluginDisabled(object sender, EventArgs e)
|
||||
private void InstanceOnDisabled(object sender, EventArgs e)
|
||||
{
|
||||
if (RegistrationType == RegistrationType.Input)
|
||||
_dataModelUIService.RemoveDataModelInput(this);
|
||||
|
||||
@ -16,7 +16,7 @@ namespace Artemis.UI.Shared
|
||||
ViewModelType = viewModelType;
|
||||
|
||||
if (PluginInfo != Constants.CorePluginInfo)
|
||||
PluginInfo.Instance.PluginDisabled += InstanceOnPluginDisabled;
|
||||
PluginInfo.Instance.Disabled += InstanceOnDisabled;
|
||||
}
|
||||
|
||||
public PluginInfo PluginInfo { get; }
|
||||
@ -26,10 +26,10 @@ namespace Artemis.UI.Shared
|
||||
internal void Unsubscribe()
|
||||
{
|
||||
if (PluginInfo != Constants.CorePluginInfo)
|
||||
PluginInfo.Instance.PluginDisabled -= InstanceOnPluginDisabled;
|
||||
PluginInfo.Instance.Disabled -= InstanceOnDisabled;
|
||||
}
|
||||
|
||||
private void InstanceOnPluginDisabled(object sender, EventArgs e)
|
||||
private void InstanceOnDisabled(object sender, EventArgs e)
|
||||
{
|
||||
// Profile editor service will call Unsubscribe
|
||||
_profileEditorService.RemovePropertyInput(this);
|
||||
|
||||
@ -42,24 +42,24 @@ namespace Artemis.UI.Shared.Services
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
public DataModelPropertiesViewModel GetPluginDataModelVisualization(Plugin plugin, bool includeMainDataModel)
|
||||
public DataModelPropertiesViewModel GetPluginDataModelVisualization(PluginImplementation pluginImplementation, bool includeMainDataModel)
|
||||
{
|
||||
if (includeMainDataModel)
|
||||
{
|
||||
DataModelPropertiesViewModel mainDataModel = GetMainDataModelVisualization();
|
||||
|
||||
// If the main data model already includes the plugin data model we're done
|
||||
if (mainDataModel.Children.Any(c => c.DataModel.PluginInfo.Instance == plugin))
|
||||
if (mainDataModel.Children.Any(c => c.DataModel.Implementation.Instance == pluginImplementation))
|
||||
return mainDataModel;
|
||||
// Otherwise get just the plugin data model and add it
|
||||
DataModelPropertiesViewModel pluginDataModel = GetPluginDataModelVisualization(plugin, false);
|
||||
DataModelPropertiesViewModel pluginDataModel = GetPluginDataModelVisualization(pluginImplementation, false);
|
||||
if (pluginDataModel != null)
|
||||
mainDataModel.Children.Add(pluginDataModel);
|
||||
|
||||
return mainDataModel;
|
||||
}
|
||||
|
||||
DataModel dataModel = _dataModelService.GetPluginDataModel(plugin);
|
||||
DataModel dataModel = _dataModelService.GetPluginDataModel(pluginImplementation);
|
||||
if (dataModel == null)
|
||||
return null;
|
||||
|
||||
|
||||
@ -109,11 +109,11 @@ namespace Artemis.UI.Shared.Services
|
||||
|
||||
private async Task<object> ShowDialogAt<T>(string identifier, IParameter[] parameters) where T : DialogViewModelBase
|
||||
{
|
||||
Plugin callingPlugin = _pluginService.GetCallingPlugin();
|
||||
PluginImplementation callingPluginImplementation = _pluginService.GetCallingPlugin();
|
||||
if (parameters == null) throw new ArgumentNullException(nameof(parameters));
|
||||
|
||||
if (callingPlugin != null)
|
||||
return await ShowDialog(identifier, callingPlugin.PluginInfo.Kernel.Get<T>(parameters));
|
||||
if (callingPluginImplementation != null)
|
||||
return await ShowDialog(identifier, callingPluginImplementation.PluginInfo.Kernel.Get<T>(parameters));
|
||||
return await ShowDialog(identifier, _kernel.Get<T>(parameters));
|
||||
}
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ namespace Artemis.UI.Shared.Services
|
||||
IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelEditors { get; }
|
||||
IReadOnlyCollection<DataModelVisualizationRegistration> RegisteredDataModelDisplays { get; }
|
||||
DataModelPropertiesViewModel GetMainDataModelVisualization();
|
||||
DataModelPropertiesViewModel GetPluginDataModelVisualization(Plugin plugin, bool includeMainDataModel);
|
||||
DataModelPropertiesViewModel GetPluginDataModelVisualization(PluginImplementation pluginImplementation, bool includeMainDataModel);
|
||||
|
||||
DataModelVisualizationRegistration RegisterDataModelInput<T>(PluginInfo pluginInfo, IReadOnlyCollection<Type> compatibleConversionTypes) where T : DataModelInputViewModel;
|
||||
DataModelVisualizationRegistration RegisterDataModelDisplay<T>(PluginInfo pluginInfo) where T : DataModelDisplayViewModel;
|
||||
|
||||
@ -35,7 +35,7 @@ namespace Artemis.UI.Ninject.Factories
|
||||
|
||||
public interface ISettingsVmFactory : IVmFactory
|
||||
{
|
||||
PluginSettingsViewModel CreatePluginSettingsViewModel(Plugin plugin);
|
||||
PluginSettingsViewModel CreatePluginSettingsViewModel(PluginImplementation pluginImplementation);
|
||||
DeviceSettingsViewModel CreateDeviceSettingsViewModel(ArtemisDevice device);
|
||||
}
|
||||
|
||||
|
||||
@ -55,7 +55,7 @@ namespace Artemis.UI.Screens.Settings.Debug
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Device.Plugin.PluginInfo.Directory.FullName);
|
||||
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Device.PluginImplementation.PluginInfo.Directory.FullName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@ -117,7 +117,7 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
|
||||
|
||||
private void PopulateModules()
|
||||
{
|
||||
Modules = _pluginService.GetPluginsOfType<Module>().Where(p => p.Enabled).ToList();
|
||||
Modules = _pluginService.GetPluginsOfType<Module>().Where(p => p.IsEnabled).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -60,7 +60,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Devices
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Device.Plugin.PluginInfo.Directory.FullName);
|
||||
Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Device.PluginImplementation.PluginInfo.Directory.FullName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@ -30,18 +30,18 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
|
||||
private readonly IWindowManager _windowManager;
|
||||
private bool _enabling;
|
||||
private Plugin _plugin;
|
||||
private PluginImplementation _pluginImplementation;
|
||||
private PluginInfo _pluginInfo;
|
||||
|
||||
public PluginSettingsViewModel(Plugin plugin,
|
||||
public PluginSettingsViewModel(PluginImplementation pluginImplementation,
|
||||
ILogger logger,
|
||||
IWindowManager windowManager,
|
||||
IDialogService dialogService,
|
||||
IPluginService pluginService,
|
||||
ISnackbarMessageQueue snackbarMessageQueue)
|
||||
{
|
||||
Plugin = plugin;
|
||||
PluginInfo = plugin.PluginInfo;
|
||||
PluginImplementation = pluginImplementation;
|
||||
PluginInfo = pluginImplementation.PluginInfo;
|
||||
|
||||
_logger = logger;
|
||||
_windowManager = windowManager;
|
||||
@ -50,10 +50,10 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
_snackbarMessageQueue = snackbarMessageQueue;
|
||||
}
|
||||
|
||||
public Plugin Plugin
|
||||
public PluginImplementation PluginImplementation
|
||||
{
|
||||
get => _plugin;
|
||||
set => SetAndNotify(ref _plugin, value);
|
||||
get => _pluginImplementation;
|
||||
set => SetAndNotify(ref _pluginImplementation, value);
|
||||
}
|
||||
|
||||
public PluginInfo PluginInfo
|
||||
@ -69,20 +69,20 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
}
|
||||
|
||||
public PackIconKind Icon => GetIconKind();
|
||||
public string Type => Plugin.GetType().BaseType?.Name ?? Plugin.GetType().Name;
|
||||
public bool CanOpenSettings => IsEnabled && Plugin.ConfigurationDialog != null;
|
||||
public string Type => PluginImplementation.GetType().BaseType?.Name ?? PluginImplementation.GetType().Name;
|
||||
public bool CanOpenSettings => IsEnabled && PluginImplementation.ConfigurationDialog != null;
|
||||
public bool DisplayLoadFailed => !Enabling && PluginInfo.LoadException != null;
|
||||
public bool RequiresRestart => Plugin.Enabled && !PluginInfo.Enabled;
|
||||
public bool RequiresRestart => PluginImplementation.IsEnabled && !PluginInfo.IsEnabled;
|
||||
|
||||
public bool IsEnabled
|
||||
{
|
||||
get => Plugin.PluginInfo.Enabled;
|
||||
get => PluginImplementation.PluginInfo.IsEnabled;
|
||||
set => Task.Run(() => UpdateEnabled(value));
|
||||
}
|
||||
|
||||
public void OpenSettings()
|
||||
{
|
||||
PluginConfigurationDialog configurationViewModel = Plugin.ConfigurationDialog;
|
||||
PluginConfigurationDialog configurationViewModel = PluginImplementation.ConfigurationDialog;
|
||||
if (configurationViewModel == null)
|
||||
return;
|
||||
|
||||
@ -93,8 +93,8 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
if (constructors.Length != 1)
|
||||
throw new ArtemisUIException("Plugin configuration dialogs must have exactly one constructor");
|
||||
|
||||
ParameterInfo pluginParameter = constructors.First().GetParameters().First(p => typeof(Plugin).IsAssignableFrom(p.ParameterType));
|
||||
ConstructorArgument plugin = new ConstructorArgument(pluginParameter.Name, Plugin);
|
||||
ParameterInfo pluginParameter = constructors.First().GetParameters().First(p => typeof(PluginImplementation).IsAssignableFrom(p.ParameterType));
|
||||
ConstructorArgument plugin = new ConstructorArgument(pluginParameter.Name, PluginImplementation);
|
||||
PluginConfigurationViewModel viewModel = (PluginConfigurationViewModel) PluginInfo.Kernel.Get(configurationViewModel.Type, plugin);
|
||||
_windowManager.ShowDialog(new PluginSettingsWindowViewModel(viewModel, Icon));
|
||||
}
|
||||
@ -127,7 +127,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
|
||||
public async Task Restart()
|
||||
{
|
||||
_logger.Debug("Restarting for device provider disable {pluginInfo}", Plugin.PluginInfo);
|
||||
_logger.Debug("Restarting for device provider disable {pluginInfo}", PluginImplementation.PluginInfo);
|
||||
|
||||
// Give the logger a chance to write, might not always be enough but oh well
|
||||
await Task.Delay(500);
|
||||
@ -143,7 +143,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
return iconEnum;
|
||||
}
|
||||
|
||||
switch (Plugin)
|
||||
switch (PluginImplementation)
|
||||
{
|
||||
case BaseDataModelExpansion _:
|
||||
return PackIconKind.TableAdd;
|
||||
@ -170,7 +170,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
return;
|
||||
}
|
||||
|
||||
if (!enable && Plugin is DeviceProvider)
|
||||
if (!enable && PluginImplementation is DeviceProvider)
|
||||
{
|
||||
await DisableDeviceProvider();
|
||||
return;
|
||||
@ -183,7 +183,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
|
||||
try
|
||||
{
|
||||
_pluginService.EnablePlugin(Plugin);
|
||||
_pluginService.EnablePlugin(PluginImplementation);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -195,7 +195,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
}
|
||||
}
|
||||
else
|
||||
_pluginService.DisablePlugin(Plugin);
|
||||
_pluginService.DisablePlugin(PluginImplementation);
|
||||
|
||||
NotifyOfPropertyChange(nameof(IsEnabled));
|
||||
NotifyOfPropertyChange(nameof(CanOpenSettings));
|
||||
@ -208,9 +208,9 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
bool restart = false;
|
||||
|
||||
// If any plugin already requires a restart, don't ask the user again
|
||||
bool restartQueued = _pluginService.GetAllPluginInfo().Any(p => p.Instance != null && !p.Enabled && p.Instance.Enabled);
|
||||
bool restartQueued = _pluginService.GetAllPluginInfo().Any(p => p.Instance != null && !p.IsEnabled && p.Instance.IsEnabled);
|
||||
// If the plugin isn't enabled (load failed), it can be disabled without a restart
|
||||
if (!restartQueued && Plugin.Enabled)
|
||||
if (!restartQueued && PluginImplementation.IsEnabled)
|
||||
{
|
||||
restart = await _dialogService.ShowConfirmDialog(
|
||||
"Disable device provider",
|
||||
@ -220,10 +220,10 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
|
||||
);
|
||||
}
|
||||
|
||||
_pluginService.DisablePlugin(Plugin);
|
||||
_pluginService.DisablePlugin(PluginImplementation);
|
||||
if (restart)
|
||||
{
|
||||
_logger.Debug("Restarting for device provider disable {pluginInfo}", Plugin.PluginInfo);
|
||||
_logger.Debug("Restarting for device provider disable {pluginInfo}", PluginImplementation.PluginInfo);
|
||||
|
||||
// Give the logger a chance to write, might not always be enough but oh well
|
||||
await Task.Delay(500);
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
Identifier="PluginSettingsDialog"
|
||||
DialogTheme="Inherit">
|
||||
<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.PluginImplementation.PluginInfo.Name}" DockPanel.Dock="Top" Margin="-18 0 0 0" ShowShadow="False">
|
||||
<controls:AppBar.AppIcon>
|
||||
<materialDesign:PackIcon Kind="{Binding Icon}" Width="20" Height="28" />
|
||||
</controls:AppBar.AppIcon>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user