mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Plugins - Implemented features
Core - Removed Stylet dependency for #500
This commit is contained in:
parent
b56966c585
commit
e812929215
@ -50,7 +50,6 @@
|
|||||||
<PackageReference Include="Serilog.Sinks.Debug" Version="1.0.1" />
|
<PackageReference Include="Serilog.Sinks.Debug" Version="1.0.1" />
|
||||||
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
|
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
|
||||||
<PackageReference Include="SkiaSharp" Version="1.68.3" />
|
<PackageReference Include="SkiaSharp" Version="1.68.3" />
|
||||||
<PackageReference Include="Stylet" Version="1.3.4" />
|
|
||||||
<PackageReference Include="System.Buffers" Version="4.5.0" />
|
<PackageReference Include="System.Buffers" Version="4.5.0" />
|
||||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||||
<PackageReference Include="System.Reflection.Metadata" Version="1.8.0" />
|
<PackageReference Include="System.Reflection.Metadata" Version="1.8.0" />
|
||||||
|
|||||||
@ -42,6 +42,7 @@
|
|||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Clayerproperties_005Ctypes/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Clayerproperties_005Ctypes/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Clayershapes/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Clayershapes/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Csurface/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Csurface/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=mvvm/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=placeholders/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=placeholders/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Cdatamodelexpansions_005Cattributes/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Cdatamodelexpansions_005Cattributes/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|||||||
@ -12,7 +12,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The full path to the Artemis application folder
|
/// The full path to the Artemis application folder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly string ApplicationFolder = Path.GetDirectoryName(typeof(Constants).Assembly.Location);
|
public static readonly string ApplicationFolder = Path.GetDirectoryName(typeof(Constants).Assembly.Location)!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The full path to the Artemis executable
|
/// The full path to the Artemis executable
|
||||||
@ -34,11 +34,16 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly PluginInfo CorePluginInfo = new PluginInfo
|
public static readonly PluginInfo CorePluginInfo = new PluginInfo
|
||||||
{
|
{
|
||||||
Guid = Guid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff"), Name = "Artemis Core", IsEnabled = true
|
Guid = Guid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff"), Name = "Artemis Core"
|
||||||
};
|
};
|
||||||
|
|
||||||
internal static readonly CorePluginImplementation CorePluginImplementation = new CorePluginImplementation {PluginInfo = CorePluginInfo};
|
/// <summary>
|
||||||
internal static readonly EffectPlaceholderPlugin EffectPlaceholderPlugin = new EffectPlaceholderPlugin {PluginInfo = CorePluginInfo};
|
/// The plugin used by core components of Artemis
|
||||||
|
/// </summary>
|
||||||
|
public static readonly Plugin CorePlugin = new Plugin(CorePluginInfo, new DirectoryInfo(ApplicationFolder));
|
||||||
|
|
||||||
|
internal static readonly CorePluginFeature CorePluginFeature = new CorePluginFeature {Plugin = CorePlugin};
|
||||||
|
internal static readonly EffectPlaceholderPlugin EffectPlaceholderPlugin = new EffectPlaceholderPlugin {Plugin = CorePlugin};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A read-only collection containing all primitive numeric types
|
/// A read-only collection containing all primitive numeric types
|
||||||
|
|||||||
18
src/Artemis.Core/Events/Plugins/PluginFeatureEventArgs.cs
Normal file
18
src/Artemis.Core/Events/Plugins/PluginFeatureEventArgs.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
public class PluginFeatureEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public PluginFeatureEventArgs()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginFeatureEventArgs(PluginFeature pluginFeature)
|
||||||
|
{
|
||||||
|
PluginFeature = pluginFeature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PluginFeature PluginFeature { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,18 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Artemis.Core
|
|
||||||
{
|
|
||||||
public class PluginImplementationEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
public PluginImplementationEventArgs()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginImplementationEventArgs(PluginImplementation pluginImplementation)
|
|
||||||
{
|
|
||||||
PluginImplementation = pluginImplementation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginImplementation PluginImplementation { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
24
src/Artemis.Core/Exceptions/ArtemisPluginFeatureException.cs
Normal file
24
src/Artemis.Core/Exceptions/ArtemisPluginFeatureException.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
public class ArtemisPluginFeatureException : Exception
|
||||||
|
{
|
||||||
|
public PluginFeature PluginFeature { get; }
|
||||||
|
|
||||||
|
public ArtemisPluginFeatureException(PluginFeature pluginFeature)
|
||||||
|
{
|
||||||
|
PluginFeature = pluginFeature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArtemisPluginFeatureException(PluginFeature pluginFeature, string message) : base(message)
|
||||||
|
{
|
||||||
|
PluginFeature = pluginFeature;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArtemisPluginFeatureException(PluginFeature pluginFeature, string message, Exception inner) : base(message, inner)
|
||||||
|
{
|
||||||
|
PluginFeature = pluginFeature;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
72
src/Artemis.Core/MVVM/CorePropertyChanged.cs
Normal file
72
src/Artemis.Core/MVVM/CorePropertyChanged.cs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a basic bindable class which notifies when a property value changes.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class CorePropertyChanged : INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
#region Events
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a property value changes.
|
||||||
|
/// </summary>
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the property already matches the desirec value or needs to be updated.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of the property.</typeparam>
|
||||||
|
/// <param name="storage">Reference to the backing-filed.</param>
|
||||||
|
/// <param name="value">Value to apply.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
protected virtual bool RequiresUpdate<T>(ref T storage, T value)
|
||||||
|
{
|
||||||
|
return !Equals(storage, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the property already matches the desired value and updates it if not.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of the property.</typeparam>
|
||||||
|
/// <param name="storage">Reference to the backing-filed.</param>
|
||||||
|
/// <param name="value">Value to apply.</param>
|
||||||
|
/// <param name="propertyName">
|
||||||
|
/// Name of the property used to notify listeners. This value is optional
|
||||||
|
/// and can be provided automatically when invoked from compilers that support <see cref="CallerMemberNameAttribute" />
|
||||||
|
/// .
|
||||||
|
/// </param>
|
||||||
|
/// <returns><c>true</c> if the value was changed, <c>false</c> if the existing value matched the desired value.</returns>
|
||||||
|
protected virtual bool SetAndNotify<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
if (!RequiresUpdate(ref storage, value)) return false;
|
||||||
|
|
||||||
|
storage = value;
|
||||||
|
// ReSharper disable once ExplicitCallerInfoArgument
|
||||||
|
OnPropertyChanged(propertyName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Triggers the <see cref="PropertyChanged" />-event when a a property value has changed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="propertyName">
|
||||||
|
/// Name of the property used to notify listeners. This value is optional
|
||||||
|
/// and can be provided automatically when invoked from compilers that support <see cref="CallerMemberNameAttribute" />
|
||||||
|
/// .
|
||||||
|
/// </param>
|
||||||
|
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,7 +5,6 @@ using System.Linq;
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using Artemis.Core.Properties;
|
using Artemis.Core.Properties;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
@ -19,13 +18,13 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ColorGradient()
|
public ColorGradient()
|
||||||
{
|
{
|
||||||
Stops = new BindableCollection<ColorGradientStop>();
|
Stops = new List<ColorGradientStop>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a list of all the <see cref="ColorGradientStop" />s in the gradient
|
/// Gets a list of all the <see cref="ColorGradientStop" />s in the gradient
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public BindableCollection<ColorGradientStop> Stops { get; }
|
public List<ColorGradientStop> Stops { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets all the colors in the color gradient
|
/// Gets all the colors in the color gradient
|
||||||
|
|||||||
@ -22,10 +22,10 @@ namespace Artemis.Core
|
|||||||
public abstract string Icon { get; }
|
public abstract string Icon { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin info this condition operator belongs to
|
/// Gets the plugin this condition operator belongs to
|
||||||
/// <para>Note: Not set until after registering</para>
|
/// <para>Note: Not set until after registering</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginInfo PluginInfo { get; internal set; }
|
public Plugin Plugin { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the left side type of this condition operator
|
/// Gets the left side type of this condition operator
|
||||||
|
|||||||
@ -346,7 +346,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
if (Operator != null)
|
if (Operator != null)
|
||||||
{
|
{
|
||||||
Entity.OperatorPluginGuid = Operator.PluginInfo.Guid;
|
Entity.OperatorPluginGuid = Operator.Plugin.Guid;
|
||||||
Entity.OperatorType = Operator.GetType().Name;
|
Entity.OperatorType = Operator.GetType().Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -358,7 +358,7 @@ namespace Artemis.Core
|
|||||||
private void ConditionOperatorStoreOnConditionOperatorAdded(object? sender, ConditionOperatorStoreEvent e)
|
private void ConditionOperatorStoreOnConditionOperatorAdded(object? sender, ConditionOperatorStoreEvent e)
|
||||||
{
|
{
|
||||||
BaseConditionOperator conditionOperator = e.Registration.ConditionOperator;
|
BaseConditionOperator conditionOperator = e.Registration.ConditionOperator;
|
||||||
if (Entity.OperatorPluginGuid == conditionOperator.PluginInfo.Guid && Entity.OperatorType == conditionOperator.GetType().Name)
|
if (Entity.OperatorPluginGuid == conditionOperator.Plugin.Guid && Entity.OperatorType == conditionOperator.GetType().Name)
|
||||||
UpdateOperator(conditionOperator);
|
UpdateOperator(conditionOperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
internal EventPredicateWrapperDataModel()
|
internal EventPredicateWrapperDataModel()
|
||||||
{
|
{
|
||||||
Implementation = Constants.CorePluginInfo;
|
Feature = Constants.CorePluginFeature;
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataModelIgnore]
|
[DataModelIgnore]
|
||||||
|
|||||||
@ -16,7 +16,7 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
internal ListPredicateWrapperDataModel()
|
internal ListPredicateWrapperDataModel()
|
||||||
{
|
{
|
||||||
Implementation = Constants.CorePluginInfo;
|
Feature = Constants.CorePluginFeature;
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataModelIgnore]
|
[DataModelIgnore]
|
||||||
|
|||||||
@ -12,10 +12,10 @@ namespace Artemis.Core
|
|||||||
public abstract class BaseDataBindingModifierType
|
public abstract class BaseDataBindingModifierType
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin info this data binding modifier belongs to
|
/// Gets the plugin this data binding modifier belongs to
|
||||||
/// <para>Note: Not set until after registering</para>
|
/// <para>Note: Not set until after registering</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginInfo PluginInfo { get; internal set; }
|
public Plugin Plugin { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the value type of this modifier type
|
/// Gets the value type of this modifier type
|
||||||
|
|||||||
@ -238,7 +238,7 @@ namespace Artemis.Core
|
|||||||
if (ModifierType != null)
|
if (ModifierType != null)
|
||||||
{
|
{
|
||||||
Entity.ModifierType = ModifierType.GetType().Name;
|
Entity.ModifierType = ModifierType.GetType().Name;
|
||||||
Entity.ModifierTypePluginGuid = ModifierType.PluginInfo.Guid;
|
Entity.ModifierTypePluginGuid = ModifierType.Plugin.Guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// General
|
// General
|
||||||
@ -286,7 +286,7 @@ namespace Artemis.Core
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
BaseDataBindingModifierType modifierType = e.TypeRegistration.DataBindingModifierType;
|
BaseDataBindingModifierType modifierType = e.TypeRegistration.DataBindingModifierType;
|
||||||
if (modifierType.PluginInfo.Guid == Entity.ModifierTypePluginGuid && modifierType.GetType().Name == Entity.ModifierType)
|
if (modifierType.Plugin.Guid == Entity.ModifierTypePluginGuid && modifierType.GetType().Name == Entity.ModifierType)
|
||||||
UpdateModifierType(modifierType);
|
UpdateModifierType(modifierType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -91,9 +91,9 @@ namespace Artemis.Core
|
|||||||
public DataModel? Target { get; private set; }
|
public DataModel? Target { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the data model GUID of the <see cref="Target" /> if it is a <see cref="DataModel" />
|
/// Gets the data model ID of the <see cref="Target" /> if it is a <see cref="DataModel" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid? DataModelGuid => Target?.Implementation.Guid;
|
public string? DataModelId => Target?.Feature.Id;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the point-separated path associated with this <see cref="DataModelPath" />
|
/// Gets the point-separated path associated with this <see cref="DataModelPath" />
|
||||||
@ -267,8 +267,8 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
Path = Entity.Path;
|
Path = Entity.Path;
|
||||||
|
|
||||||
if (Target == null && Entity.DataModelGuid != null)
|
if (Target == null && Entity.DataModelId != null)
|
||||||
Target = DataModelStore.Get(Entity.DataModelGuid.Value)?.DataModel;
|
Target = DataModelStore.Get(Entity.DataModelId)?.DataModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -279,7 +279,7 @@ namespace Artemis.Core
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Entity.Path = Path;
|
Entity.Path = Path;
|
||||||
Entity.DataModelGuid = DataModelGuid;
|
Entity.DataModelId = DataModelId;
|
||||||
|
|
||||||
Entity.WrapperType = Target switch
|
Entity.WrapperType = Target switch
|
||||||
{
|
{
|
||||||
@ -295,7 +295,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private void DataModelStoreOnDataModelAdded(object? sender, DataModelStoreEvent e)
|
private void DataModelStoreOnDataModelAdded(object? sender, DataModelStoreEvent e)
|
||||||
{
|
{
|
||||||
if (e.Registration.DataModel.Implementation.Guid != Entity.DataModelGuid)
|
if (e.Registration.DataModel.Feature.Id != Entity.DataModelId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Target = e.Registration.DataModel;
|
Target = e.Registration.DataModel;
|
||||||
@ -304,7 +304,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private void DataModelStoreOnDataModelRemoved(object? sender, DataModelStoreEvent e)
|
private void DataModelStoreOnDataModelRemoved(object? sender, DataModelStoreEvent e)
|
||||||
{
|
{
|
||||||
if (e.Registration.DataModel.Implementation.Guid != Entity.DataModelGuid)
|
if (e.Registration.DataModel.Feature.Id != Entity.DataModelId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Target = null;
|
Target = null;
|
||||||
|
|||||||
@ -190,9 +190,9 @@ namespace Artemis.Core
|
|||||||
typeof(PropertyGroupDescriptionAttribute)
|
typeof(PropertyGroupDescriptionAttribute)
|
||||||
);
|
);
|
||||||
General.GroupDescription = (PropertyGroupDescriptionAttribute) generalAttribute;
|
General.GroupDescription = (PropertyGroupDescriptionAttribute) generalAttribute;
|
||||||
General.Initialize(this, "General.", Constants.CorePluginInfo);
|
General.Initialize(this, "General.", Constants.CorePluginFeature);
|
||||||
Transform.GroupDescription = (PropertyGroupDescriptionAttribute) transformAttribute;
|
Transform.GroupDescription = (PropertyGroupDescriptionAttribute) transformAttribute;
|
||||||
Transform.Initialize(this, "Transform.", Constants.CorePluginInfo);
|
Transform.Initialize(this, "Transform.", Constants.CorePluginFeature);
|
||||||
|
|
||||||
General.ShapeType.CurrentValueSet += ShapeTypeOnCurrentValueSet;
|
General.ShapeType.CurrentValueSet += ShapeTypeOnCurrentValueSet;
|
||||||
ApplyShapeType();
|
ApplyShapeType();
|
||||||
@ -619,7 +619,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
BaseLayerBrush brush = LayerBrush;
|
BaseLayerBrush brush = LayerBrush;
|
||||||
DeactivateLayerBrush();
|
DeactivateLayerBrush();
|
||||||
LayerEntity.PropertyEntities.RemoveAll(p => p.PluginGuid == brush.PluginInfo.Guid && p.Path.StartsWith("LayerBrush."));
|
LayerEntity.PropertyEntities.RemoveAll(p => p.FeatureId == brush.ProviderId && p.Path.StartsWith("LayerBrush."));
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ActivateLayerBrush()
|
internal void ActivateLayerBrush()
|
||||||
@ -628,7 +628,7 @@ namespace Artemis.Core
|
|||||||
if (current == null)
|
if (current == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LayerBrushDescriptor descriptor = LayerBrushStore.Get(current.BrushPluginGuid, current.BrushType)?.LayerBrushDescriptor;
|
LayerBrushDescriptor? descriptor = LayerBrushStore.Get(current.LayerBrushProviderId, current.BrushType)?.LayerBrushDescriptor;
|
||||||
descriptor?.CreateInstance(this);
|
descriptor?.CreateInstance(this);
|
||||||
|
|
||||||
OnLayerBrushUpdated();
|
OnLayerBrushUpdated();
|
||||||
@ -662,7 +662,7 @@ namespace Artemis.Core
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
LayerBrushReference current = General.BrushReference.CurrentValue;
|
LayerBrushReference current = General.BrushReference.CurrentValue;
|
||||||
if (e.Registration.PluginImplementation.PluginInfo.Guid == current.BrushPluginGuid &&
|
if (e.Registration.PluginFeature.Id == current.LayerBrushProviderId &&
|
||||||
e.Registration.LayerBrushDescriptor.LayerBrushType.Name == current.BrushType)
|
e.Registration.LayerBrushDescriptor.LayerBrushType.Name == current.BrushType)
|
||||||
ActivateLayerBrush();
|
ActivateLayerBrush();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using Artemis.Core.LayerBrushes;
|
||||||
using Artemis.Core.LayerBrushes;
|
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
@ -8,24 +7,24 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class LayerBrushReference
|
public class LayerBrushReference
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The GUID of the plugin the brush descriptor resides in
|
|
||||||
/// </summary>
|
|
||||||
public Guid BrushPluginGuid { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The full type name of the brush descriptor
|
|
||||||
/// </summary>
|
|
||||||
public string BrushType { get; set; }
|
|
||||||
|
|
||||||
public LayerBrushReference()
|
public LayerBrushReference()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public LayerBrushReference(LayerBrushDescriptor descriptor)
|
public LayerBrushReference(LayerBrushDescriptor descriptor)
|
||||||
{
|
{
|
||||||
BrushPluginGuid = descriptor.LayerBrushProvider.PluginInfo.Guid;
|
LayerBrushProviderId = descriptor.Provider.Id;
|
||||||
BrushType = descriptor.LayerBrushType.Name;
|
BrushType = descriptor.LayerBrushType.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ID of the layer brush provided the brush was provided by
|
||||||
|
/// </summary>
|
||||||
|
public string LayerBrushProviderId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The full type name of the brush descriptor
|
||||||
|
/// </summary>
|
||||||
|
public string BrushType { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,12 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a keyframe on a <see cref="LayerProperty{T}" /> containing a value and a timestamp
|
/// Represents a keyframe on a <see cref="LayerProperty{T}" /> containing a value and a timestamp
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class LayerPropertyKeyframe<T> : PropertyChangedBase
|
public class LayerPropertyKeyframe<T> : CorePropertyChanged
|
||||||
{
|
{
|
||||||
private LayerProperty<T> _layerProperty;
|
private LayerProperty<T> _layerProperty;
|
||||||
private TimeSpan _position;
|
private TimeSpan _position;
|
||||||
|
|||||||
@ -30,9 +30,9 @@ namespace Artemis.Core
|
|||||||
public PropertyGroupDescriptionAttribute GroupDescription { get; internal set; }
|
public PropertyGroupDescriptionAttribute GroupDescription { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the info of the plugin this group is associated with
|
/// Gets the plugin feature this group is associated with
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginInfo PluginInfo { get; internal set; }
|
public PluginFeature Feature { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the profile element (such as layer or folder) this group is associated with
|
/// Gets the profile element (such as layer or folder) this group is associated with
|
||||||
@ -145,18 +145,18 @@ namespace Artemis.Core
|
|||||||
PropertyGroupInitialized?.Invoke(this, EventArgs.Empty);
|
PropertyGroupInitialized?.Invoke(this, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Initialize(RenderProfileElement profileElement, [NotNull] string path, PluginInfo pluginInfo)
|
internal void Initialize(RenderProfileElement profileElement, [NotNull] string path, PluginFeature feature)
|
||||||
{
|
{
|
||||||
if (path == null)
|
if (path == null)
|
||||||
throw new ArgumentNullException(nameof(path));
|
throw new ArgumentNullException(nameof(path));
|
||||||
if (pluginInfo == null)
|
if (feature == null)
|
||||||
throw new ArgumentNullException(nameof(pluginInfo));
|
throw new ArgumentNullException(nameof(feature));
|
||||||
|
|
||||||
// Doubt this will happen but let's make sure
|
// Doubt this will happen but let's make sure
|
||||||
if (PropertiesInitialized)
|
if (PropertiesInitialized)
|
||||||
throw new ArtemisCoreException("Layer property group already initialized, wut");
|
throw new ArtemisCoreException("Layer property group already initialized, wut");
|
||||||
|
|
||||||
PluginInfo = pluginInfo;
|
Feature = feature;
|
||||||
ProfileElement = profileElement;
|
ProfileElement = profileElement;
|
||||||
Path = path.TrimEnd('.');
|
Path = path.TrimEnd('.');
|
||||||
|
|
||||||
@ -246,7 +246,7 @@ namespace Artemis.Core
|
|||||||
instance.GroupDescription = propertyGroupDescription;
|
instance.GroupDescription = propertyGroupDescription;
|
||||||
instance.LayerBrush = LayerBrush;
|
instance.LayerBrush = LayerBrush;
|
||||||
instance.LayerEffect = LayerEffect;
|
instance.LayerEffect = LayerEffect;
|
||||||
instance.Initialize(ProfileElement, $"{path}{propertyInfo.Name}.", PluginInfo);
|
instance.Initialize(ProfileElement, $"{path}{propertyInfo.Name}.", Feature);
|
||||||
|
|
||||||
propertyInfo.SetValue(this, instance);
|
propertyInfo.SetValue(this, instance);
|
||||||
_layerPropertyGroups.Add(instance);
|
_layerPropertyGroups.Add(instance);
|
||||||
@ -254,11 +254,11 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private PropertyEntity GetPropertyEntity(RenderProfileElement profileElement, string path, out bool fromStorage)
|
private PropertyEntity GetPropertyEntity(RenderProfileElement profileElement, string path, out bool fromStorage)
|
||||||
{
|
{
|
||||||
PropertyEntity entity = profileElement.RenderElementEntity.PropertyEntities.FirstOrDefault(p => p.PluginGuid == PluginInfo.Guid && p.Path == path);
|
PropertyEntity entity = profileElement.RenderElementEntity.PropertyEntities.FirstOrDefault(p => p.FeatureId == Feature.Id && p.Path == path);
|
||||||
fromStorage = entity != null;
|
fromStorage = entity != null;
|
||||||
if (entity == null)
|
if (entity == null)
|
||||||
{
|
{
|
||||||
entity = new PropertyEntity {PluginGuid = PluginInfo.Guid, Path = path};
|
entity = new PropertyEntity {FeatureId = Feature.Id, Path = path};
|
||||||
profileElement.RenderElementEntity.PropertyEntities.Add(entity);
|
profileElement.RenderElementEntity.PropertyEntities.Add(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Core.Modules;
|
using Artemis.Core.Modules;
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
@ -147,7 +146,7 @@ namespace Artemis.Core
|
|||||||
throw new ObjectDisposedException("Profile");
|
throw new ObjectDisposedException("Profile");
|
||||||
|
|
||||||
ProfileEntity.Id = EntityId;
|
ProfileEntity.Id = EntityId;
|
||||||
ProfileEntity.PluginGuid = Module.PluginInfo.Guid;
|
ProfileEntity.ModuleId = Module.Id;
|
||||||
ProfileEntity.Name = Name;
|
ProfileEntity.Name = Name;
|
||||||
ProfileEntity.IsActive = IsActivated;
|
ProfileEntity.IsActive = IsActivated;
|
||||||
|
|
||||||
|
|||||||
@ -3,11 +3,10 @@ using System.Collections.Generic;
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
public abstract class ProfileElement : PropertyChangedBase, IDisposable
|
public abstract class ProfileElement : CorePropertyChanged, IDisposable
|
||||||
{
|
{
|
||||||
private bool _enabled;
|
private bool _enabled;
|
||||||
private Guid _entityId;
|
private Guid _entityId;
|
||||||
|
|||||||
@ -44,7 +44,7 @@ namespace Artemis.Core
|
|||||||
LayerEffectEntity layerEffectEntity = new LayerEffectEntity
|
LayerEffectEntity layerEffectEntity = new LayerEffectEntity
|
||||||
{
|
{
|
||||||
Id = layerEffect.EntityId,
|
Id = layerEffect.EntityId,
|
||||||
PluginGuid = layerEffect.Descriptor.PlaceholderFor ?? layerEffect.PluginInfo.Guid,
|
ProviderId = layerEffect.Descriptor.PlaceholderFor ?? layerEffect.ProviderId,
|
||||||
EffectType = layerEffect.GetEffectTypeName(),
|
EffectType = layerEffect.GetEffectTypeName(),
|
||||||
Name = layerEffect.Name,
|
Name = layerEffect.Name,
|
||||||
Enabled = layerEffect.Enabled,
|
Enabled = layerEffect.Enabled,
|
||||||
@ -215,11 +215,11 @@ namespace Artemis.Core
|
|||||||
foreach (LayerEffectEntity layerEffectEntity in RenderElementEntity.LayerEffects)
|
foreach (LayerEffectEntity layerEffectEntity in RenderElementEntity.LayerEffects)
|
||||||
{
|
{
|
||||||
// If there is a non-placeholder existing effect, skip this entity
|
// If there is a non-placeholder existing effect, skip this entity
|
||||||
BaseLayerEffect existing = _layerEffects.FirstOrDefault(e => e.EntityId == layerEffectEntity.Id);
|
BaseLayerEffect? existing = _layerEffects.FirstOrDefault(e => e.EntityId == layerEffectEntity.Id);
|
||||||
if (existing != null && existing.Descriptor.PlaceholderFor == null)
|
if (existing != null && existing.Descriptor.PlaceholderFor == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
LayerEffectDescriptor descriptor = LayerEffectStore.Get(layerEffectEntity.PluginGuid, layerEffectEntity.EffectType)?.LayerEffectDescriptor;
|
LayerEffectDescriptor? descriptor = LayerEffectStore.Get(layerEffectEntity.ProviderId, layerEffectEntity.EffectType)?.LayerEffectDescriptor;
|
||||||
if (descriptor != null)
|
if (descriptor != null)
|
||||||
{
|
{
|
||||||
// If a descriptor is found but there is an existing placeholder, remove the placeholder
|
// If a descriptor is found but there is an existing placeholder, remove the placeholder
|
||||||
@ -235,7 +235,7 @@ namespace Artemis.Core
|
|||||||
else if (existing == null)
|
else if (existing == null)
|
||||||
{
|
{
|
||||||
// If no descriptor was found and there was no existing placeholder, create a placeholder
|
// If no descriptor was found and there was no existing placeholder, create a placeholder
|
||||||
descriptor = PlaceholderLayerEffectDescriptor.Create(layerEffectEntity.PluginGuid);
|
descriptor = PlaceholderLayerEffectDescriptor.Create(layerEffectEntity.ProviderId);
|
||||||
descriptor.CreateInstance(this, layerEffectEntity);
|
descriptor.CreateInstance(this, layerEffectEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -253,22 +253,22 @@ namespace Artemis.Core
|
|||||||
private void LayerEffectStoreOnLayerEffectRemoved(object sender, LayerEffectStoreEvent e)
|
private void LayerEffectStoreOnLayerEffectRemoved(object sender, LayerEffectStoreEvent e)
|
||||||
{
|
{
|
||||||
// If effects provided by the plugin are on the element, replace them with placeholders
|
// If effects provided by the plugin are on the element, replace them with placeholders
|
||||||
List<BaseLayerEffect> pluginEffects = _layerEffects.Where(ef => ef.Descriptor.LayerEffectProvider != null &&
|
List<BaseLayerEffect> pluginEffects = _layerEffects.Where(ef => ef.Descriptor.Provider != null &&
|
||||||
ef.PluginInfo.Guid == e.Registration.PluginImplementation.PluginInfo.Guid).ToList();
|
ef.ProviderId == e.Registration.PluginFeature.Id).ToList();
|
||||||
foreach (BaseLayerEffect pluginEffect in pluginEffects)
|
foreach (BaseLayerEffect pluginEffect in pluginEffects)
|
||||||
{
|
{
|
||||||
LayerEffectEntity entity = RenderElementEntity.LayerEffects.First(en => en.Id == pluginEffect.EntityId);
|
LayerEffectEntity entity = RenderElementEntity.LayerEffects.First(en => en.Id == pluginEffect.EntityId);
|
||||||
_layerEffects.Remove(pluginEffect);
|
_layerEffects.Remove(pluginEffect);
|
||||||
pluginEffect.Dispose();
|
pluginEffect.Dispose();
|
||||||
|
|
||||||
LayerEffectDescriptor descriptor = PlaceholderLayerEffectDescriptor.Create(pluginEffect.PluginInfo.Guid);
|
LayerEffectDescriptor descriptor = PlaceholderLayerEffectDescriptor.Create(pluginEffect.ProviderId);
|
||||||
descriptor.CreateInstance(this, entity);
|
descriptor.CreateInstance(this, entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LayerEffectStoreOnLayerEffectAdded(object sender, LayerEffectStoreEvent e)
|
private void LayerEffectStoreOnLayerEffectAdded(object sender, LayerEffectStoreEvent e)
|
||||||
{
|
{
|
||||||
if (RenderElementEntity.LayerEffects.Any(ef => ef.PluginGuid == e.Registration.PluginImplementation.PluginInfo.Guid))
|
if (RenderElementEntity.LayerEffects.Any(ef => ef.ProviderId == e.Registration.PluginFeature.Id))
|
||||||
ActivateEffects();
|
ActivateEffects();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,14 +3,13 @@ using System.Collections.Generic;
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a timeline used by profile elements
|
/// Represents a timeline used by profile elements
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Timeline : PropertyChangedBase, IStorageModel
|
public class Timeline : CorePropertyChanged, IStorageModel
|
||||||
{
|
{
|
||||||
private const int MaxExtraTimelines = 15;
|
private const int MaxExtraTimelines = 15;
|
||||||
|
|
||||||
@ -275,20 +274,20 @@ namespace Artemis.Core
|
|||||||
if (segment <= TimelineSegment.End)
|
if (segment <= TimelineSegment.End)
|
||||||
{
|
{
|
||||||
if (startUpdated || segment < TimelineSegment.End)
|
if (startUpdated || segment < TimelineSegment.End)
|
||||||
NotifyOfPropertyChange(nameof(EndSegmentStartPosition));
|
OnPropertyChanged(nameof(EndSegmentStartPosition));
|
||||||
NotifyOfPropertyChange(nameof(EndSegmentEndPosition));
|
OnPropertyChanged(nameof(EndSegmentEndPosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segment <= TimelineSegment.Main)
|
if (segment <= TimelineSegment.Main)
|
||||||
{
|
{
|
||||||
if (startUpdated || segment < TimelineSegment.Main)
|
if (startUpdated || segment < TimelineSegment.Main)
|
||||||
NotifyOfPropertyChange(nameof(MainSegmentStartPosition));
|
OnPropertyChanged(nameof(MainSegmentStartPosition));
|
||||||
NotifyOfPropertyChange(nameof(MainSegmentEndPosition));
|
OnPropertyChanged(nameof(MainSegmentEndPosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (segment <= TimelineSegment.Start) NotifyOfPropertyChange(nameof(StartSegmentEndPosition));
|
if (segment <= TimelineSegment.Start) OnPropertyChanged(nameof(StartSegmentEndPosition));
|
||||||
|
|
||||||
NotifyOfPropertyChange(nameof(Length));
|
OnPropertyChanged(nameof(Length));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@ -4,20 +4,19 @@ using System.Linq;
|
|||||||
using Artemis.Storage.Entities.Surface;
|
using Artemis.Storage.Entities.Surface;
|
||||||
using RGB.NET.Core;
|
using RGB.NET.Core;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
public class ArtemisDevice : PropertyChangedBase
|
public class ArtemisDevice : CorePropertyChanged
|
||||||
{
|
{
|
||||||
private ReadOnlyCollection<ArtemisLed> _leds;
|
private ReadOnlyCollection<ArtemisLed> _leds;
|
||||||
private SKPath _renderPath;
|
private SKPath _renderPath;
|
||||||
private SKRect _renderRectangle;
|
private SKRect _renderRectangle;
|
||||||
|
|
||||||
internal ArtemisDevice(IRGBDevice rgbDevice, PluginImplementation pluginImplementation, ArtemisSurface surface)
|
internal ArtemisDevice(IRGBDevice rgbDevice, PluginFeature pluginFeature, ArtemisSurface surface)
|
||||||
{
|
{
|
||||||
RgbDevice = rgbDevice;
|
RgbDevice = rgbDevice;
|
||||||
PluginImplementation = pluginImplementation;
|
PluginFeature = pluginFeature;
|
||||||
Surface = surface;
|
Surface = surface;
|
||||||
DeviceEntity = new DeviceEntity();
|
DeviceEntity = new DeviceEntity();
|
||||||
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
||||||
@ -30,10 +29,10 @@ namespace Artemis.Core
|
|||||||
CalculateRenderProperties();
|
CalculateRenderProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ArtemisDevice(IRGBDevice rgbDevice, PluginImplementation pluginImplementation, ArtemisSurface surface, DeviceEntity deviceEntity)
|
internal ArtemisDevice(IRGBDevice rgbDevice, PluginFeature pluginFeature, ArtemisSurface surface, DeviceEntity deviceEntity)
|
||||||
{
|
{
|
||||||
RgbDevice = rgbDevice;
|
RgbDevice = rgbDevice;
|
||||||
PluginImplementation = pluginImplementation;
|
PluginFeature = pluginFeature;
|
||||||
Surface = surface;
|
Surface = surface;
|
||||||
DeviceEntity = deviceEntity;
|
DeviceEntity = deviceEntity;
|
||||||
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
|
||||||
@ -52,7 +51,7 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IRGBDevice RgbDevice { get; }
|
public IRGBDevice RgbDevice { get; }
|
||||||
public PluginImplementation PluginImplementation { get; }
|
public PluginFeature PluginFeature { get; }
|
||||||
public ArtemisSurface Surface { get; }
|
public ArtemisSurface Surface { get; }
|
||||||
public DeviceEntity DeviceEntity { get; }
|
public DeviceEntity DeviceEntity { get; }
|
||||||
|
|
||||||
@ -68,7 +67,7 @@ namespace Artemis.Core
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
DeviceEntity.X = value;
|
DeviceEntity.X = value;
|
||||||
NotifyOfPropertyChange(nameof(X));
|
OnPropertyChanged(nameof(X));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +77,7 @@ namespace Artemis.Core
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
DeviceEntity.Y = value;
|
DeviceEntity.Y = value;
|
||||||
NotifyOfPropertyChange(nameof(Y));
|
OnPropertyChanged(nameof(Y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +87,7 @@ namespace Artemis.Core
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
DeviceEntity.Rotation = value;
|
DeviceEntity.Rotation = value;
|
||||||
NotifyOfPropertyChange(nameof(Rotation));
|
OnPropertyChanged(nameof(Rotation));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +97,7 @@ namespace Artemis.Core
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
DeviceEntity.Scale = value;
|
DeviceEntity.Scale = value;
|
||||||
NotifyOfPropertyChange(nameof(Scale));
|
OnPropertyChanged(nameof(Scale));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +107,7 @@ namespace Artemis.Core
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
DeviceEntity.ZIndex = value;
|
DeviceEntity.ZIndex = value;
|
||||||
NotifyOfPropertyChange(nameof(ZIndex));
|
OnPropertyChanged(nameof(ZIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
using RGB.NET.Core;
|
using RGB.NET.Core;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
public class ArtemisLed : PropertyChangedBase
|
public class ArtemisLed : CorePropertyChanged
|
||||||
{
|
{
|
||||||
private SKRect _absoluteRenderRectangle;
|
private SKRect _absoluteRenderRectangle;
|
||||||
private SKRect _renderRectangle;
|
private SKRect _renderRectangle;
|
||||||
|
|||||||
@ -3,11 +3,10 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Storage.Entities.Surface;
|
using Artemis.Storage.Entities.Surface;
|
||||||
using RGB.NET.Core;
|
using RGB.NET.Core;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
public class ArtemisSurface : PropertyChangedBase
|
public class ArtemisSurface : CorePropertyChanged
|
||||||
{
|
{
|
||||||
private List<ArtemisDevice> _devices;
|
private List<ArtemisDevice> _devices;
|
||||||
private bool _isActive;
|
private bool _isActive;
|
||||||
|
|||||||
@ -6,6 +6,7 @@ using Ninject.Activation;
|
|||||||
|
|
||||||
namespace Artemis.Core.Ninject
|
namespace Artemis.Core.Ninject
|
||||||
{
|
{
|
||||||
|
// TODO: Investigate if this can't just be set as a constant on the plugin child kernel
|
||||||
internal class PluginSettingsProvider : Provider<PluginSettings>
|
internal class PluginSettingsProvider : Provider<PluginSettings>
|
||||||
{
|
{
|
||||||
private static readonly List<PluginSettings> PluginSettings = new List<PluginSettings>();
|
private static readonly List<PluginSettings> PluginSettings = new List<PluginSettings>();
|
||||||
@ -25,21 +26,22 @@ namespace Artemis.Core.Ninject
|
|||||||
throw new ArtemisCoreException("PluginSettings couldn't be injected, failed to get the injection parent request");
|
throw new ArtemisCoreException("PluginSettings couldn't be injected, failed to get the injection parent request");
|
||||||
|
|
||||||
// First try by PluginInfo parameter
|
// First try by PluginInfo parameter
|
||||||
PluginInfo pluginInfo = parentRequest.Parameters.FirstOrDefault(p => p.Name == "PluginInfo")?.GetValue(context, null) as PluginInfo;
|
Plugin? plugin = parentRequest.Parameters.FirstOrDefault(p => p.Name == "Plugin")?.GetValue(context, null) as Plugin;
|
||||||
if (pluginInfo == null)
|
|
||||||
pluginInfo = _pluginManagementService.GetPluginByAssembly(parentRequest.Service.Assembly)?.PluginInfo;
|
|
||||||
// Fall back to assembly based detection
|
// Fall back to assembly based detection
|
||||||
if (pluginInfo == null)
|
if (plugin == null)
|
||||||
|
plugin = _pluginManagementService.GetPluginByAssembly(parentRequest.Service.Assembly);
|
||||||
|
|
||||||
|
if (plugin == null)
|
||||||
throw new ArtemisCoreException("PluginSettings can only be injected with the PluginInfo parameter provided " +
|
throw new ArtemisCoreException("PluginSettings can only be injected with the PluginInfo parameter provided " +
|
||||||
"or into a class defined in a plugin assembly");
|
"or into a class defined in a plugin assembly");
|
||||||
|
|
||||||
lock (PluginSettings)
|
lock (PluginSettings)
|
||||||
{
|
{
|
||||||
PluginSettings? existingSettings = PluginSettings.FirstOrDefault(p => p.PluginInfo == pluginInfo);
|
PluginSettings? existingSettings = PluginSettings.FirstOrDefault(p => p.Plugin == plugin);
|
||||||
if (existingSettings != null)
|
if (existingSettings != null)
|
||||||
return existingSettings;
|
return existingSettings;
|
||||||
|
|
||||||
PluginSettings? settings = new PluginSettings(pluginInfo, _pluginRepository);
|
PluginSettings? settings = new PluginSettings(plugin, _pluginRepository);
|
||||||
PluginSettings.Add(settings);
|
PluginSettings.Add(settings);
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ namespace Artemis.Core.Ninject
|
|||||||
protected override ISettingsService CreateInstance(IContext context)
|
protected override ISettingsService CreateInstance(IContext context)
|
||||||
{
|
{
|
||||||
IRequest parentRequest = context.Request.ParentRequest;
|
IRequest parentRequest = context.Request.ParentRequest;
|
||||||
if (parentRequest == null || typeof(PluginImplementation).IsAssignableFrom(parentRequest.Service))
|
if (parentRequest == null || typeof(PluginFeature).IsAssignableFrom(parentRequest.Service))
|
||||||
throw new ArtemisPluginException($"SettingsService can not be injected into a plugin. Inject {nameof(PluginSettings)} instead.");
|
throw new ArtemisPluginException($"SettingsService can not be injected into a plugin. Inject {nameof(PluginSettings)} instead.");
|
||||||
|
|
||||||
return _instance;
|
return _instance;
|
||||||
|
|||||||
@ -14,10 +14,10 @@ namespace Artemis.Core.DataModelExpansions
|
|||||||
private readonly Dictionary<string, DataModel> _dynamicDataModels = new Dictionary<string, DataModel>();
|
private readonly Dictionary<string, DataModel> _dynamicDataModels = new Dictionary<string, DataModel>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin implementation this data model belongs to
|
/// Gets the plugin feature this data model belongs to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataModelIgnore]
|
[DataModelIgnore]
|
||||||
public DataModelPluginImplementation Implementation { get; internal set; }
|
public DataModelPluginFeature Feature { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="DataModelPropertyAttribute" /> describing this data model
|
/// Gets the <see cref="DataModelPropertyAttribute" /> describing this data model
|
||||||
@ -43,9 +43,9 @@ namespace Artemis.Core.DataModelExpansions
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public ReadOnlyCollection<PropertyInfo> GetHiddenProperties()
|
public ReadOnlyCollection<PropertyInfo> GetHiddenProperties()
|
||||||
{
|
{
|
||||||
if (Implementation is ProfileModule profileModule)
|
if (Feature is ProfileModule profileModule)
|
||||||
return profileModule.HiddenProperties;
|
return profileModule.HiddenProperties;
|
||||||
if (Implementation is BaseDataModelExpansion dataModelExpansion)
|
if (Feature is BaseDataModelExpansion dataModelExpansion)
|
||||||
return dataModelExpansion.HiddenProperties;
|
return dataModelExpansion.HiddenProperties;
|
||||||
|
|
||||||
return new List<PropertyInfo>().AsReadOnly();
|
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}' " +
|
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.Implementation = Implementation;
|
dynamicDataModel.Feature = Feature;
|
||||||
dynamicDataModel.DataModelDescription = new DataModelPropertyAttribute
|
dynamicDataModel.DataModelDescription = new DataModelPropertyAttribute
|
||||||
{
|
{
|
||||||
Name = string.IsNullOrWhiteSpace(name) ? key.Humanize() : name,
|
Name = string.IsNullOrWhiteSpace(name) ? key.Humanize() : name,
|
||||||
|
|||||||
@ -45,7 +45,7 @@ namespace Artemis.Core.DataModelExpansions
|
|||||||
internal override void InternalEnable()
|
internal override void InternalEnable()
|
||||||
{
|
{
|
||||||
DataModel = Activator.CreateInstance<T>();
|
DataModel = Activator.CreateInstance<T>();
|
||||||
DataModel.Implementation = PluginInfo;
|
DataModel.Feature = this;
|
||||||
DataModel.DataModelDescription = GetDataModelDescription();
|
DataModel.DataModelDescription = GetDataModelDescription();
|
||||||
base.InternalEnable();
|
base.InternalEnable();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ namespace Artemis.Core.DataModelExpansions
|
|||||||
/// For internal use only, to implement your own layer property type, extend <see cref="DataModelExpansion{T}" />
|
/// For internal use only, to implement your own layer property type, extend <see cref="DataModelExpansion{T}" />
|
||||||
/// instead.
|
/// instead.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class BaseDataModelExpansion : DataModelPluginImplementation
|
public abstract class BaseDataModelExpansion : DataModelPluginFeature
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a list of all properties ignored at runtime using <c>IgnoreProperty(x => x.y)</c>
|
/// Gets a list of all properties ignored at runtime using <c>IgnoreProperty(x => x.y)</c>
|
||||||
@ -35,7 +35,7 @@ namespace Artemis.Core.DataModelExpansions
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual DataModelPropertyAttribute GetDataModelDescription()
|
public virtual DataModelPropertyAttribute GetDataModelDescription()
|
||||||
{
|
{
|
||||||
return new DataModelPropertyAttribute {Name = PluginInfo.Name, Description = PluginInfo.Description};
|
return new DataModelPropertyAttribute {Name = Plugin.Info.Name, Description = Plugin.Info.Description};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4,9 +4,9 @@ using System.Threading.Tasks;
|
|||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an implementation of a certain type provided by a plugin with support for data models
|
/// Represents an feature of a certain type provided by a plugin with support for data models
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class DataModelPluginImplementation : PluginImplementation
|
public abstract class DataModelPluginFeature : PluginFeature
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers a timed update that whenever the plugin is enabled calls the provided <paramref name="action" /> at the
|
/// Registers a timed update that whenever the plugin is enabled calls the provided <paramref name="action" /> at the
|
||||||
@ -23,11 +23,11 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
if (action == null)
|
if (action == null)
|
||||||
throw new ArgumentNullException(nameof(action));
|
throw new ArgumentNullException(nameof(action));
|
||||||
return new TimedUpdateRegistration(PluginInfo, interval, action);
|
return new TimedUpdateRegistration(this, interval, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers a timed update that whenever the plugin is enabled calls the provided <paramref name="action" /> at the
|
/// Registers a timed update that whenever the plugin is enabled calls the provided <paramref name="asyncAction" /> at the
|
||||||
/// provided
|
/// provided
|
||||||
/// <paramref name="interval" />
|
/// <paramref name="interval" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -41,7 +41,7 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
if (asyncAction == null)
|
if (asyncAction == null)
|
||||||
throw new ArgumentNullException(nameof(asyncAction));
|
throw new ArgumentNullException(nameof(asyncAction));
|
||||||
return new TimedUpdateRegistration(PluginInfo, interval, asyncAction);
|
return new TimedUpdateRegistration(this, interval, asyncAction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10,7 +10,7 @@ namespace Artemis.Core.DeviceProviders
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allows you to implement and register your own device provider
|
/// Allows you to implement and register your own device provider
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class DeviceProvider : PluginImplementation
|
public abstract class DeviceProvider : PluginFeature
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the <see cref="DeviceProvider" /> class
|
/// Creates a new instance of the <see cref="DeviceProvider" /> class
|
||||||
@ -50,9 +50,9 @@ namespace Artemis.Core.DeviceProviders
|
|||||||
{
|
{
|
||||||
// Start from the plugin directory
|
// Start from the plugin directory
|
||||||
if (e.RelativePart != null && e.FileName != null)
|
if (e.RelativePart != null && e.FileName != null)
|
||||||
e.FinalPath = Path.Combine(PluginInfo.Directory.FullName, e.RelativePart, e.FileName);
|
e.FinalPath = Path.Combine(Plugin.Directory.FullName, e.RelativePart, e.FileName);
|
||||||
else if (e.RelativePath != null)
|
else if (e.RelativePath != null)
|
||||||
e.FinalPath = Path.Combine(PluginInfo.Directory.FullName, e.RelativePath);
|
e.FinalPath = Path.Combine(Plugin.Directory.FullName, e.RelativePath);
|
||||||
|
|
||||||
IRGBDeviceInfo deviceInfo = ((IRGBDevice) sender).DeviceInfo;
|
IRGBDeviceInfo deviceInfo = ((IRGBDevice) sender).DeviceInfo;
|
||||||
if (e.FileName != null && !File.Exists(e.FinalPath))
|
if (e.FileName != null && !File.Exists(e.FinalPath))
|
||||||
|
|||||||
20
src/Artemis.Core/Plugins/IPluginBootstrapper.cs
Normal file
20
src/Artemis.Core/Plugins/IPluginBootstrapper.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An optional entry point for your plugin
|
||||||
|
/// </summary>
|
||||||
|
public interface IPluginBootstrapper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the plugin is activated
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="plugin">The plugin instance of your plugin</param>
|
||||||
|
void Enable(Plugin plugin);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when the plugin is deactivated or when Artemis shuts down
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="plugin">The plugin instance of your plugin</param>
|
||||||
|
void Disable(Plugin plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/Artemis.Core/Plugins/IPluginConfigurationDialog.cs
Normal file
7
src/Artemis.Core/Plugins/IPluginConfigurationDialog.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
public interface IPluginConfigurationDialog
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/Artemis.Core/Plugins/IPluginConfigurationViewModel.cs
Normal file
10
src/Artemis.Core/Plugins/IPluginConfigurationViewModel.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace Artemis.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents a view model for a plugin configuration window
|
||||||
|
/// </summary>
|
||||||
|
public interface IPluginConfigurationViewModel
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
namespace Artemis.Core.LayerBrushes
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the configuration dialog of a layer brush
|
||||||
|
/// </summary>
|
||||||
|
public interface ILayerBrushConfigurationDialog
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,17 +1,15 @@
|
|||||||
using System;
|
using System;
|
||||||
using Artemis.Core.Services;
|
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core.LayerBrushes
|
namespace Artemis.Core.LayerBrushes
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For internal use only, please use <see cref="LayerBrush{T}" /> or <see cref="RgbNetLayerBrush{T}" /> or instead
|
/// For internal use only, please use <see cref="LayerBrush{T}" /> or <see cref="RgbNetLayerBrush{T}" /> or instead
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class BaseLayerBrush : PropertyChangedBase, IDisposable
|
public abstract class BaseLayerBrush : CorePropertyChanged, IDisposable
|
||||||
{
|
{
|
||||||
private LayerBrushType _brushType;
|
private LayerBrushType _brushType;
|
||||||
private LayerBrushConfigurationDialog _configurationDialog;
|
private ILayerBrushConfigurationDialog _configurationDialog;
|
||||||
private LayerBrushDescriptor _descriptor;
|
private LayerBrushDescriptor _descriptor;
|
||||||
private Layer _layer;
|
private Layer _layer;
|
||||||
private bool _supportsTransformation = true;
|
private bool _supportsTransformation = true;
|
||||||
@ -37,7 +35,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a configuration dialog complementing the regular properties
|
/// Gets or sets a configuration dialog complementing the regular properties
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LayerBrushConfigurationDialog ConfigurationDialog
|
public ILayerBrushConfigurationDialog ConfigurationDialog
|
||||||
{
|
{
|
||||||
get => _configurationDialog;
|
get => _configurationDialog;
|
||||||
protected set => SetAndNotify(ref _configurationDialog, value);
|
protected set => SetAndNotify(ref _configurationDialog, value);
|
||||||
@ -53,9 +51,9 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin info that defined this brush
|
/// Gets the ID of the <see cref="LayerBrushProvider" /> that provided this effect
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginInfo PluginInfo => Descriptor.LayerBrushProvider.PluginInfo;
|
public string ProviderId => Descriptor?.Provider?.Id;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a reference to the layer property group without knowing it's type
|
/// Gets a reference to the layer property group without knowing it's type
|
||||||
@ -72,21 +70,11 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
protected set
|
protected set
|
||||||
{
|
{
|
||||||
if (value && BrushType == LayerBrushType.RgbNet)
|
if (value && BrushType == LayerBrushType.RgbNet)
|
||||||
throw new ArtemisPluginException(PluginInfo, "An RGB.NET brush cannot support transformation");
|
throw new ArtemisPluginFeatureException(Descriptor.Provider, "An RGB.NET brush cannot support transformation");
|
||||||
_supportsTransformation = value;
|
_supportsTransformation = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
DisableLayerBrush();
|
|
||||||
BaseProperties.Dispose();
|
|
||||||
|
|
||||||
Dispose(true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when the layer brush is activated
|
/// Called when the layer brush is activated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -112,6 +100,16 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
internal virtual void Dispose(bool disposing)
|
internal virtual void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
DisableLayerBrush();
|
||||||
|
BaseProperties.Dispose();
|
||||||
|
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -37,7 +37,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
Properties = Activator.CreateInstance<T>();
|
Properties = Activator.CreateInstance<T>();
|
||||||
Properties.GroupDescription ??= new PropertyGroupDescriptionAttribute {Name = Descriptor.DisplayName, Description = Descriptor.Description};
|
Properties.GroupDescription ??= new PropertyGroupDescriptionAttribute {Name = Descriptor.DisplayName, Description = Descriptor.Description};
|
||||||
Properties.LayerBrush = this;
|
Properties.LayerBrush = this;
|
||||||
Properties.Initialize(Layer, "LayerBrush.", PluginInfo);
|
Properties.Initialize(Layer, "LayerBrush.", Descriptor.Provider);
|
||||||
PropertiesInitialized = true;
|
PropertiesInitialized = true;
|
||||||
|
|
||||||
EnableLayerBrush();
|
EnableLayerBrush();
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using Artemis.Core.Services;
|
|
||||||
using Ninject;
|
using Ninject;
|
||||||
|
|
||||||
namespace Artemis.Core.LayerBrushes
|
namespace Artemis.Core.LayerBrushes
|
||||||
@ -9,13 +8,13 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class LayerBrushDescriptor
|
public class LayerBrushDescriptor
|
||||||
{
|
{
|
||||||
internal LayerBrushDescriptor(string displayName, string description, string icon, Type layerBrushType, LayerBrushProvider layerBrushProvider)
|
internal LayerBrushDescriptor(string displayName, string description, string icon, Type layerBrushType, LayerBrushProvider provider)
|
||||||
{
|
{
|
||||||
DisplayName = displayName;
|
DisplayName = displayName;
|
||||||
Description = description;
|
Description = description;
|
||||||
Icon = icon;
|
Icon = icon;
|
||||||
LayerBrushType = layerBrushType;
|
LayerBrushType = layerBrushType;
|
||||||
LayerBrushProvider = layerBrushProvider;
|
Provider = provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -42,7 +41,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The plugin that provided this <see cref="LayerBrushDescriptor" />
|
/// The plugin that provided this <see cref="LayerBrushDescriptor" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LayerBrushProvider LayerBrushProvider { get; }
|
public LayerBrushProvider Provider { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the provided <paramref name="reference" /> references to a brush provided by this descriptor
|
/// Determines whether the provided <paramref name="reference" /> references to a brush provided by this descriptor
|
||||||
@ -51,7 +50,8 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
{
|
{
|
||||||
if (reference == null)
|
if (reference == null)
|
||||||
return false;
|
return false;
|
||||||
return LayerBrushProvider.PluginInfo.Guid == reference.BrushPluginGuid && LayerBrushType.Name == reference.BrushType;
|
|
||||||
|
return Provider.Id == reference.LayerBrushProviderId && LayerBrushType.Name == reference.BrushType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -62,7 +62,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
if (layer.LayerBrush != null)
|
if (layer.LayerBrush != null)
|
||||||
throw new ArtemisCoreException("Layer already has an instantiated layer brush");
|
throw new ArtemisCoreException("Layer already has an instantiated layer brush");
|
||||||
|
|
||||||
BaseLayerBrush brush = (BaseLayerBrush) LayerBrushProvider.PluginInfo.Kernel.Get(LayerBrushType);
|
BaseLayerBrush brush = (BaseLayerBrush) Provider.Plugin.Kernel!.Get(LayerBrushType);
|
||||||
brush.Layer = layer;
|
brush.Layer = layer;
|
||||||
brush.Descriptor = this;
|
brush.Descriptor = this;
|
||||||
brush.Initialize();
|
brush.Initialize();
|
||||||
|
|||||||
@ -7,7 +7,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allows you to create one or more <see cref="LayerBrush{T}" />s usable by profile layers.
|
/// Allows you to create one or more <see cref="LayerBrush{T}" />s usable by profile layers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class LayerBrushProvider : PluginImplementation
|
public abstract class LayerBrushProvider : PluginFeature
|
||||||
{
|
{
|
||||||
private readonly List<LayerBrushDescriptor> _layerBrushDescriptors;
|
private readonly List<LayerBrushDescriptor> _layerBrushDescriptors;
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
protected void RegisterLayerBrushDescriptor<T>(string displayName, string description, string icon) where T : BaseLayerBrush
|
protected void RegisterLayerBrushDescriptor<T>(string displayName, string description, string icon) where T : BaseLayerBrush
|
||||||
{
|
{
|
||||||
if (!IsEnabled)
|
if (!IsEnabled)
|
||||||
throw new ArtemisPluginException(PluginInfo, "Can only add a layer brush descriptor when the plugin is enabled");
|
throw new ArtemisPluginException(Plugin, "Can only add a layer brush descriptor when the plugin is enabled");
|
||||||
|
|
||||||
LayerBrushDescriptor descriptor = new LayerBrushDescriptor(displayName, description, icon, typeof(T), this);
|
LayerBrushDescriptor descriptor = new LayerBrushDescriptor(displayName, description, icon, typeof(T), this);
|
||||||
_layerBrushDescriptors.Add(descriptor);
|
_layerBrushDescriptors.Add(descriptor);
|
||||||
|
|||||||
@ -0,0 +1,6 @@
|
|||||||
|
namespace Artemis.Core.LayerEffects
|
||||||
|
{
|
||||||
|
public interface IEffectConfigurationViewModel
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
namespace Artemis.Core.LayerEffects
|
||||||
|
{
|
||||||
|
public interface ILayerEffectConfigurationDialog
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,16 +1,15 @@
|
|||||||
using System;
|
using System;
|
||||||
using Artemis.Core.Services;
|
using Artemis.Core.Services;
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core.LayerEffects
|
namespace Artemis.Core.LayerEffects
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For internal use only, please use <see cref="LayerEffect{T}" /> instead
|
/// For internal use only, please use <see cref="LayerEffect{T}" /> instead
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class BaseLayerEffect : PropertyChangedBase, IDisposable
|
public abstract class BaseLayerEffect : CorePropertyChanged, IDisposable
|
||||||
{
|
{
|
||||||
private LayerEffectConfigurationDialog _configurationDialog;
|
private ILayerEffectConfigurationDialog _configurationDialog;
|
||||||
private LayerEffectDescriptor _descriptor;
|
private LayerEffectDescriptor _descriptor;
|
||||||
private bool _enabled;
|
private bool _enabled;
|
||||||
private Guid _entityId;
|
private Guid _entityId;
|
||||||
@ -77,7 +76,7 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="LayerEffectDescriptor" /> that registered this effect
|
/// Gets the <see cref="LayerEffectDescriptor" /> that registered this effect
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LayerEffectDescriptor Descriptor
|
public LayerEffectDescriptor? Descriptor
|
||||||
{
|
{
|
||||||
get => _descriptor;
|
get => _descriptor;
|
||||||
internal set => SetAndNotify(ref _descriptor, value);
|
internal set => SetAndNotify(ref _descriptor, value);
|
||||||
@ -86,16 +85,16 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a configuration dialog complementing the regular properties
|
/// Gets or sets a configuration dialog complementing the regular properties
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LayerEffectConfigurationDialog ConfigurationDialog
|
public ILayerEffectConfigurationDialog ConfigurationDialog
|
||||||
{
|
{
|
||||||
get => _configurationDialog;
|
get => _configurationDialog;
|
||||||
protected set => SetAndNotify(ref _configurationDialog, value);
|
protected set => SetAndNotify(ref _configurationDialog, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin info that defined this effect
|
/// Gets the ID of the <see cref="LayerEffectProvider"/> that provided this effect
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginInfo PluginInfo => Descriptor.LayerEffectProvider?.PluginInfo;
|
public string ProviderId => Descriptor?.Provider?.Id;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a reference to the layer property group without knowing it's type
|
/// Gets a reference to the layer property group without knowing it's type
|
||||||
|
|||||||
@ -37,7 +37,7 @@ namespace Artemis.Core.LayerEffects
|
|||||||
{
|
{
|
||||||
Properties = Activator.CreateInstance<T>();
|
Properties = Activator.CreateInstance<T>();
|
||||||
Properties.LayerEffect = this;
|
Properties.LayerEffect = this;
|
||||||
Properties.Initialize(ProfileElement, PropertyRootPath, PluginInfo);
|
Properties.Initialize(ProfileElement, PropertyRootPath, Descriptor.Provider);
|
||||||
PropertiesInitialized = true;
|
PropertiesInitialized = true;
|
||||||
|
|
||||||
EnableLayerEffect();
|
EnableLayerEffect();
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Artemis.Core.LayerEffects.Placeholder;
|
using Artemis.Core.LayerEffects.Placeholder;
|
||||||
using Artemis.Core.Services;
|
|
||||||
using Artemis.Storage.Entities.Profile;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Ninject;
|
using Ninject;
|
||||||
|
|
||||||
@ -12,13 +11,13 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class LayerEffectDescriptor
|
public class LayerEffectDescriptor
|
||||||
{
|
{
|
||||||
internal LayerEffectDescriptor(string displayName, string description, string icon, Type layerEffectType, LayerEffectProvider layerEffectProvider)
|
internal LayerEffectDescriptor(string displayName, string description, string icon, Type layerEffectType, LayerEffectProvider provider)
|
||||||
{
|
{
|
||||||
DisplayName = displayName;
|
DisplayName = displayName;
|
||||||
Description = description;
|
Description = description;
|
||||||
Icon = icon;
|
Icon = icon;
|
||||||
LayerEffectType = layerEffectType;
|
LayerEffectType = layerEffectType;
|
||||||
LayerEffectProvider = layerEffectProvider;
|
Provider = provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -45,12 +44,12 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The plugin that provided this <see cref="LayerEffectDescriptor" />
|
/// The plugin that provided this <see cref="LayerEffectDescriptor" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LayerEffectProvider LayerEffectProvider { get; }
|
public LayerEffectProvider? Provider { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the GUID this descriptor is acting as a placeholder for. If null, this descriptor is not a placeholder
|
/// Gets the GUID this descriptor is acting as a placeholder for. If null, this descriptor is not a placeholder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Guid? PlaceholderFor { get; internal set; }
|
public string? PlaceholderFor { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an instance of the described effect and applies it to the render element
|
/// Creates an instance of the described effect and applies it to the render element
|
||||||
@ -67,7 +66,10 @@ namespace Artemis.Core.LayerEffects
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseLayerEffect effect = (BaseLayerEffect) LayerEffectProvider.PluginInfo.Kernel.Get(LayerEffectType);
|
if (Provider == null)
|
||||||
|
throw new ArtemisCoreException("Cannot create an instance of a layer effect because this descriptor is not a placeholder but is still missing its provider");
|
||||||
|
|
||||||
|
BaseLayerEffect effect = (BaseLayerEffect) Provider.Plugin.Kernel!.Get(LayerEffectType);
|
||||||
effect.ProfileElement = renderElement;
|
effect.ProfileElement = renderElement;
|
||||||
effect.EntityId = entity.Id;
|
effect.EntityId = entity.Id;
|
||||||
effect.Order = entity.Order;
|
effect.Order = entity.Order;
|
||||||
@ -83,7 +85,7 @@ namespace Artemis.Core.LayerEffects
|
|||||||
|
|
||||||
private void CreatePlaceHolderInstance(RenderProfileElement renderElement, LayerEffectEntity entity)
|
private void CreatePlaceHolderInstance(RenderProfileElement renderElement, LayerEffectEntity entity)
|
||||||
{
|
{
|
||||||
PlaceholderLayerEffect effect = new PlaceholderLayerEffect(entity, PlaceholderFor.Value) {ProfileElement = renderElement, Descriptor = this};
|
PlaceholderLayerEffect effect = new PlaceholderLayerEffect(entity, PlaceholderFor) {ProfileElement = renderElement, Descriptor = this};
|
||||||
effect.Initialize();
|
effect.Initialize();
|
||||||
renderElement.ActivateLayerEffect(effect);
|
renderElement.ActivateLayerEffect(effect);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ namespace Artemis.Core.LayerEffects
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allows you to register one or more <see cref="LayerEffect{T}" />s usable by profile layers.
|
/// Allows you to register one or more <see cref="LayerEffect{T}" />s usable by profile layers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class LayerEffectProvider : PluginImplementation
|
public abstract class LayerEffectProvider : PluginFeature
|
||||||
{
|
{
|
||||||
private readonly List<LayerEffectDescriptor> _layerEffectDescriptors;
|
private readonly List<LayerEffectDescriptor> _layerEffectDescriptors;
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ namespace Artemis.Core.LayerEffects
|
|||||||
protected void RegisterLayerEffectDescriptor<T>(string displayName, string description, string icon) where T : BaseLayerEffect
|
protected void RegisterLayerEffectDescriptor<T>(string displayName, string description, string icon) where T : BaseLayerEffect
|
||||||
{
|
{
|
||||||
if (!IsEnabled)
|
if (!IsEnabled)
|
||||||
throw new ArtemisPluginException(PluginInfo, "Can only add a layer effect descriptor when the plugin is enabled");
|
throw new ArtemisPluginFeatureException(this, "Can only add a layer effect descriptor when the plugin is enabled");
|
||||||
|
|
||||||
LayerEffectDescriptor descriptor = new LayerEffectDescriptor(displayName, description, icon, typeof(T), this);
|
LayerEffectDescriptor descriptor = new LayerEffectDescriptor(displayName, description, icon, typeof(T), this);
|
||||||
_layerEffectDescriptors.Add(descriptor);
|
_layerEffectDescriptors.Add(descriptor);
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using Artemis.Storage.Entities.Profile;
|
||||||
using Artemis.Storage.Entities.Profile;
|
|
||||||
using SkiaSharp;
|
using SkiaSharp;
|
||||||
|
|
||||||
namespace Artemis.Core.LayerEffects.Placeholder
|
namespace Artemis.Core.LayerEffects.Placeholder
|
||||||
@ -9,7 +8,7 @@ namespace Artemis.Core.LayerEffects.Placeholder
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class PlaceholderLayerEffect : LayerEffect<PlaceholderProperties>
|
internal class PlaceholderLayerEffect : LayerEffect<PlaceholderProperties>
|
||||||
{
|
{
|
||||||
internal PlaceholderLayerEffect(LayerEffectEntity originalEntity, Guid placeholderFor)
|
internal PlaceholderLayerEffect(LayerEffectEntity originalEntity, string placeholderFor)
|
||||||
{
|
{
|
||||||
OriginalEntity = originalEntity;
|
OriginalEntity = originalEntity;
|
||||||
PlaceholderFor = placeholderFor;
|
PlaceholderFor = placeholderFor;
|
||||||
@ -21,8 +20,9 @@ namespace Artemis.Core.LayerEffects.Placeholder
|
|||||||
HasBeenRenamed = OriginalEntity.HasBeenRenamed;
|
HasBeenRenamed = OriginalEntity.HasBeenRenamed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string PlaceholderFor { get; }
|
||||||
|
|
||||||
internal LayerEffectEntity OriginalEntity { get; }
|
internal LayerEffectEntity OriginalEntity { get; }
|
||||||
public Guid PlaceholderFor { get; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void EnableLayerEffect()
|
public override void EnableLayerEffect()
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
using System;
|
namespace Artemis.Core.LayerEffects.Placeholder
|
||||||
|
|
||||||
namespace Artemis.Core.LayerEffects.Placeholder
|
|
||||||
{
|
{
|
||||||
internal static class PlaceholderLayerEffectDescriptor
|
internal static class PlaceholderLayerEffectDescriptor
|
||||||
{
|
{
|
||||||
public static LayerEffectDescriptor Create(Guid missingPluginGuid)
|
public static LayerEffectDescriptor Create(string missingProviderId)
|
||||||
{
|
{
|
||||||
LayerEffectDescriptor descriptor = new LayerEffectDescriptor("Missing effect", "This effect could not be loaded", "FileQuestion", null, Constants.EffectPlaceholderPlugin)
|
LayerEffectDescriptor descriptor = new LayerEffectDescriptor("Missing effect", "This effect could not be loaded", "FileQuestion", null, Constants.EffectPlaceholderPlugin)
|
||||||
{
|
{
|
||||||
PlaceholderFor = missingPluginGuid
|
PlaceholderFor = missingProviderId
|
||||||
};
|
};
|
||||||
|
|
||||||
return descriptor;
|
return descriptor;
|
||||||
|
|||||||
10
src/Artemis.Core/Plugins/Modules/IModuleViewModel.cs
Normal file
10
src/Artemis.Core/Plugins/Modules/IModuleViewModel.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace Artemis.Core.Modules
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The base class for any view model that belongs to a module
|
||||||
|
/// </summary>
|
||||||
|
public interface IModuleViewModel
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -42,13 +42,13 @@ namespace Artemis.Core.Modules
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual DataModelPropertyAttribute GetDataModelDescription()
|
public virtual DataModelPropertyAttribute GetDataModelDescription()
|
||||||
{
|
{
|
||||||
return new DataModelPropertyAttribute {Name = PluginInfo.Name, Description = PluginInfo.Description};
|
return new DataModelPropertyAttribute {Name = Plugin.Info.Name, Description = Plugin.Info.Description};
|
||||||
}
|
}
|
||||||
|
|
||||||
internal override void InternalEnable()
|
internal override void InternalEnable()
|
||||||
{
|
{
|
||||||
DataModel = Activator.CreateInstance<T>();
|
DataModel = Activator.CreateInstance<T>();
|
||||||
DataModel.Implementation = PluginInfo;
|
DataModel.Feature = this;
|
||||||
DataModel.DataModelDescription = GetDataModelDescription();
|
DataModel.DataModelDescription = GetDataModelDescription();
|
||||||
base.InternalEnable();
|
base.InternalEnable();
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ namespace Artemis.Core.Modules
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allows you to add support for new games/applications
|
/// Allows you to add support for new games/applications
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class Module : DataModelPluginImplementation
|
public abstract class Module : DataModelPluginFeature
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The modules display name that's shown in the menu
|
/// The modules display name that's shown in the menu
|
||||||
@ -236,7 +236,7 @@ namespace Artemis.Core.Modules
|
|||||||
if (Entity == null)
|
if (Entity == null)
|
||||||
Entity = new ModuleSettingsEntity();
|
Entity = new ModuleSettingsEntity();
|
||||||
|
|
||||||
Entity.PluginGuid = PluginInfo.Guid;
|
Entity.ModuleId = Id;
|
||||||
Entity.PriorityCategory = (int) PriorityCategory;
|
Entity.PriorityCategory = (int) PriorityCategory;
|
||||||
Entity.Priority = Priority;
|
Entity.Priority = Priority;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
namespace Artemis.Core.Modules
|
namespace Artemis.Core.Modules
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public class ModuleTab<T> : ModuleTab where T : ModuleViewModel
|
public class ModuleTab<T> : ModuleTab where T : IModuleViewModel
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ModuleTab{T}" /> class
|
/// Initializes a new instance of the <see cref="ModuleTab{T}" /> class
|
||||||
|
|||||||
@ -46,7 +46,7 @@ namespace Artemis.Core.Modules
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual DataModelPropertyAttribute GetDataModelDescription()
|
public virtual DataModelPropertyAttribute GetDataModelDescription()
|
||||||
{
|
{
|
||||||
return new DataModelPropertyAttribute {Name = PluginInfo.Name, Description = PluginInfo.Description};
|
return new DataModelPropertyAttribute {Name = Plugin.Info.Name, Description = Plugin.Info.Description};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -74,7 +74,7 @@ namespace Artemis.Core.Modules
|
|||||||
internal override void InternalEnable()
|
internal override void InternalEnable()
|
||||||
{
|
{
|
||||||
DataModel = Activator.CreateInstance<T>();
|
DataModel = Activator.CreateInstance<T>();
|
||||||
DataModel.Implementation = PluginInfo;
|
DataModel.Feature = this;
|
||||||
DataModel.DataModelDescription = GetDataModelDescription();
|
DataModel.DataModelDescription = GetDataModelDescription();
|
||||||
base.InternalEnable();
|
base.InternalEnable();
|
||||||
}
|
}
|
||||||
@ -184,7 +184,7 @@ namespace Artemis.Core.Modules
|
|||||||
internal async Task ChangeActiveProfileAnimated(Profile profile, ArtemisSurface surface)
|
internal async Task ChangeActiveProfileAnimated(Profile profile, ArtemisSurface surface)
|
||||||
{
|
{
|
||||||
if (profile != null && profile.Module != this)
|
if (profile != null && profile.Module != this)
|
||||||
throw new ArtemisCoreException($"Cannot activate a profile of module {profile.Module} on a module of plugin {PluginInfo}.");
|
throw new ArtemisCoreException($"Cannot activate a profile of module {profile.Module} on a module of plugin {this}.");
|
||||||
if (!IsActivated)
|
if (!IsActivated)
|
||||||
throw new ArtemisCoreException("Cannot activate a profile on a deactivated module");
|
throw new ArtemisCoreException("Cannot activate a profile on a deactivated module");
|
||||||
|
|
||||||
@ -206,7 +206,7 @@ namespace Artemis.Core.Modules
|
|||||||
internal void ChangeActiveProfile(Profile profile, ArtemisSurface surface)
|
internal void ChangeActiveProfile(Profile profile, ArtemisSurface surface)
|
||||||
{
|
{
|
||||||
if (profile != null && profile.Module != this)
|
if (profile != null && profile.Module != this)
|
||||||
throw new ArtemisCoreException($"Cannot activate a profile of module {profile.Module} on a module of plugin {PluginInfo}.");
|
throw new ArtemisCoreException($"Cannot activate a profile of module {profile.Module} on a module of plugin {this}.");
|
||||||
if (!IsActivated)
|
if (!IsActivated)
|
||||||
throw new ArtemisCoreException("Cannot activate a profile on a deactivated module");
|
throw new ArtemisCoreException("Cannot activate a profile on a deactivated module");
|
||||||
|
|
||||||
|
|||||||
@ -7,16 +7,15 @@ using System.Reflection;
|
|||||||
using Artemis.Storage.Entities.Plugins;
|
using Artemis.Storage.Entities.Plugins;
|
||||||
using McMaster.NETCore.Plugins;
|
using McMaster.NETCore.Plugins;
|
||||||
using Ninject;
|
using Ninject;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a plugin
|
/// Represents a plugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Plugin : PropertyChangedBase, IDisposable
|
public class Plugin : CorePropertyChanged, IDisposable
|
||||||
{
|
{
|
||||||
private readonly List<PluginImplementation> _implementations;
|
private readonly List<PluginFeature> _features;
|
||||||
|
|
||||||
private bool _isEnabled;
|
private bool _isEnabled;
|
||||||
|
|
||||||
@ -25,7 +24,7 @@ namespace Artemis.Core
|
|||||||
Info = info;
|
Info = info;
|
||||||
Directory = directory;
|
Directory = directory;
|
||||||
|
|
||||||
_implementations = new List<PluginImplementation>();
|
_features = new List<PluginFeature>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -46,7 +45,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a configuration dialog for this plugin that is accessible in the UI under Settings > Plugins
|
/// Gets or sets a configuration dialog for this plugin that is accessible in the UI under Settings > Plugins
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginConfigurationDialog? ConfigurationDialog { get; protected set; }
|
public IPluginConfigurationDialog? ConfigurationDialog { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates whether the user enabled the plugin or not
|
/// Indicates whether the user enabled the plugin or not
|
||||||
@ -58,19 +57,24 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a read-only collection of all implementations this plugin provides
|
/// Gets a read-only collection of all features this plugin provides
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ReadOnlyCollection<PluginImplementation> Implementations => _implementations.AsReadOnly();
|
public ReadOnlyCollection<PluginFeature> Features => _features.AsReadOnly();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The assembly the plugin code lives in
|
/// The assembly the plugin code lives in
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal Assembly? Assembly { get; set; }
|
public Assembly? Assembly { get; internal set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the plugin bootstrapper
|
||||||
|
/// </summary>
|
||||||
|
public IPluginBootstrapper? Bootstrapper { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The Ninject kernel of the plugin
|
/// The Ninject kernel of the plugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal IKernel? Kernel { get; set; }
|
public IKernel? Kernel { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The PluginLoader backing this plugin
|
/// The PluginLoader backing this plugin
|
||||||
@ -80,7 +84,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The entity representing the plugin
|
/// The entity representing the plugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal PluginEntity? Entity { get; set; }
|
internal PluginEntity Entity { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resolves the relative path provided in the <paramref name="path" /> parameter to an absolute path
|
/// Resolves the relative path provided in the <paramref name="path" /> parameter to an absolute path
|
||||||
@ -92,25 +96,15 @@ namespace Artemis.Core
|
|||||||
return path == null ? null : Path.Combine(Directory.FullName, path);
|
return path == null ? null : Path.Combine(Directory.FullName, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void ApplyToEntity()
|
/// <summary>
|
||||||
|
/// Looks up the instance of the feature of type <typeparamref name="T" />
|
||||||
|
/// <para>Note: This method only returns instances of enabled features</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of feature to find</typeparam>
|
||||||
|
/// <returns>If found, the instance of the feature</returns>
|
||||||
|
public T? GetFeature<T>() where T : PluginFeature
|
||||||
{
|
{
|
||||||
Entity.Id = Guid;
|
return _features.FirstOrDefault(i => i is T) as T;
|
||||||
Entity.IsEnabled = IsEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void AddImplementation(PluginImplementation implementation)
|
|
||||||
{
|
|
||||||
implementation.Plugin = this;
|
|
||||||
_implementations.Add(implementation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetEnabled(bool enable)
|
|
||||||
{
|
|
||||||
if (IsEnabled == enable)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!enable && Implementations.Any(e => e.IsEnabled))
|
|
||||||
throw new ArtemisCoreException("Cannot disable this plugin because it still has enabled implementations");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
@ -119,13 +113,118 @@ namespace Artemis.Core
|
|||||||
return Info.ToString();
|
return Info.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void ApplyToEntity()
|
||||||
|
{
|
||||||
|
Entity.Id = Guid;
|
||||||
|
Entity.IsEnabled = IsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void AddFeature(PluginFeature feature)
|
||||||
|
{
|
||||||
|
feature.Plugin = this;
|
||||||
|
_features.Add(feature);
|
||||||
|
|
||||||
|
OnFeatureAdded(new PluginFeatureEventArgs(feature));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void RemoveFeature(PluginFeature feature)
|
||||||
|
{
|
||||||
|
_features.Remove(feature);
|
||||||
|
feature.InternalDisable();
|
||||||
|
feature.Dispose();
|
||||||
|
|
||||||
|
OnFeatureRemoved(new PluginFeatureEventArgs(feature));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal void SetEnabled(bool enable)
|
||||||
|
{
|
||||||
|
if (IsEnabled == enable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!enable && Features.Any(e => e.IsEnabled))
|
||||||
|
throw new ArtemisCoreException("Cannot disable this plugin because it still has enabled features");
|
||||||
|
|
||||||
|
IsEnabled = enable;
|
||||||
|
|
||||||
|
if (enable)
|
||||||
|
{
|
||||||
|
Bootstrapper?.Enable(this);
|
||||||
|
OnEnabled();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Bootstrapper?.Disable(this);
|
||||||
|
OnDisabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
foreach (PluginImplementation pluginImplementation in Implementations)
|
foreach (PluginFeature feature in Features)
|
||||||
pluginImplementation.Dispose();
|
feature.Dispose();
|
||||||
|
|
||||||
Kernel?.Dispose();
|
Kernel?.Dispose();
|
||||||
PluginLoader?.Dispose();
|
PluginLoader?.Dispose();
|
||||||
|
|
||||||
|
_features.Clear();
|
||||||
|
SetEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Events
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when the plugin is enabled
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler? Enabled;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when the plugin is disabled
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler? Disabled;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when an feature is loaded and added to the plugin
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<PluginFeatureEventArgs>? FeatureAdded;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when an feature is disabled and removed from the plugin
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<PluginFeatureEventArgs>? FeatureRemoved;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the Enabled event
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnEnabled()
|
||||||
|
{
|
||||||
|
Enabled?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the Disabled event
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnDisabled()
|
||||||
|
{
|
||||||
|
Disabled?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the FeatureAdded event
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnFeatureAdded(PluginFeatureEventArgs e)
|
||||||
|
{
|
||||||
|
FeatureAdded?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the FeatureRemoved event
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnFeatureRemoved(PluginFeatureEventArgs e)
|
||||||
|
{
|
||||||
|
FeatureRemoved?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,24 +1,22 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Artemis.Storage.Entities.Plugins;
|
using Artemis.Storage.Entities.Plugins;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents an implementation of a certain type provided by a plugin
|
/// Represents an feature of a certain type provided by a plugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class PluginImplementation : PropertyChangedBase, IDisposable
|
public abstract class PluginFeature : CorePropertyChanged, IDisposable
|
||||||
{
|
{
|
||||||
private Exception? _loadException;
|
|
||||||
private bool _isEnabled;
|
private bool _isEnabled;
|
||||||
|
private Exception? _loadException;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin that provides this implementation
|
/// Gets the plugin that provides this feature
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Plugin? Plugin { get; internal set; }
|
public Plugin Plugin { get; internal set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets whether the plugin is enabled
|
/// Gets whether the plugin is enabled
|
||||||
@ -38,15 +36,20 @@ namespace Artemis.Core
|
|||||||
internal set => SetAndNotify(ref _loadException, value);
|
internal set => SetAndNotify(ref _loadException, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal PluginImplementationEntity? Entity { get; set; }
|
/// <summary>
|
||||||
|
/// Gets the identifier of this plugin feature
|
||||||
|
/// </summary>
|
||||||
|
public string Id => $"{GetType().FullName}-{Plugin.Guid.ToString().Substring(0, 8)}"; // Not as unique as a GUID but good enough and stays readable
|
||||||
|
|
||||||
|
internal PluginFeatureEntity Entity { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when the implementation is activated
|
/// Called when the feature is activated
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract void Enable();
|
public abstract void Enable();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when the implementation is deactivated or when Artemis shuts down
|
/// Called when the feature is deactivated or when Artemis shuts down
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract void Disable();
|
public abstract void Disable();
|
||||||
|
|
||||||
@ -56,12 +59,12 @@ namespace Artemis.Core
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (Plugin == null)
|
if (Plugin == null)
|
||||||
throw new ArtemisCoreException("Cannot enable a plugin implementation that is not associated with a plugin");
|
throw new ArtemisCoreException("Cannot enable a plugin feature that is not associated with a plugin");
|
||||||
|
|
||||||
lock (Plugin)
|
lock (Plugin)
|
||||||
{
|
{
|
||||||
if (!Plugin.IsEnabled)
|
if (!Plugin.IsEnabled)
|
||||||
throw new ArtemisCoreException("Cannot enable a plugin implementation of a disabled plugin");
|
throw new ArtemisCoreException("Cannot enable a plugin feature of a disabled plugin");
|
||||||
|
|
||||||
if (!enable)
|
if (!enable)
|
||||||
{
|
{
|
||||||
@ -89,19 +92,10 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
// Allow up to 15 seconds for plugins to activate.
|
// 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
|
// This means plugins that need more time should do their long running tasks in a background thread, which is intentional
|
||||||
ManualResetEvent wait = new ManualResetEvent(false);
|
// This would've been a perfect match for Thread.Abort but that didn't make it into .NET Core
|
||||||
Thread work = new Thread(() =>
|
Task enableTask = Task.Run(InternalEnable);
|
||||||
{
|
if (!enableTask.Wait(TimeSpan.FromSeconds(15)))
|
||||||
InternalEnable();
|
|
||||||
wait.Set();
|
|
||||||
});
|
|
||||||
work.Start();
|
|
||||||
wait.WaitOne(TimeSpan.FromSeconds(15));
|
|
||||||
if (work.IsAlive)
|
|
||||||
{
|
|
||||||
work.Abort();
|
|
||||||
throw new ArtemisPluginException(Plugin, "Plugin load timeout");
|
throw new ArtemisPluginException(Plugin, "Plugin load timeout");
|
||||||
}
|
|
||||||
|
|
||||||
LoadException = null;
|
LoadException = null;
|
||||||
OnEnabled();
|
OnEnabled();
|
||||||
@ -144,7 +138,7 @@ namespace Artemis.Core
|
|||||||
internal void CreateLockFile()
|
internal void CreateLockFile()
|
||||||
{
|
{
|
||||||
if (Plugin == null)
|
if (Plugin == null)
|
||||||
throw new ArtemisCoreException("Cannot lock a plugin implementation that is not associated with a plugin");
|
throw new ArtemisCoreException("Cannot lock a plugin feature that is not associated with a plugin");
|
||||||
|
|
||||||
File.Create(Plugin.ResolveRelativePath($"{GetType().FullName}.lock")).Close();
|
File.Create(Plugin.ResolveRelativePath($"{GetType().FullName}.lock")).Close();
|
||||||
}
|
}
|
||||||
@ -152,7 +146,7 @@ namespace Artemis.Core
|
|||||||
internal void DeleteLockFile()
|
internal void DeleteLockFile()
|
||||||
{
|
{
|
||||||
if (Plugin == null)
|
if (Plugin == null)
|
||||||
throw new ArtemisCoreException("Cannot lock a plugin implementation that is not associated with a plugin");
|
throw new ArtemisCoreException("Cannot lock a plugin feature that is not associated with a plugin");
|
||||||
|
|
||||||
if (GetLockFileCreated())
|
if (GetLockFileCreated())
|
||||||
File.Delete(Plugin.ResolveRelativePath($"{GetType().FullName}.lock"));
|
File.Delete(Plugin.ResolveRelativePath($"{GetType().FullName}.lock"));
|
||||||
@ -161,7 +155,7 @@ namespace Artemis.Core
|
|||||||
internal bool GetLockFileCreated()
|
internal bool GetLockFileCreated()
|
||||||
{
|
{
|
||||||
if (Plugin == null)
|
if (Plugin == null)
|
||||||
throw new ArtemisCoreException("Cannot lock a plugin implementation that is not associated with a plugin");
|
throw new ArtemisCoreException("Cannot lock a plugin feature that is not associated with a plugin");
|
||||||
|
|
||||||
return File.Exists(Plugin.ResolveRelativePath($"{GetType().FullName}.lock"));
|
return File.Exists(Plugin.ResolveRelativePath($"{GetType().FullName}.lock"));
|
||||||
}
|
}
|
||||||
@ -171,17 +165,17 @@ namespace Artemis.Core
|
|||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when the implementation is enabled
|
/// Occurs when the feature is enabled
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler? Enabled;
|
public event EventHandler? Enabled;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when the implementation is disabled
|
/// Occurs when the feature is disabled
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler? Disabled;
|
public event EventHandler? Disabled;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Triggers the PluginEnabled event
|
/// Triggers the Enabled event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void OnEnabled()
|
protected virtual void OnEnabled()
|
||||||
{
|
{
|
||||||
@ -189,7 +183,7 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Triggers the PluginDisabled event
|
/// Triggers the Disabled event
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void OnDisabled()
|
protected virtual void OnDisabled()
|
||||||
{
|
{
|
||||||
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
@ -8,7 +7,7 @@ namespace Artemis.Core
|
|||||||
/// Represents basic info about a plugin and contains a reference to the instance of said plugin
|
/// Represents basic info about a plugin and contains a reference to the instance of said plugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonObject(MemberSerialization.OptIn)]
|
[JsonObject(MemberSerialization.OptIn)]
|
||||||
public class PluginInfo : PropertyChangedBase
|
public class PluginInfo : CorePropertyChanged
|
||||||
{
|
{
|
||||||
private string _description;
|
private string _description;
|
||||||
private Guid _guid;
|
private Guid _guid;
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
using Artemis.Storage.Entities.Plugins;
|
using Artemis.Storage.Entities.Plugins;
|
||||||
using Artemis.Storage.Repositories.Interfaces;
|
using Artemis.Storage.Repositories.Interfaces;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
@ -10,17 +9,18 @@ namespace Artemis.Core
|
|||||||
/// Represents a setting tied to a plugin of type <typeparamref name="T" />
|
/// Represents a setting tied to a plugin of type <typeparamref name="T" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The value type of the setting</typeparam>
|
/// <typeparam name="T">The value type of the setting</typeparam>
|
||||||
public class PluginSetting<T> : PropertyChangedBase
|
public class PluginSetting<T> : CorePropertyChanged
|
||||||
{
|
{
|
||||||
|
// TODO: Why? Should have included that...
|
||||||
// ReSharper disable once NotAccessedField.Local
|
// ReSharper disable once NotAccessedField.Local
|
||||||
private readonly PluginInfo _pluginInfo;
|
private readonly Plugin _plugin;
|
||||||
private readonly IPluginRepository _pluginRepository;
|
private readonly IPluginRepository _pluginRepository;
|
||||||
private readonly PluginSettingEntity _pluginSettingEntity;
|
private readonly PluginSettingEntity _pluginSettingEntity;
|
||||||
private T _value;
|
private T _value;
|
||||||
|
|
||||||
internal PluginSetting(PluginInfo pluginInfo, IPluginRepository pluginRepository, PluginSettingEntity pluginSettingEntity)
|
internal PluginSetting(Plugin plugin, IPluginRepository pluginRepository, PluginSettingEntity pluginSettingEntity)
|
||||||
{
|
{
|
||||||
_pluginInfo = pluginInfo;
|
_plugin = plugin;
|
||||||
_pluginRepository = pluginRepository;
|
_pluginRepository = pluginRepository;
|
||||||
_pluginSettingEntity = pluginSettingEntity;
|
_pluginSettingEntity = pluginSettingEntity;
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
_value = value;
|
_value = value;
|
||||||
OnSettingChanged();
|
OnSettingChanged();
|
||||||
NotifyOfPropertyChange(nameof(Value));
|
OnPropertyChanged(nameof(Value));
|
||||||
|
|
||||||
if (AutoSave)
|
if (AutoSave)
|
||||||
Save();
|
Save();
|
||||||
|
|||||||
@ -14,17 +14,17 @@ namespace Artemis.Core
|
|||||||
private readonly IPluginRepository _pluginRepository;
|
private readonly IPluginRepository _pluginRepository;
|
||||||
private readonly Dictionary<string, object> _settingEntities;
|
private readonly Dictionary<string, object> _settingEntities;
|
||||||
|
|
||||||
internal PluginSettings(PluginInfo pluginInfo, IPluginRepository pluginRepository)
|
internal PluginSettings(Plugin plugin, IPluginRepository pluginRepository)
|
||||||
{
|
{
|
||||||
PluginInfo = pluginInfo;
|
Plugin = plugin;
|
||||||
_pluginRepository = pluginRepository;
|
_pluginRepository = pluginRepository;
|
||||||
_settingEntities = new Dictionary<string, object>();
|
_settingEntities = new Dictionary<string, object>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the info of the plugin this setting belongs to
|
/// Gets the plugin these settings belong to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginInfo PluginInfo { get; }
|
public Plugin Plugin { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the setting with the provided name. If the setting does not exist yet, it is created.
|
/// Gets the setting with the provided name. If the setting does not exist yet, it is created.
|
||||||
@ -41,15 +41,15 @@ namespace Artemis.Core
|
|||||||
if (_settingEntities.ContainsKey(name))
|
if (_settingEntities.ContainsKey(name))
|
||||||
return (PluginSetting<T>) _settingEntities[name];
|
return (PluginSetting<T>) _settingEntities[name];
|
||||||
// Try to find in database
|
// Try to find in database
|
||||||
PluginSettingEntity settingEntity = _pluginRepository.GetSettingByNameAndGuid(name, PluginInfo.Guid);
|
PluginSettingEntity settingEntity = _pluginRepository.GetSettingByNameAndGuid(name, Plugin.Guid);
|
||||||
// If not found, create a new one
|
// If not found, create a new one
|
||||||
if (settingEntity == null)
|
if (settingEntity == null)
|
||||||
{
|
{
|
||||||
settingEntity = new PluginSettingEntity {Name = name, PluginGuid = PluginInfo.Guid, Value = JsonConvert.SerializeObject(defaultValue)};
|
settingEntity = new PluginSettingEntity {Name = name, PluginGuid = Plugin.Guid, Value = JsonConvert.SerializeObject(defaultValue)};
|
||||||
_pluginRepository.AddSetting(settingEntity);
|
_pluginRepository.AddSetting(settingEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginSetting<T> pluginSetting = new PluginSetting<T>(PluginInfo, _pluginRepository, settingEntity);
|
PluginSetting<T> pluginSetting = new PluginSetting<T>(Plugin, _pluginRepository, settingEntity);
|
||||||
|
|
||||||
// This overrides null with the default value, I'm not sure if that's desirable because you
|
// This overrides null with the default value, I'm not sure if that's desirable because you
|
||||||
// might expect something to go null and you might not
|
// might expect something to go null and you might not
|
||||||
|
|||||||
@ -8,40 +8,41 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a registration for a timed plugin update
|
/// Represents a registration for a timed plugin update
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TimedUpdateRegistration
|
public class TimedUpdateRegistration : IDisposable
|
||||||
{
|
{
|
||||||
private DateTime _lastEvent;
|
private DateTime _lastEvent;
|
||||||
private Timer _timer;
|
private Timer _timer;
|
||||||
|
private bool _disposed;
|
||||||
|
|
||||||
internal TimedUpdateRegistration(PluginInfo pluginInfo, TimeSpan interval, Action<double> action)
|
internal TimedUpdateRegistration(PluginFeature feature, TimeSpan interval, Action<double> action)
|
||||||
{
|
{
|
||||||
PluginInfo = pluginInfo;
|
Feature = feature;
|
||||||
Interval = interval;
|
Interval = interval;
|
||||||
Action = action;
|
Action = action;
|
||||||
|
|
||||||
PluginInfo.Plugin.Enabled += InstanceOnEnabled;
|
Feature.Enabled += FeatureOnEnabled;
|
||||||
PluginInfo.Plugin.Disabled += InstanceOnDisabled;
|
Feature.Disabled += FeatureOnDisabled;
|
||||||
if (PluginInfo.Plugin.IsEnabled)
|
if (Feature.IsEnabled)
|
||||||
Start();
|
Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TimedUpdateRegistration(PluginInfo pluginInfo, TimeSpan interval, Func<double, Task> asyncAction)
|
internal TimedUpdateRegistration(PluginFeature feature, TimeSpan interval, Func<double, Task> asyncAction)
|
||||||
{
|
{
|
||||||
PluginInfo = pluginInfo;
|
Feature = feature;
|
||||||
Interval = interval;
|
Interval = interval;
|
||||||
AsyncAction = asyncAction;
|
AsyncAction = asyncAction;
|
||||||
|
|
||||||
PluginInfo.Plugin.Enabled += InstanceOnEnabled;
|
Feature.Enabled += FeatureOnEnabled;
|
||||||
PluginInfo.Plugin.Disabled += InstanceOnDisabled;
|
Feature.Disabled += FeatureOnDisabled;
|
||||||
if (PluginInfo.Plugin.IsEnabled)
|
if (Feature.IsEnabled)
|
||||||
Start();
|
Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin info of the plugin this registration is associated with
|
/// Gets the plugin feature this registration is associated with
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginInfo PluginInfo { get; }
|
public PluginFeature Feature { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the interval at which the update should occur
|
/// Gets the interval at which the update should occur
|
||||||
@ -64,10 +65,13 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Start()
|
public void Start()
|
||||||
{
|
{
|
||||||
|
if (_disposed)
|
||||||
|
throw new ObjectDisposedException("TimedUpdateRegistration");
|
||||||
|
|
||||||
lock (this)
|
lock (this)
|
||||||
{
|
{
|
||||||
if (!PluginInfo.Plugin.IsEnabled)
|
if (!Feature.IsEnabled)
|
||||||
throw new ArtemisPluginException("Cannot start a timed update for a disabled plugin");
|
throw new ArtemisPluginException("Cannot start a timed update for a disabled plugin feature");
|
||||||
|
|
||||||
if (_timer != null)
|
if (_timer != null)
|
||||||
return;
|
return;
|
||||||
@ -85,6 +89,9 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
|
if (_disposed)
|
||||||
|
throw new ObjectDisposedException("TimedUpdateRegistration");
|
||||||
|
|
||||||
lock (this)
|
lock (this)
|
||||||
{
|
{
|
||||||
if (_timer == null)
|
if (_timer == null)
|
||||||
@ -99,7 +106,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private void TimerOnElapsed(object sender, ElapsedEventArgs e)
|
private void TimerOnElapsed(object sender, ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
if (!PluginInfo.Plugin.IsEnabled)
|
if (!Feature.IsEnabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lock (this)
|
lock (this)
|
||||||
@ -108,7 +115,7 @@ namespace Artemis.Core
|
|||||||
_lastEvent = DateTime.Now;
|
_lastEvent = DateTime.Now;
|
||||||
|
|
||||||
// Modules don't always want to update, honor that
|
// Modules don't always want to update, honor that
|
||||||
if (PluginInfo.Plugin is Module module && !module.IsUpdateAllowed)
|
if (Feature is Module module && !module.IsUpdateAllowed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Action != null)
|
if (Action != null)
|
||||||
@ -121,14 +128,25 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InstanceOnEnabled(object sender, EventArgs e)
|
private void FeatureOnEnabled(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Start();
|
Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InstanceOnDisabled(object sender, EventArgs e)
|
private void FeatureOnDisabled(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
|
||||||
|
Feature.Enabled -= FeatureOnEnabled;
|
||||||
|
Feature.Disabled -= FeatureOnDisabled;
|
||||||
|
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ namespace Artemis.Core.Services
|
|||||||
IRgbService rgbService, ISurfaceService surfaceService, IProfileService profileService, IModuleService moduleService)
|
IRgbService rgbService, ISurfaceService surfaceService, IProfileService profileService, IModuleService moduleService)
|
||||||
{
|
{
|
||||||
Kernel = kernel;
|
Kernel = kernel;
|
||||||
Constants.CorePluginInfo.Kernel = kernel;
|
Constants.CorePlugin.Kernel = kernel;
|
||||||
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_pluginManagementService = pluginManagementService;
|
_pluginManagementService = pluginManagementService;
|
||||||
@ -133,8 +133,8 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
private void UpdatePluginCache()
|
private void UpdatePluginCache()
|
||||||
{
|
{
|
||||||
_modules = _pluginManagementService.GetPluginsOfType<Module>().Where(p => p.IsEnabled).ToList();
|
_modules = _pluginManagementService.GetFeaturesOfType<Module>().Where(p => p.IsEnabled).ToList();
|
||||||
_dataModelExpansions = _pluginManagementService.GetPluginsOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled).ToList();
|
_dataModelExpansions = _pluginManagementService.GetFeaturesOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ConfigureJsonConvert()
|
private void ConfigureJsonConvert()
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using Artemis.Core.DeviceProviders;
|
||||||
using RGB.NET.Core;
|
using RGB.NET.Core;
|
||||||
|
|
||||||
namespace Artemis.Core.Services
|
namespace Artemis.Core.Services
|
||||||
@ -33,69 +34,77 @@ namespace Artemis.Core.Services
|
|||||||
void UnloadPlugins();
|
void UnloadPlugins();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads the plugin defined in the provided <see cref="PluginInfo" />
|
/// Loads the plugin located in the provided <paramref name="directory" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pluginInfo">The plugin info defining the plugin to load</param>
|
/// <param name="directory">The directory where the plugin is located</param>
|
||||||
void LoadPlugin(DirectoryInfo pluginInfo);
|
Plugin LoadPlugin(DirectoryInfo directory);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unloads the plugin defined in the provided <see cref="PluginInfo" />
|
/// Enables the provided <paramref name="plugin" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pluginInfo">The plugin info defining the plugin to unload</param>
|
/// <param name="plugin">The plugin to enable</param>
|
||||||
void UnloadPlugin(PluginInfo pluginInfo);
|
void EnablePlugin(Plugin plugin, bool ignorePluginLock = false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables the provided plugin
|
/// Unloads the provided <paramref name="plugin" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pluginImplementation"></param>
|
/// <param name="plugin">The plugin to unload</param>
|
||||||
|
void UnloadPlugin(Plugin plugin);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disables the provided <paramref name="plugin" />
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="plugin">The plugin to disable</param>
|
||||||
|
void DisablePlugin(Plugin plugin);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enables the provided plugin feature
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pluginFeature"></param>
|
||||||
/// <param name="isAutoEnable">If true, fails if there is a lock file present</param>
|
/// <param name="isAutoEnable">If true, fails if there is a lock file present</param>
|
||||||
void EnablePluginImplementation(PluginImplementation pluginImplementation, bool isAutoEnable = false);
|
void EnablePluginFeature(PluginFeature pluginFeature, bool isAutoEnable = false);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Disables the provided plugin
|
/// Disables the provided plugin feature
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pluginImplementation"></param>
|
/// <param name="pluginFeature"></param>
|
||||||
void DisablePluginImplementation(PluginImplementation pluginImplementation);
|
void DisablePluginFeature(PluginFeature pluginFeature);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds the plugin info related to the plugin
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pluginImplementation">The plugin you want to find the plugin info for</param>
|
|
||||||
/// <returns>The plugins PluginInfo</returns>
|
|
||||||
PluginInfo GetPluginInfo(PluginImplementation pluginImplementation);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin info of all loaded plugins
|
/// Gets the plugin info of all loaded plugins
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A list containing all the plugin info</returns>
|
/// <returns>A list containing all the plugin info</returns>
|
||||||
List<PluginInfo> GetAllPluginInfo();
|
List<Plugin> GetAllPlugins();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds all enabled <see cref="PluginImplementation" /> instances of <typeparamref name="T" />
|
/// Finds all enabled <see cref="PluginFeature" /> instances of <typeparamref name="T" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Either <see cref="PluginImplementation" /> or a plugin type implementing <see cref="PluginImplementation" /></typeparam>
|
/// <typeparam name="T">
|
||||||
/// <returns>Returns a list of plugin instances of <typeparamref name="T" /></returns>
|
/// Either <see cref="PluginFeature" /> or a plugin type implementing
|
||||||
List<T> GetPluginsOfType<T>() where T : PluginImplementation;
|
/// <see cref="PluginFeature" />
|
||||||
|
/// </typeparam>
|
||||||
|
/// <returns>Returns a list of feature instances of <typeparamref name="T" /></returns>
|
||||||
|
List<T> GetFeaturesOfType<T>() where T : PluginFeature;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin that provided the specified assembly
|
/// Gets the plugin that provided the specified assembly
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="assembly"></param>
|
/// <param name="assembly"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
PluginImplementation GetPluginByAssembly(Assembly assembly);
|
Plugin GetPluginByAssembly(Assembly assembly);
|
||||||
|
|
||||||
|
/// <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();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin that defined the specified device
|
/// Gets the plugin that defined the specified device
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="device"></param>
|
/// <param name="device"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
PluginImplementation GetPluginByDevice(IRGBDevice device);
|
DeviceProvider GetDeviceProviderByDevice(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>
|
|
||||||
PluginImplementation GetCallingPlugin();
|
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
@ -134,6 +143,26 @@ namespace Artemis.Core.Services
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
event EventHandler<PluginEventArgs> PluginDisabled;
|
event EventHandler<PluginEventArgs> PluginDisabled;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a plugin feature is being enabled
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<PluginFeatureEventArgs> PluginFeatureEnabling;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a plugin feature has been enabled
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<PluginFeatureEventArgs> PluginFeatureEnabled;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a plugin feature could not be enabled
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<PluginFeatureEventArgs> PluginFeatureEnableFailed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when a plugin feature has been disabled
|
||||||
|
/// </summary>
|
||||||
|
public event EventHandler<PluginFeatureEventArgs> PluginFeatureDisabled;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -26,16 +26,129 @@ namespace Artemis.Core.Services
|
|||||||
_moduleRepository = moduleRepository;
|
_moduleRepository = moduleRepository;
|
||||||
_pluginManagementService = pluginManagementService;
|
_pluginManagementService = pluginManagementService;
|
||||||
_profileService = profileService;
|
_profileService = profileService;
|
||||||
_pluginManagementService.PluginEnabled += PluginManagementServiceOnPluginManagementEnabled;
|
_pluginManagementService.PluginFeatureEnabled += OnPluginFeatureEnabled;
|
||||||
|
|
||||||
Timer activationUpdateTimer = new Timer(2000);
|
Timer activationUpdateTimer = new Timer(2000);
|
||||||
activationUpdateTimer.Start();
|
activationUpdateTimer.Start();
|
||||||
activationUpdateTimer.Elapsed += ActivationUpdateTimerOnElapsed;
|
activationUpdateTimer.Elapsed += ActivationUpdateTimerOnElapsed;
|
||||||
|
|
||||||
foreach (Module module in _pluginManagementService.GetPluginsOfType<Module>())
|
foreach (Module module in _pluginManagementService.GetFeaturesOfType<Module>())
|
||||||
InitialiseOrApplyPriority(module);
|
InitialiseOrApplyPriority(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void ActivationUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
await UpdateModuleActivation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ActivateModule(Module module)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
module.Activate(false);
|
||||||
|
|
||||||
|
// If this is a profile module, activate the last active profile after module activation
|
||||||
|
if (module is ProfileModule profileModule)
|
||||||
|
await _profileService.ActivateLastProfileAnimated(profileModule);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Error(new ArtemisPluginFeatureException(
|
||||||
|
module, "Failed to activate module and last profile.", e), "Failed to activate module and last profile"
|
||||||
|
);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DeactivateModule(Module module)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// If this is a profile module, animate profile disable
|
||||||
|
// module.Deactivate would do the same but without animation
|
||||||
|
if (module.IsActivated && module is ProfileModule profileModule)
|
||||||
|
await profileModule.ChangeActiveProfileAnimated(null, null);
|
||||||
|
|
||||||
|
module.Deactivate(false);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Error(new ArtemisPluginFeatureException(
|
||||||
|
module, "Failed to deactivate module and last profile.", e), "Failed to deactivate module and last profile"
|
||||||
|
);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OverrideActivate(Module module)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (module.IsActivated)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If activating while it should be deactivated, its an override
|
||||||
|
bool shouldBeActivated = module.EvaluateActivationRequirements();
|
||||||
|
module.Activate(!shouldBeActivated);
|
||||||
|
|
||||||
|
// If this is a profile module, activate the last active profile after module activation
|
||||||
|
if (module is ProfileModule profileModule)
|
||||||
|
_profileService.ActivateLastProfile(profileModule);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Error(new ArtemisPluginFeatureException(
|
||||||
|
module, "Failed to activate module and last profile.", e), "Failed to activate module and last profile"
|
||||||
|
);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OverrideDeactivate(Module module, bool clearingOverride)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!module.IsActivated)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If deactivating while it should be activated, its an override
|
||||||
|
bool shouldBeActivated = module.EvaluateActivationRequirements();
|
||||||
|
// No need to deactivate if it is not in an overridden state
|
||||||
|
if (shouldBeActivated && !module.IsActivatedOverride && !clearingOverride)
|
||||||
|
return;
|
||||||
|
|
||||||
|
module.Deactivate(true);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Error(new ArtemisPluginFeatureException(
|
||||||
|
module, "Failed to deactivate module and last profile.", e), "Failed to deactivate module and last profile"
|
||||||
|
);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPluginFeatureEnabled(object? sender, PluginFeatureEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.PluginFeature is Module module)
|
||||||
|
InitialiseOrApplyPriority(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitialiseOrApplyPriority(Module module)
|
||||||
|
{
|
||||||
|
ModulePriorityCategory category = module.DefaultPriorityCategory;
|
||||||
|
int priority = 1;
|
||||||
|
|
||||||
|
module.Entity = _moduleRepository.GetByModuleId(module.Id);
|
||||||
|
if (module.Entity != null)
|
||||||
|
{
|
||||||
|
category = (ModulePriorityCategory) module.Entity.PriorityCategory;
|
||||||
|
priority = module.Entity.Priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateModulePriority(module, category, priority);
|
||||||
|
}
|
||||||
|
|
||||||
public Module ActiveModuleOverride { get; private set; }
|
public Module ActiveModuleOverride { get; private set; }
|
||||||
|
|
||||||
public async Task SetActiveModuleOverride(Module overrideModule)
|
public async Task SetActiveModuleOverride(Module overrideModule)
|
||||||
@ -53,10 +166,12 @@ namespace Artemis.Core.Services
|
|||||||
_logger.Information($"Setting active module override to {overrideModule.DisplayName}");
|
_logger.Information($"Setting active module override to {overrideModule.DisplayName}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
_logger.Information("Clearing active module override");
|
_logger.Information("Clearing active module override");
|
||||||
|
}
|
||||||
|
|
||||||
// Always deactivate all other modules whenever override is called
|
// Always deactivate all other modules whenever override is called
|
||||||
List<Module> modules = _pluginManagementService.GetPluginsOfType<Module>().ToList();
|
List<Module> modules = _pluginManagementService.GetFeaturesOfType<Module>().ToList();
|
||||||
foreach (Module module in modules.Where(m => m != overrideModule))
|
foreach (Module module in modules.Where(m => m != overrideModule))
|
||||||
OverrideDeactivate(module, overrideModule != null);
|
OverrideDeactivate(module, overrideModule != null);
|
||||||
|
|
||||||
@ -83,13 +198,8 @@ namespace Artemis.Core.Services
|
|||||||
// the principle is different for this service but not for the module
|
// the principle is different for this service but not for the module
|
||||||
bool shouldBeActivated = ActiveModuleOverride.EvaluateActivationRequirements();
|
bool shouldBeActivated = ActiveModuleOverride.EvaluateActivationRequirements();
|
||||||
if (shouldBeActivated && ActiveModuleOverride.IsActivatedOverride)
|
if (shouldBeActivated && ActiveModuleOverride.IsActivatedOverride)
|
||||||
{
|
|
||||||
ActiveModuleOverride.Reactivate(true, false);
|
ActiveModuleOverride.Reactivate(true, false);
|
||||||
}
|
else if (!shouldBeActivated && !ActiveModuleOverride.IsActivatedOverride) ActiveModuleOverride.Reactivate(false, true);
|
||||||
else if (!shouldBeActivated && !ActiveModuleOverride.IsActivatedOverride)
|
|
||||||
{
|
|
||||||
ActiveModuleOverride.Reactivate(false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -97,10 +207,9 @@ namespace Artemis.Core.Services
|
|||||||
Stopwatch stopwatch = new Stopwatch();
|
Stopwatch stopwatch = new Stopwatch();
|
||||||
stopwatch.Start();
|
stopwatch.Start();
|
||||||
|
|
||||||
List<Module> modules = _pluginManagementService.GetPluginsOfType<Module>().ToList();
|
List<Module> modules = _pluginManagementService.GetFeaturesOfType<Module>().ToList();
|
||||||
List<Task> tasks = new List<Task>();
|
List<Task> tasks = new List<Task>();
|
||||||
foreach (Module module in modules)
|
foreach (Module module in modules)
|
||||||
{
|
|
||||||
lock (module)
|
lock (module)
|
||||||
{
|
{
|
||||||
bool shouldBeActivated = module.EvaluateActivationRequirements() && module.IsEnabled;
|
bool shouldBeActivated = module.EvaluateActivationRequirements() && module.IsEnabled;
|
||||||
@ -109,7 +218,6 @@ namespace Artemis.Core.Services
|
|||||||
else if (!shouldBeActivated && module.IsActivated)
|
else if (!shouldBeActivated && module.IsActivated)
|
||||||
tasks.Add(DeactivateModule(module));
|
tasks.Add(DeactivateModule(module));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
await Task.WhenAll(tasks);
|
await Task.WhenAll(tasks);
|
||||||
|
|
||||||
@ -128,7 +236,12 @@ namespace Artemis.Core.Services
|
|||||||
if (module.PriorityCategory == category && module.Priority == priority)
|
if (module.PriorityCategory == category && module.Priority == priority)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
List<Module> modules = _pluginManagementService.GetPluginsOfType<Module>().Where(m => m.PriorityCategory == category).OrderBy(m => m.Priority).ToList();
|
List<Module> modules = _pluginManagementService
|
||||||
|
.GetFeaturesOfType<Module>()
|
||||||
|
.Where(m => m.PriorityCategory == category)
|
||||||
|
.OrderBy(m => m.Priority)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
if (modules.Contains(module))
|
if (modules.Contains(module))
|
||||||
modules.Remove(module);
|
modules.Remove(module);
|
||||||
|
|
||||||
@ -149,110 +262,5 @@ namespace Artemis.Core.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void ActivationUpdateTimerOnElapsed(object sender, ElapsedEventArgs e)
|
|
||||||
{
|
|
||||||
await UpdateModuleActivation();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ActivateModule(Module module)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
module.Activate(false);
|
|
||||||
|
|
||||||
// If this is a profile module, activate the last active profile after module activation
|
|
||||||
if (module is ProfileModule profileModule)
|
|
||||||
await _profileService.ActivateLastProfileAnimated(profileModule);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.Error(new ArtemisPluginException(module.PluginInfo, "Failed to activate module and last profile.", e), "Failed to activate module and last profile");
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DeactivateModule(Module module)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// If this is a profile module, animate profile disable
|
|
||||||
// module.Deactivate would do the same but without animation
|
|
||||||
if (module.IsActivated && module is ProfileModule profileModule)
|
|
||||||
await profileModule.ChangeActiveProfileAnimated(null, null);
|
|
||||||
|
|
||||||
module.Deactivate(false);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.Error(new ArtemisPluginException(module.PluginInfo, "Failed to deactivate module and last profile.", e), "Failed to deactivate module and last profile");
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OverrideActivate(Module module)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (module.IsActivated)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// If activating while it should be deactivated, its an override
|
|
||||||
bool shouldBeActivated = module.EvaluateActivationRequirements();
|
|
||||||
module.Activate(!shouldBeActivated);
|
|
||||||
|
|
||||||
// If this is a profile module, activate the last active profile after module activation
|
|
||||||
if (module is ProfileModule profileModule)
|
|
||||||
_profileService.ActivateLastProfile(profileModule);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.Error(new ArtemisPluginException(module.PluginInfo, "Failed to activate module and last profile.", e), "Failed to activate module and last profile");
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OverrideDeactivate(Module module, bool clearingOverride)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!module.IsActivated)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// If deactivating while it should be activated, its an override
|
|
||||||
bool shouldBeActivated = module.EvaluateActivationRequirements();
|
|
||||||
// No need to deactivate if it is not in an overridden state
|
|
||||||
if (shouldBeActivated && !module.IsActivatedOverride && !clearingOverride)
|
|
||||||
return;
|
|
||||||
|
|
||||||
module.Deactivate(true);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
_logger.Error(new ArtemisPluginException(module.PluginInfo, "Failed to deactivate module and last profile.", e), "Failed to deactivate module and last profile");
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PluginManagementServiceOnPluginManagementEnabled(object sender, PluginEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.PluginInfo.Plugin is Module module)
|
|
||||||
InitialiseOrApplyPriority(module);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitialiseOrApplyPriority(Module module)
|
|
||||||
{
|
|
||||||
ModulePriorityCategory category = module.DefaultPriorityCategory;
|
|
||||||
int priority = 1;
|
|
||||||
|
|
||||||
module.Entity = _moduleRepository.GetByPluginGuid(module.PluginInfo.Guid);
|
|
||||||
if (module.Entity != null)
|
|
||||||
{
|
|
||||||
category = (ModulePriorityCategory) module.Entity.PriorityCategory;
|
|
||||||
priority = module.Entity.Priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateModulePriority(module, category, priority);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,6 +41,21 @@ namespace Artemis.Core.Services
|
|||||||
Directory.CreateDirectory(Constants.DataFolder + "plugins");
|
Directory.CreateDirectory(Constants.DataFolder + "plugins");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CopyBuiltInPlugin(FileInfo zipFileInfo, ZipArchive zipArchive)
|
||||||
|
{
|
||||||
|
DirectoryInfo pluginDirectory = new DirectoryInfo(Path.Combine(Constants.DataFolder, "plugins", Path.GetFileNameWithoutExtension(zipFileInfo.Name)));
|
||||||
|
bool createLockFile = File.Exists(Path.Combine(pluginDirectory.FullName, "artemis.lock"));
|
||||||
|
|
||||||
|
// Remove the old directory if it exists
|
||||||
|
if (Directory.Exists(pluginDirectory.FullName))
|
||||||
|
pluginDirectory.DeleteRecursively();
|
||||||
|
Directory.CreateDirectory(pluginDirectory.FullName);
|
||||||
|
|
||||||
|
zipArchive.ExtractToDirectory(pluginDirectory.FullName, true);
|
||||||
|
if (createLockFile)
|
||||||
|
File.Create(Path.Combine(pluginDirectory.FullName, "artemis.lock")).Close();
|
||||||
|
}
|
||||||
|
|
||||||
public bool LoadingPlugins { get; private set; }
|
public bool LoadingPlugins { get; private set; }
|
||||||
|
|
||||||
#region Built in plugins
|
#region Built in plugins
|
||||||
@ -72,7 +87,9 @@ namespace Artemis.Core.Services
|
|||||||
// Find the matching plugin in the plugin folder
|
// Find the matching plugin in the plugin folder
|
||||||
DirectoryInfo? match = pluginDirectory.EnumerateDirectories().FirstOrDefault(d => d.Name == Path.GetFileNameWithoutExtension(zipFile.Name));
|
DirectoryInfo? match = pluginDirectory.EnumerateDirectories().FirstOrDefault(d => d.Name == Path.GetFileNameWithoutExtension(zipFile.Name));
|
||||||
if (match == null)
|
if (match == null)
|
||||||
|
{
|
||||||
CopyBuiltInPlugin(zipFile, archive);
|
CopyBuiltInPlugin(zipFile, archive);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string metadataFile = Path.Combine(match.FullName, "plugin.json");
|
string metadataFile = Path.Combine(match.FullName, "plugin.json");
|
||||||
@ -105,6 +122,48 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
public List<Plugin> GetAllPlugins()
|
||||||
|
{
|
||||||
|
return new List<Plugin>(_plugins);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<T> GetFeaturesOfType<T>() where T : PluginFeature
|
||||||
|
{
|
||||||
|
return _plugins.Where(p => p.IsEnabled).SelectMany(p => p.Features.Where(i => i.IsEnabled && i is T)).Cast<T>().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Plugin? GetPluginByAssembly(Assembly assembly)
|
||||||
|
{
|
||||||
|
return _plugins.FirstOrDefault(p => p.Assembly == assembly);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: move to a more appropriate service
|
||||||
|
public DeviceProvider GetDeviceProviderByDevice(IRGBDevice rgbDevice)
|
||||||
|
{
|
||||||
|
return GetFeaturesOfType<DeviceProvider>().First(d => d.RgbDeviceProvider.Devices != null && d.RgbDeviceProvider.Devices.Contains(rgbDevice));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Plugin? GetCallingPlugin()
|
||||||
|
{
|
||||||
|
StackTrace stackTrace = new StackTrace(); // get call stack
|
||||||
|
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
|
||||||
|
|
||||||
|
foreach (StackFrame stackFrame in stackFrames)
|
||||||
|
{
|
||||||
|
Assembly assembly = stackFrame.GetMethod().DeclaringType.Assembly;
|
||||||
|
Plugin plugin = GetPluginByAssembly(assembly);
|
||||||
|
if (plugin != null)
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
UnloadPlugins();
|
||||||
|
}
|
||||||
|
|
||||||
#region Plugins
|
#region Plugins
|
||||||
|
|
||||||
public void LoadPlugins(bool ignorePluginLock)
|
public void LoadPlugins(bool ignorePluginLock)
|
||||||
@ -125,7 +184,8 @@ namespace Artemis.Core.Services
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LoadPlugin(subDirectory);
|
Plugin plugin = LoadPlugin(subDirectory);
|
||||||
|
EnablePlugin(plugin, ignorePluginLock);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@ -133,22 +193,6 @@ namespace Artemis.Core.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activate plugins after they are all loaded
|
|
||||||
foreach (Plugin plugin in _plugins.Where(p => p.Entity.IsEnabled))
|
|
||||||
{
|
|
||||||
foreach (PluginImplementation pluginImplementation in plugin.Implementations.Where(i => i.Entity.IsEnabled))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
EnablePluginImplementation(pluginImplementation, !ignorePluginLock);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
// ignored, logged in EnablePlugin
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadingPlugins = false;
|
LoadingPlugins = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,29 +209,32 @@ namespace Artemis.Core.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadPlugin(DirectoryInfo pluginDirectory)
|
public Plugin LoadPlugin(DirectoryInfo directory)
|
||||||
{
|
{
|
||||||
lock (_plugins)
|
lock (_plugins)
|
||||||
{
|
{
|
||||||
_logger.Debug("Loading plugin from {directory}", pluginDirectory.FullName);
|
_logger.Debug("Loading plugin from {directory}", directory.FullName);
|
||||||
|
|
||||||
// Load the metadata
|
// Load the metadata
|
||||||
string metadataFile = Path.Combine(pluginDirectory.FullName, "plugin.json");
|
string metadataFile = Path.Combine(directory.FullName, "plugin.json");
|
||||||
if (!File.Exists(metadataFile))
|
if (!File.Exists(metadataFile))
|
||||||
_logger.Warning(new ArtemisPluginException("Couldn't find the plugins metadata file at " + metadataFile), "Plugin exception");
|
_logger.Warning(new ArtemisPluginException("Couldn't find the plugins metadata file at " + metadataFile), "Plugin exception");
|
||||||
|
|
||||||
// PluginInfo contains the ID which we need to move on
|
// PluginInfo contains the ID which we need to move on
|
||||||
PluginInfo pluginInfo = JsonConvert.DeserializeObject<PluginInfo>(File.ReadAllText(metadataFile));
|
PluginInfo pluginInfo = JsonConvert.DeserializeObject<PluginInfo>(File.ReadAllText(metadataFile));
|
||||||
|
|
||||||
|
if (pluginInfo.Guid == Constants.CorePluginInfo.Guid)
|
||||||
|
throw new ArtemisPluginException($"Plugin cannot use reserved GUID {pluginInfo.Guid}");
|
||||||
|
|
||||||
// Ensure the plugin is not already loaded
|
// Ensure the plugin is not already loaded
|
||||||
if (_plugins.Any(p => p.Guid == pluginInfo.Guid))
|
if (_plugins.Any(p => p.Guid == pluginInfo.Guid))
|
||||||
throw new ArtemisCoreException("Cannot load a plugin that is already loaded");
|
throw new ArtemisCoreException("Cannot load a plugin that is already loaded");
|
||||||
|
|
||||||
Plugin plugin = new Plugin(pluginInfo, pluginDirectory);
|
Plugin plugin = new Plugin(pluginInfo, directory);
|
||||||
OnPluginLoading(new PluginEventArgs(plugin));
|
OnPluginLoading(new PluginEventArgs(plugin));
|
||||||
|
|
||||||
// Load the entity and fall back on creating a new one
|
// Load the entity and fall back on creating a new one
|
||||||
plugin.Entity = _pluginRepository.GetPluginByGuid(pluginInfo.Guid) ?? new PluginEntity { Id = plugin.Guid, IsEnabled = true };
|
plugin.Entity = _pluginRepository.GetPluginByGuid(pluginInfo.Guid) ?? new PluginEntity {Id = plugin.Guid, IsEnabled = true};
|
||||||
|
|
||||||
// Locate the main assembly entry
|
// Locate the main assembly entry
|
||||||
string? mainFile = plugin.ResolveRelativePath(plugin.Info.Main);
|
string? mainFile = plugin.ResolveRelativePath(plugin.Info.Main);
|
||||||
@ -210,42 +257,81 @@ namespace Artemis.Core.Services
|
|||||||
throw new ArtemisPluginException(plugin, "Failed to load the plugins assembly", e);
|
throw new ArtemisPluginException(plugin, "Failed to load the plugins assembly", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the Plugin implementation from the main assembly and if there is only one, instantiate it
|
List<Type> bootstrappers = plugin.Assembly.GetTypes().Where(t => typeof(IPluginBootstrapper).IsAssignableFrom(t)).ToList();
|
||||||
List<Type> implementationTypes;
|
if (bootstrappers.Count > 1)
|
||||||
|
_logger.Warning($"{plugin} has more than one bootstrapper, only initializing {bootstrappers.First().FullName}");
|
||||||
|
if (bootstrappers.Any())
|
||||||
|
plugin.Bootstrapper = (IPluginBootstrapper?) Activator.CreateInstance(bootstrappers.First());
|
||||||
|
|
||||||
|
_plugins.Add(plugin);
|
||||||
|
|
||||||
|
OnPluginLoaded(new PluginEventArgs(plugin));
|
||||||
|
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EnablePlugin(Plugin plugin, bool ignorePluginLock)
|
||||||
|
{
|
||||||
|
if (plugin.Assembly == null)
|
||||||
|
throw new ArtemisPluginException(plugin, "Cannot enable a plugin that hasn't successfully been loaded");
|
||||||
|
|
||||||
|
// Create the Ninject child kernel and load the module
|
||||||
|
plugin.Kernel = new ChildKernel(_kernel);
|
||||||
|
plugin.Kernel.Bind<Plugin>().ToConstant(plugin);
|
||||||
|
plugin.Kernel.Load(new PluginModule(plugin.Info));
|
||||||
|
|
||||||
|
plugin.SetEnabled(true);
|
||||||
|
|
||||||
|
// Get the Plugin feature from the main assembly and if there is only one, instantiate it
|
||||||
|
List<Type> featureTypes;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
implementationTypes = plugin.Assembly.GetTypes().Where(t => typeof(PluginImplementation).IsAssignableFrom(t)).ToList();
|
featureTypes = plugin.Assembly.GetTypes().Where(t => typeof(PluginFeature).IsAssignableFrom(t)).ToList();
|
||||||
}
|
}
|
||||||
catch (ReflectionTypeLoadException e)
|
catch (ReflectionTypeLoadException e)
|
||||||
{
|
{
|
||||||
throw new ArtemisPluginException(plugin, "Failed to initialize the plugin assembly", new AggregateException(e.LoaderExceptions));
|
throw new ArtemisPluginException(plugin, "Failed to initialize the plugin assembly", new AggregateException(e.LoaderExceptions));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the Ninject child kernel and load the module
|
if (!featureTypes.Any())
|
||||||
plugin.Kernel = new ChildKernel(_kernel);
|
_logger.Warning("Plugin {plugin} contains no features", plugin);
|
||||||
plugin.Kernel.Load(new PluginModule(pluginInfo));
|
|
||||||
|
|
||||||
if (!implementationTypes.Any())
|
// Create instances of each feature and add them to the plugin
|
||||||
_logger.Warning("Plugin {plugin} contains no implementations", plugin);
|
|
||||||
|
|
||||||
// Create instances of each implementation and add them to the plugin
|
|
||||||
// Construction should be simple and not contain any logic so failure at this point means the entire plugin fails
|
// Construction should be simple and not contain any logic so failure at this point means the entire plugin fails
|
||||||
foreach (Type implementationType in implementationTypes)
|
foreach (Type featureType in featureTypes)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PluginImplementation instance = (PluginImplementation)plugin.Kernel.Get(implementationType);
|
// Include Plugin as a parameter for the PluginSettingsProvider
|
||||||
plugin.AddImplementation(instance);
|
IParameter[] parameters = {new Parameter("Plugin", plugin, false)};
|
||||||
|
PluginFeature instance = (PluginFeature) plugin.Kernel.Get(featureType, parameters);
|
||||||
|
plugin.AddFeature(instance);
|
||||||
|
|
||||||
|
// Load the enabled state and if not found, default to true
|
||||||
|
instance.Entity = plugin.Entity.Features.FirstOrDefault(i => i.Type == featureType.FullName) ??
|
||||||
|
new PluginFeatureEntity {IsEnabled = true, Type = featureType.FullName};
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
throw new ArtemisPluginException(plugin, "Failed to load instantiate implementation", e);
|
throw new ArtemisPluginException(plugin, "Failed to load instantiate feature", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_plugins.Add(plugin);
|
// Activate plugins after they are all loaded
|
||||||
OnPluginLoaded(new PluginEventArgs(plugin));
|
foreach (PluginFeature pluginFeature in plugin.Features.Where(i => i.Entity.IsEnabled))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
EnablePluginFeature(pluginFeature, !ignorePluginLock);
|
||||||
}
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// ignored, logged in EnablePluginFeature
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OnPluginEnabled(new PluginEventArgs(plugin));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UnloadPlugin(Plugin plugin)
|
public void UnloadPlugin(Plugin plugin)
|
||||||
@ -254,11 +340,11 @@ namespace Artemis.Core.Services
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
plugin.SetEnabled(false);
|
DisablePlugin(plugin);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// TODO: Log these
|
_logger.Warning(new ArtemisPluginException(plugin, "Exception during DisablePlugin call for UnloadPlugin", e), "Failed to unload plugin");
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -267,38 +353,59 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
plugin.Dispose();
|
plugin.Dispose();
|
||||||
_plugins.Remove(plugin);
|
_plugins.Remove(plugin);
|
||||||
|
|
||||||
OnPluginUnloaded(new PluginEventArgs(plugin));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DisablePlugin(Plugin plugin)
|
||||||
|
{
|
||||||
|
if (!plugin.IsEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (plugin.Features.Any())
|
||||||
|
{
|
||||||
|
PluginFeature feature = plugin.Features[0];
|
||||||
|
plugin.RemoveFeature(feature);
|
||||||
|
OnPluginFeatureDisabled(new PluginFeatureEventArgs(feature));
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.SetEnabled(false);
|
||||||
|
|
||||||
|
plugin.Kernel.Dispose();
|
||||||
|
plugin.Kernel = null;
|
||||||
|
|
||||||
|
OnPluginDisabled(new PluginEventArgs(plugin));
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Features
|
||||||
|
|
||||||
#region Implementations
|
public void EnablePluginFeature(PluginFeature pluginFeature, bool isAutoEnable = false)
|
||||||
|
|
||||||
public void EnablePluginImplementation(PluginImplementation pluginImplementation, bool isAutoEnable = false)
|
|
||||||
{
|
{
|
||||||
_logger.Debug("Enabling plugin implementation {implementation} - {plugin}", pluginImplementation, pluginImplementation.Plugin);
|
_logger.Debug("Enabling plugin feature {feature} - {plugin}", pluginFeature, pluginFeature.Plugin);
|
||||||
|
|
||||||
lock (_plugins)
|
lock (_plugins)
|
||||||
{
|
{
|
||||||
|
OnPluginFeatureEnabling(new PluginFeatureEventArgs(pluginFeature));
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// A device provider may be queued for disable on next restart, this undoes that
|
// A device provider may be queued for disable on next restart, this undoes that
|
||||||
if (pluginImplementation is DeviceProvider && pluginImplementation.IsEnabled && !pluginImplementation.PluginInfo.IsEnabled)
|
if (pluginFeature is DeviceProvider && pluginFeature.IsEnabled && !pluginFeature.Entity.IsEnabled)
|
||||||
{
|
{
|
||||||
pluginImplementation.PluginInfo.IsEnabled = true;
|
pluginFeature.Entity.IsEnabled = true;
|
||||||
pluginImplementation.PluginInfo.ApplyToEntity();
|
SavePlugin(pluginFeature.Plugin);
|
||||||
_pluginRepository.SavePlugin(pluginImplementation.PluginInfo.PluginEntity);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginImplementation.SetEnabled(true, isAutoEnable);
|
pluginFeature.SetEnabled(true, isAutoEnable);
|
||||||
|
pluginFeature.Entity.IsEnabled = true;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.Warning(new ArtemisPluginException(pluginImplementation.PluginInfo, "Exception during SetEnabled(true)", e), "Failed to enable plugin");
|
_logger.Warning(
|
||||||
|
new ArtemisPluginException(pluginFeature.Plugin, $"Exception during SetEnabled(true) on {pluginFeature}", e),
|
||||||
|
"Failed to enable plugin"
|
||||||
|
);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@ -306,108 +413,83 @@ 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
|
// 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
|
// not affect the user's settings
|
||||||
if (isAutoEnable)
|
if (isAutoEnable)
|
||||||
pluginImplementation.PluginInfo.IsEnabled = true;
|
pluginFeature.Entity.IsEnabled = true;
|
||||||
|
|
||||||
pluginImplementation.PluginInfo.ApplyToEntity();
|
SavePlugin(pluginFeature.Plugin);
|
||||||
_pluginRepository.SavePlugin(pluginImplementation.PluginInfo.PluginEntity);
|
|
||||||
|
|
||||||
if (pluginImplementation.PluginInfo.IsEnabled)
|
if (pluginFeature.IsEnabled)
|
||||||
_logger.Debug("Successfully enabled plugin {pluginInfo}", pluginImplementation.PluginInfo);
|
{
|
||||||
|
_logger.Debug("Successfully enabled plugin feature {feature} - {plugin}", pluginFeature, pluginFeature.Plugin);
|
||||||
|
OnPluginFeatureEnabled(new PluginFeatureEventArgs(pluginFeature));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OnPluginFeatureEnableFailed(new PluginFeatureEventArgs(pluginFeature));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OnPluginImplementationEnabled(new PluginImplementationEventArgs(pluginImplementation));
|
public void DisablePluginFeature(PluginFeature pluginFeature)
|
||||||
}
|
|
||||||
|
|
||||||
public void DisablePluginImplementation(PluginImplementation pluginImplementation)
|
|
||||||
{
|
{
|
||||||
lock (_plugins)
|
lock (_plugins)
|
||||||
{
|
{
|
||||||
_logger.Debug("Disabling plugin {pluginInfo}", pluginImplementation.PluginInfo);
|
try
|
||||||
|
{
|
||||||
|
_logger.Debug("Disabling plugin feature {feature} - {plugin}", pluginFeature, pluginFeature.Plugin);
|
||||||
|
|
||||||
// Device providers cannot be disabled at runtime simply queue a disable for next restart
|
// Device providers cannot be disabled at runtime simply queue a disable for next restart
|
||||||
if (pluginImplementation is DeviceProvider)
|
if (pluginFeature is DeviceProvider)
|
||||||
{
|
{
|
||||||
// Don't call SetEnabled(false) but simply update enabled state and save it
|
// Don't call SetEnabled(false) but simply update enabled state and save it
|
||||||
pluginImplementation.PluginInfo.IsEnabled = false;
|
pluginFeature.Entity.IsEnabled = false;
|
||||||
pluginImplementation.PluginInfo.ApplyToEntity();
|
SavePlugin(pluginFeature.Plugin);
|
||||||
_pluginRepository.SavePlugin(pluginImplementation.PluginInfo.PluginEntity);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginImplementation.SetEnabled(false);
|
pluginFeature.SetEnabled(false);
|
||||||
pluginImplementation.PluginInfo.ApplyToEntity();
|
|
||||||
_pluginRepository.SavePlugin(pluginImplementation.PluginInfo.PluginEntity);
|
|
||||||
|
|
||||||
_logger.Debug("Successfully disabled plugin {pluginInfo}", pluginImplementation.PluginInfo);
|
|
||||||
}
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
pluginFeature.Entity.IsEnabled = false;
|
||||||
|
SavePlugin(pluginFeature.Plugin);
|
||||||
|
|
||||||
OnPluginDisabled(new PluginEventArgs(pluginImplementation.PluginInfo));
|
if (!pluginFeature.IsEnabled)
|
||||||
|
{
|
||||||
|
_logger.Debug("Successfully disabled plugin feature {feature} - {plugin}", pluginFeature, pluginFeature.Plugin);
|
||||||
|
OnPluginFeatureDisabled(new PluginFeatureEventArgs(pluginFeature));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Storage
|
||||||
|
|
||||||
public PluginInfo GetPluginInfo(PluginImplementation pluginImplementation)
|
private void SavePlugin(Plugin plugin)
|
||||||
{
|
{
|
||||||
return _plugins.FirstOrDefault(p => p.Plugin == pluginImplementation);
|
foreach (PluginFeature pluginFeature in plugin.Features)
|
||||||
|
{
|
||||||
|
if (plugin.Entity.Features.All(i => i.Type != pluginFeature.GetType().FullName))
|
||||||
|
plugin.Entity.Features.Add(pluginFeature.Entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<PluginInfo> GetAllPluginInfo()
|
_pluginRepository.SavePlugin(plugin.Entity);
|
||||||
{
|
|
||||||
return new List<PluginInfo>(_plugins);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<T> GetPluginsOfType<T>() where T : PluginImplementation
|
private PluginFeatureEntity GetOrCreateFeatureEntity(PluginFeature feature)
|
||||||
{
|
{
|
||||||
return _plugins.Where(p => p.IsEnabled && p.Plugin is T).Select(p => (T) p.Plugin).ToList();
|
return feature.Plugin.Entity.Features.FirstOrDefault(i => i.Type == feature.GetType().FullName) ??
|
||||||
|
new PluginFeatureEntity {IsEnabled = true, Type = feature.GetType().FullName};
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginImplementation GetPluginByAssembly(Assembly assembly)
|
#endregion
|
||||||
{
|
|
||||||
return _plugins.FirstOrDefault(p => p.Assembly == assembly)?.Plugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginImplementation GetPluginByDevice(IRGBDevice rgbDevice)
|
|
||||||
{
|
|
||||||
return GetPluginsOfType<DeviceProvider>().First(d => d.RgbDeviceProvider.Devices != null && d.RgbDeviceProvider.Devices.Contains(rgbDevice));
|
|
||||||
}
|
|
||||||
|
|
||||||
public PluginImplementation GetCallingPlugin()
|
|
||||||
{
|
|
||||||
StackTrace stackTrace = new StackTrace(); // get call stack
|
|
||||||
StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
|
|
||||||
|
|
||||||
foreach (StackFrame stackFrame in stackFrames)
|
|
||||||
{
|
|
||||||
Assembly assembly = stackFrame.GetMethod().DeclaringType.Assembly;
|
|
||||||
PluginImplementation pluginImplementation = GetPluginByAssembly(assembly);
|
|
||||||
if (pluginImplementation != null)
|
|
||||||
return pluginImplementation;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
UnloadPlugins();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CopyBuiltInPlugin(FileInfo zipFileInfo, ZipArchive zipArchive)
|
|
||||||
{
|
|
||||||
DirectoryInfo pluginDirectory = new DirectoryInfo(Path.Combine(Constants.DataFolder, "plugins", Path.GetFileNameWithoutExtension(zipFileInfo.Name)));
|
|
||||||
bool createLockFile = File.Exists(Path.Combine(pluginDirectory.FullName, "artemis.lock"));
|
|
||||||
|
|
||||||
// Remove the old directory if it exists
|
|
||||||
if (Directory.Exists(pluginDirectory.FullName))
|
|
||||||
pluginDirectory.DeleteRecursively();
|
|
||||||
Directory.CreateDirectory(pluginDirectory.FullName);
|
|
||||||
|
|
||||||
zipArchive.ExtractToDirectory(pluginDirectory.FullName, true);
|
|
||||||
if (createLockFile)
|
|
||||||
File.Create(Path.Combine(pluginDirectory.FullName, "artemis.lock")).Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Events
|
#region Events
|
||||||
|
|
||||||
@ -419,8 +501,10 @@ namespace Artemis.Core.Services
|
|||||||
public event EventHandler<PluginEventArgs> PluginEnabled;
|
public event EventHandler<PluginEventArgs> PluginEnabled;
|
||||||
public event EventHandler<PluginEventArgs> PluginDisabled;
|
public event EventHandler<PluginEventArgs> PluginDisabled;
|
||||||
|
|
||||||
public event EventHandler<PluginImplementationEventArgs> PluginImplementationEnabled;
|
public event EventHandler<PluginFeatureEventArgs> PluginFeatureEnabling;
|
||||||
public event EventHandler<PluginImplementationEventArgs> PluginImplementationDisabled;
|
public event EventHandler<PluginFeatureEventArgs> PluginFeatureEnabled;
|
||||||
|
public event EventHandler<PluginFeatureEventArgs> PluginFeatureDisabled;
|
||||||
|
public event EventHandler<PluginFeatureEventArgs> PluginFeatureEnableFailed;
|
||||||
|
|
||||||
protected virtual void OnCopyingBuildInPlugins()
|
protected virtual void OnCopyingBuildInPlugins()
|
||||||
{
|
{
|
||||||
@ -457,14 +541,24 @@ namespace Artemis.Core.Services
|
|||||||
PluginDisabled?.Invoke(this, e);
|
PluginDisabled?.Invoke(this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnPluginImplementationDisabled(PluginImplementationEventArgs e)
|
protected virtual void OnPluginFeatureEnabling(PluginFeatureEventArgs e)
|
||||||
{
|
{
|
||||||
PluginImplementationDisabled?.Invoke(this, e);
|
PluginFeatureEnabling?.Invoke(this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnPluginImplementationEnabled(PluginImplementationEventArgs e)
|
protected virtual void OnPluginFeatureEnabled(PluginFeatureEventArgs e)
|
||||||
{
|
{
|
||||||
PluginImplementationEnabled?.Invoke(this, e);
|
PluginFeatureEnabled?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnPluginFeatureDisabled(PluginFeatureEventArgs e)
|
||||||
|
{
|
||||||
|
PluginFeatureDisabled?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnPluginFeatureEnableFailed(PluginFeatureEventArgs e)
|
||||||
|
{
|
||||||
|
PluginFeatureEnableFailed?.Invoke(this, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -12,14 +12,14 @@ namespace Artemis.Core.Services
|
|||||||
RegisterBuiltInConditionOperators();
|
RegisterBuiltInConditionOperators();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConditionOperatorRegistration RegisterConditionOperator(PluginInfo pluginInfo, BaseConditionOperator conditionOperator)
|
public ConditionOperatorRegistration RegisterConditionOperator(Plugin plugin, BaseConditionOperator conditionOperator)
|
||||||
{
|
{
|
||||||
if (pluginInfo == null)
|
if (plugin == null)
|
||||||
throw new ArgumentNullException(nameof(pluginInfo));
|
throw new ArgumentNullException(nameof(plugin));
|
||||||
if (conditionOperator == null)
|
if (conditionOperator == null)
|
||||||
throw new ArgumentNullException(nameof(conditionOperator));
|
throw new ArgumentNullException(nameof(conditionOperator));
|
||||||
|
|
||||||
conditionOperator.PluginInfo = pluginInfo;
|
conditionOperator.Plugin = plugin;
|
||||||
return ConditionOperatorStore.Add(conditionOperator);
|
return ConditionOperatorStore.Add(conditionOperator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,30 +43,30 @@ namespace Artemis.Core.Services
|
|||||||
private void RegisterBuiltInConditionOperators()
|
private void RegisterBuiltInConditionOperators()
|
||||||
{
|
{
|
||||||
// General usage for any type
|
// General usage for any type
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new EqualsConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new EqualsConditionOperator());
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new NotEqualConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new NotEqualConditionOperator());
|
||||||
|
|
||||||
// Numeric operators
|
// Numeric operators
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new NumberEqualsConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new NumberEqualsConditionOperator());
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new NumberNotEqualConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new NumberNotEqualConditionOperator());
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new LessThanConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new LessThanConditionOperator());
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new GreaterThanConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new GreaterThanConditionOperator());
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new LessThanOrEqualConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new LessThanOrEqualConditionOperator());
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new GreaterThanOrEqualConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new GreaterThanOrEqualConditionOperator());
|
||||||
|
|
||||||
// String operators
|
// String operators
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new StringEqualsConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new StringEqualsConditionOperator());
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new StringNotEqualConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new StringNotEqualConditionOperator());
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new StringContainsConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new StringContainsConditionOperator());
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new StringNotContainsConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new StringNotContainsConditionOperator());
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new StringStartsWithConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new StringStartsWithConditionOperator());
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new StringEndsWithConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new StringEndsWithConditionOperator());
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new StringMatchesRegexConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new StringMatchesRegexConditionOperator());
|
||||||
|
|
||||||
// Null checks, at the bottom
|
// Null checks, at the bottom
|
||||||
// TODO: Implement a priority mechanism
|
// TODO: Implement a priority mechanism
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new NullConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new NullConditionOperator());
|
||||||
RegisterConditionOperator(Constants.CorePluginInfo, new NotNullConditionOperator());
|
RegisterConditionOperator(Constants.CorePlugin, new NotNullConditionOperator());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -12,14 +12,14 @@ namespace Artemis.Core.Services
|
|||||||
RegisterBuiltInModifiers();
|
RegisterBuiltInModifiers();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataBindingModifierTypeRegistration RegisterModifierType(PluginInfo pluginInfo, BaseDataBindingModifierType dataBindingModifierType)
|
public DataBindingModifierTypeRegistration RegisterModifierType(Plugin plugin, BaseDataBindingModifierType dataBindingModifierType)
|
||||||
{
|
{
|
||||||
if (pluginInfo == null)
|
if (plugin == null)
|
||||||
throw new ArgumentNullException(nameof(pluginInfo));
|
throw new ArgumentNullException(nameof(plugin));
|
||||||
if (dataBindingModifierType == null)
|
if (dataBindingModifierType == null)
|
||||||
throw new ArgumentNullException(nameof(dataBindingModifierType));
|
throw new ArgumentNullException(nameof(dataBindingModifierType));
|
||||||
|
|
||||||
dataBindingModifierType.PluginInfo = pluginInfo;
|
dataBindingModifierType.Plugin = plugin;
|
||||||
return DataBindingModifierTypeStore.Add(dataBindingModifierType);
|
return DataBindingModifierTypeStore.Add(dataBindingModifierType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,41 +43,41 @@ namespace Artemis.Core.Services
|
|||||||
private void RegisterBuiltInModifiers()
|
private void RegisterBuiltInModifiers()
|
||||||
{
|
{
|
||||||
// Numbers - General
|
// Numbers - General
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new SumModifierType());
|
RegisterModifierType(Constants.CorePlugin, new SumModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new SubtractModifierType());
|
RegisterModifierType(Constants.CorePlugin, new SubtractModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new MultiplicationModifierType());
|
RegisterModifierType(Constants.CorePlugin, new MultiplicationModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new DivideModifierType());
|
RegisterModifierType(Constants.CorePlugin, new DivideModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new PercentageOfModifierType());
|
RegisterModifierType(Constants.CorePlugin, new PercentageOfModifierType());
|
||||||
|
|
||||||
// Numbers - Advanced
|
// Numbers - Advanced
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new MaxModifierType());
|
RegisterModifierType(Constants.CorePlugin, new MaxModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new MinModifierType());
|
RegisterModifierType(Constants.CorePlugin, new MinModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new ModuloModifierType());
|
RegisterModifierType(Constants.CorePlugin, new ModuloModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new AbsoluteModifierType());
|
RegisterModifierType(Constants.CorePlugin, new AbsoluteModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new PowerModifierType());
|
RegisterModifierType(Constants.CorePlugin, new PowerModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new SquareRootModifierType());
|
RegisterModifierType(Constants.CorePlugin, new SquareRootModifierType());
|
||||||
|
|
||||||
// Numbers - Rounding
|
// Numbers - Rounding
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new FloorModifierType());
|
RegisterModifierType(Constants.CorePlugin, new FloorModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new RoundModifierType());
|
RegisterModifierType(Constants.CorePlugin, new RoundModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new CeilingModifierType());
|
RegisterModifierType(Constants.CorePlugin, new CeilingModifierType());
|
||||||
|
|
||||||
// Numbers - Trigonometric
|
// Numbers - Trigonometric
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new SineModifierType());
|
RegisterModifierType(Constants.CorePlugin, new SineModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new CosineModifierType());
|
RegisterModifierType(Constants.CorePlugin, new CosineModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new TangentModifierType());
|
RegisterModifierType(Constants.CorePlugin, new TangentModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new CotangentModifierType());
|
RegisterModifierType(Constants.CorePlugin, new CotangentModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new SecantModifierType());
|
RegisterModifierType(Constants.CorePlugin, new SecantModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new CosecantModifierType());
|
RegisterModifierType(Constants.CorePlugin, new CosecantModifierType());
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new SKColorSumModifierType());
|
RegisterModifierType(Constants.CorePlugin, new SKColorSumModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new SKColorSaturateModifierType());
|
RegisterModifierType(Constants.CorePlugin, new SKColorSaturateModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new SKColorDesaturateModifierType());
|
RegisterModifierType(Constants.CorePlugin, new SKColorDesaturateModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new SKColorBrightenModifierType());
|
RegisterModifierType(Constants.CorePlugin, new SKColorBrightenModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new SKColorDarkenModifierType());
|
RegisterModifierType(Constants.CorePlugin, new SKColorDarkenModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new SKColorRotateHueModifierType());
|
RegisterModifierType(Constants.CorePlugin, new SKColorRotateHueModifierType());
|
||||||
RegisterModifierType(Constants.CorePluginInfo, new SKColorInvertModifierType());
|
RegisterModifierType(Constants.CorePlugin, new SKColorInvertModifierType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11,15 +11,16 @@ namespace Artemis.Core.Services
|
|||||||
public DataModelService(IPluginManagementService pluginManagementService)
|
public DataModelService(IPluginManagementService pluginManagementService)
|
||||||
{
|
{
|
||||||
// Add data models of already loaded plugins
|
// Add data models of already loaded plugins
|
||||||
foreach (Module module in pluginManagementService.GetPluginsOfType<Module>().Where(p => p.IsEnabled))
|
foreach (Module module in pluginManagementService.GetFeaturesOfType<Module>().Where(p => p.IsEnabled))
|
||||||
AddModuleDataModel(module);
|
AddModuleDataModel(module);
|
||||||
foreach (BaseDataModelExpansion dataModelExpansion in pluginManagementService.GetPluginsOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled))
|
foreach (BaseDataModelExpansion dataModelExpansion in pluginManagementService.GetFeaturesOfType<BaseDataModelExpansion>().Where(p => p.IsEnabled))
|
||||||
AddDataModelExpansionDataModel(dataModelExpansion);
|
AddDataModelExpansionDataModel(dataModelExpansion);
|
||||||
|
|
||||||
// Add data models of new plugins when they get enabled
|
// Add data models of new plugins when they get enabled
|
||||||
pluginManagementService.PluginEnabled += PluginServiceOnPluginEnabled;
|
pluginManagementService.PluginFeatureEnabled += OnPluginFeatureEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public DataModelRegistration RegisterDataModel(DataModel dataModel)
|
public DataModelRegistration RegisterDataModel(DataModel dataModel)
|
||||||
{
|
{
|
||||||
if (dataModel == null)
|
if (dataModel == null)
|
||||||
@ -44,21 +45,16 @@ namespace Artemis.Core.Services
|
|||||||
return (T) DataModelStore.GetAll().FirstOrDefault(d => d.DataModel is T)?.DataModel;
|
return (T) DataModelStore.GetAll().FirstOrDefault(d => d.DataModel is T)?.DataModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataModel GetPluginDataModel(PluginImplementation pluginImplementation)
|
public DataModel? GetPluginDataModel(PluginFeature pluginFeature)
|
||||||
{
|
{
|
||||||
return DataModelStore.Get(pluginImplementation.PluginInfo.Guid)?.DataModel;
|
return DataModelStore.Get(pluginFeature.Id)?.DataModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataModel GetPluginDataModel(Guid pluginGuid)
|
private void OnPluginFeatureEnabled(object? sender, PluginFeatureEventArgs e)
|
||||||
{
|
{
|
||||||
return DataModelStore.Get(pluginGuid)?.DataModel;
|
if (e.PluginFeature is Module module)
|
||||||
}
|
|
||||||
|
|
||||||
private void PluginServiceOnPluginEnabled(object sender, PluginEventArgs e)
|
|
||||||
{
|
|
||||||
if (e.PluginInfo.Plugin is Module module)
|
|
||||||
AddModuleDataModel(module);
|
AddModuleDataModel(module);
|
||||||
else if (e.PluginInfo.Plugin is BaseDataModelExpansion dataModelExpansion)
|
else if (e.PluginFeature is BaseDataModelExpansion dataModelExpansion)
|
||||||
AddDataModelExpansionDataModel(dataModelExpansion);
|
AddDataModelExpansionDataModel(dataModelExpansion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +64,7 @@ namespace Artemis.Core.Services
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (module.InternalDataModel.DataModelDescription == null)
|
if (module.InternalDataModel.DataModelDescription == null)
|
||||||
throw new ArtemisPluginException(module.PluginInfo, "Module overrides GetDataModelDescription but returned null");
|
throw new ArtemisPluginFeatureException(module, "Module overrides GetDataModelDescription but returned null");
|
||||||
|
|
||||||
module.InternalDataModel.IsExpansion = module.InternalExpandsMainDataModel;
|
module.InternalDataModel.IsExpansion = module.InternalExpandsMainDataModel;
|
||||||
RegisterDataModel(module.InternalDataModel);
|
RegisterDataModel(module.InternalDataModel);
|
||||||
@ -77,7 +73,7 @@ namespace Artemis.Core.Services
|
|||||||
private void AddDataModelExpansionDataModel(BaseDataModelExpansion dataModelExpansion)
|
private void AddDataModelExpansionDataModel(BaseDataModelExpansion dataModelExpansion)
|
||||||
{
|
{
|
||||||
if (dataModelExpansion.InternalDataModel.DataModelDescription == null)
|
if (dataModelExpansion.InternalDataModel.DataModelDescription == null)
|
||||||
throw new ArtemisPluginException(dataModelExpansion.PluginInfo, "Data model expansion overrides GetDataModelDescription but returned null");
|
throw new ArtemisPluginFeatureException(dataModelExpansion, "Data model expansion overrides GetDataModelDescription but returned null");
|
||||||
|
|
||||||
dataModelExpansion.InternalDataModel.IsExpansion = true;
|
dataModelExpansion.InternalDataModel.IsExpansion = true;
|
||||||
RegisterDataModel(dataModelExpansion.InternalDataModel);
|
RegisterDataModel(dataModelExpansion.InternalDataModel);
|
||||||
|
|||||||
@ -12,9 +12,9 @@ namespace Artemis.Core.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers a new condition operator for use in layer conditions
|
/// Registers a new condition operator for use in layer conditions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pluginInfo">The PluginInfo of the plugin this condition operator belongs to</param>
|
/// <param name="plugin">The plugin this condition operator belongs to</param>
|
||||||
/// <param name="conditionOperator">The condition operator to register</param>
|
/// <param name="conditionOperator">The condition operator to register</param>
|
||||||
ConditionOperatorRegistration RegisterConditionOperator([NotNull] PluginInfo pluginInfo, [NotNull] BaseConditionOperator conditionOperator);
|
ConditionOperatorRegistration RegisterConditionOperator([NotNull] Plugin plugin, [NotNull] BaseConditionOperator conditionOperator);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes a condition operator so it is no longer available for use in layer conditions
|
/// Removes a condition operator so it is no longer available for use in layer conditions
|
||||||
|
|||||||
@ -12,9 +12,9 @@ namespace Artemis.Core.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers a new modifier type for use in data bindings
|
/// Registers a new modifier type for use in data bindings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pluginInfo">The PluginInfo of the plugin this modifier type belongs to</param>
|
/// <param name="plugin">The plugin this modifier type belongs to</param>
|
||||||
/// <param name="dataBindingModifierType">The modifier type to register</param>
|
/// <param name="dataBindingModifierType">The modifier type to register</param>
|
||||||
DataBindingModifierTypeRegistration RegisterModifierType([NotNull] PluginInfo pluginInfo, [NotNull] BaseDataBindingModifierType dataBindingModifierType);
|
DataBindingModifierTypeRegistration RegisterModifierType([NotNull] Plugin plugin, [NotNull] BaseDataBindingModifierType dataBindingModifierType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes a modifier type so it is no longer available for use in data bindings
|
/// Removes a modifier type so it is no longer available for use in data bindings
|
||||||
|
|||||||
@ -34,13 +34,7 @@ namespace Artemis.Core.Services
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// If found, returns the data model of the provided plugin
|
/// If found, returns the data model of the provided plugin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pluginImplementation">The plugin to find the data model of</param>
|
/// <param name="pluginFeature">The plugin to find the data model of</param>
|
||||||
DataModel GetPluginDataModel(PluginImplementation pluginImplementation);
|
DataModel? GetPluginDataModel(PluginFeature pluginFeature);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// If found, returns the data model of the provided plugin GUID
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pluginGuid">The GUID of the plugin to find the data model of</param>
|
|
||||||
DataModel GetPluginDataModel(Guid pluginGuid);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -38,11 +38,11 @@ namespace Artemis.Core.Services
|
|||||||
{
|
{
|
||||||
PluginSetting<LayerBrushReference> defaultReference = _settingsService.GetSetting("ProfileEditor.DefaultLayerBrushDescriptor", new LayerBrushReference
|
PluginSetting<LayerBrushReference> defaultReference = _settingsService.GetSetting("ProfileEditor.DefaultLayerBrushDescriptor", new LayerBrushReference
|
||||||
{
|
{
|
||||||
BrushPluginGuid = Guid.Parse("92a9d6ba-6f7a-4937-94d5-c1d715b4141a"),
|
LayerBrushProviderId = "Artemis.Plugins.LayerBrushes.Color.ColorBrushProvider-92a9d6ba",
|
||||||
BrushType = "ColorBrush"
|
BrushType = "ColorBrush"
|
||||||
});
|
});
|
||||||
|
|
||||||
return LayerBrushStore.Get(defaultReference.Value.BrushPluginGuid, defaultReference.Value.BrushType)?.LayerBrushDescriptor;
|
return LayerBrushStore.Get(defaultReference.Value.LayerBrushProviderId, defaultReference.Value.BrushType)?.LayerBrushDescriptor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9,7 +9,7 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
internal SettingsService(IPluginRepository pluginRepository)
|
internal SettingsService(IPluginRepository pluginRepository)
|
||||||
{
|
{
|
||||||
_pluginSettings = new PluginSettings(Constants.CorePluginInfo, pluginRepository);
|
_pluginSettings = new PluginSettings(Constants.CorePlugin, pluginRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PluginSetting<T> GetSetting<T>(string name, T defaultValue = default)
|
public PluginSetting<T> GetSetting<T>(string name, T defaultValue = default)
|
||||||
|
|||||||
@ -38,13 +38,13 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
public List<ProfileDescriptor> GetProfileDescriptors(ProfileModule module)
|
public List<ProfileDescriptor> GetProfileDescriptors(ProfileModule module)
|
||||||
{
|
{
|
||||||
List<ProfileEntity> profileEntities = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid);
|
List<ProfileEntity> profileEntities = _profileRepository.GetByModuleId(module.Id);
|
||||||
return profileEntities.Select(e => new ProfileDescriptor(module, e)).ToList();
|
return profileEntities.Select(e => new ProfileDescriptor(module, e)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProfileDescriptor CreateProfileDescriptor(ProfileModule module, string name)
|
public ProfileDescriptor CreateProfileDescriptor(ProfileModule module, string name)
|
||||||
{
|
{
|
||||||
ProfileEntity profileEntity = new ProfileEntity {Id = Guid.NewGuid(), Name = name, PluginGuid = module.PluginInfo.Guid};
|
ProfileEntity profileEntity = new ProfileEntity {Id = Guid.NewGuid(), Name = name, ModuleId = module.Id};
|
||||||
_profileRepository.Add(profileEntity);
|
_profileRepository.Add(profileEntity);
|
||||||
|
|
||||||
return new ProfileDescriptor(module, profileEntity);
|
return new ProfileDescriptor(module, profileEntity);
|
||||||
@ -258,7 +258,7 @@ namespace Artemis.Core.Services
|
|||||||
|
|
||||||
public ProfileDescriptor GetLastActiveProfile(ProfileModule module)
|
public ProfileDescriptor GetLastActiveProfile(ProfileModule module)
|
||||||
{
|
{
|
||||||
List<ProfileEntity> moduleProfiles = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid);
|
List<ProfileEntity> moduleProfiles = _profileRepository.GetByModuleId(module.Id);
|
||||||
if (!moduleProfiles.Any())
|
if (!moduleProfiles.Any())
|
||||||
return CreateProfileDescriptor(module, "Default");
|
return CreateProfileDescriptor(module, "Default");
|
||||||
|
|
||||||
@ -271,7 +271,7 @@ namespace Artemis.Core.Services
|
|||||||
if (module.ActiveProfile == null)
|
if (module.ActiveProfile == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
List<ProfileEntity> profileEntities = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid);
|
List<ProfileEntity> profileEntities = _profileRepository.GetByModuleId(module.Id);
|
||||||
foreach (ProfileEntity profileEntity in profileEntities)
|
foreach (ProfileEntity profileEntity in profileEntities)
|
||||||
{
|
{
|
||||||
profileEntity.IsActive = module.ActiveProfile.EntityId == profileEntity.Id;
|
profileEntity.IsActive = module.ActiveProfile.EntityId == profileEntity.Id;
|
||||||
@ -285,7 +285,7 @@ namespace Artemis.Core.Services
|
|||||||
/// <param name="surface"></param>
|
/// <param name="surface"></param>
|
||||||
private void ActiveProfilesPopulateLeds(ArtemisSurface surface)
|
private void ActiveProfilesPopulateLeds(ArtemisSurface surface)
|
||||||
{
|
{
|
||||||
List<ProfileModule> profileModules = _pluginManagementService.GetPluginsOfType<ProfileModule>();
|
List<ProfileModule> profileModules = _pluginManagementService.GetFeaturesOfType<ProfileModule>();
|
||||||
foreach (ProfileModule profileModule in profileModules.Where(p => p.ActiveProfile != null).ToList())
|
foreach (ProfileModule profileModule in profileModules.Where(p => p.ActiveProfile != null).ToList())
|
||||||
profileModule.ActiveProfile.PopulateLeds(surface);
|
profileModule.ActiveProfile.PopulateLeds(surface);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,8 +44,8 @@ namespace Artemis.Core.Services
|
|||||||
// Add all current devices
|
// Add all current devices
|
||||||
foreach (IRGBDevice rgbDevice in _rgbService.LoadedDevices)
|
foreach (IRGBDevice rgbDevice in _rgbService.LoadedDevices)
|
||||||
{
|
{
|
||||||
PluginImplementation pluginImplementation = _pluginManagementService.GetPluginByDevice(rgbDevice);
|
PluginFeature pluginFeature = _pluginManagementService.GetDeviceProviderByDevice(rgbDevice);
|
||||||
configuration.Devices.Add(new ArtemisDevice(rgbDevice, pluginImplementation, configuration));
|
configuration.Devices.Add(new ArtemisDevice(rgbDevice, pluginFeature, configuration));
|
||||||
}
|
}
|
||||||
|
|
||||||
lock (_surfaceConfigurations)
|
lock (_surfaceConfigurations)
|
||||||
@ -136,8 +136,8 @@ namespace Artemis.Core.Services
|
|||||||
IRGBDevice device = _rgbService.Surface.Devices.FirstOrDefault(d => d.GetDeviceIdentifier() == position.DeviceIdentifier);
|
IRGBDevice device = _rgbService.Surface.Devices.FirstOrDefault(d => d.GetDeviceIdentifier() == position.DeviceIdentifier);
|
||||||
if (device != null)
|
if (device != null)
|
||||||
{
|
{
|
||||||
PluginImplementation pluginImplementation = _pluginManagementService.GetPluginByDevice(device);
|
PluginFeature pluginFeature = _pluginManagementService.GetDeviceProviderByDevice(device);
|
||||||
surfaceConfiguration.Devices.Add(new ArtemisDevice(device, pluginImplementation, surfaceConfiguration, position));
|
surfaceConfiguration.Devices.Add(new ArtemisDevice(device, pluginFeature, surfaceConfiguration, position));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,8 +178,8 @@ namespace Artemis.Core.Services
|
|||||||
DeviceEntity existingDeviceConfig = surface.SurfaceEntity.DeviceEntities.FirstOrDefault(d => d.DeviceIdentifier == deviceIdentifier);
|
DeviceEntity existingDeviceConfig = surface.SurfaceEntity.DeviceEntities.FirstOrDefault(d => d.DeviceIdentifier == deviceIdentifier);
|
||||||
if (existingDeviceConfig != null)
|
if (existingDeviceConfig != null)
|
||||||
{
|
{
|
||||||
PluginImplementation pluginImplementation = _pluginManagementService.GetPluginByDevice(rgbDevice);
|
PluginFeature pluginFeature = _pluginManagementService.GetDeviceProviderByDevice(rgbDevice);
|
||||||
device = new ArtemisDevice(rgbDevice, pluginImplementation, surface, existingDeviceConfig);
|
device = new ArtemisDevice(rgbDevice, pluginFeature, surface, existingDeviceConfig);
|
||||||
}
|
}
|
||||||
// Fall back on creating a new device
|
// Fall back on creating a new device
|
||||||
else
|
else
|
||||||
@ -189,8 +189,8 @@ namespace Artemis.Core.Services
|
|||||||
rgbDevice.DeviceInfo,
|
rgbDevice.DeviceInfo,
|
||||||
deviceIdentifier
|
deviceIdentifier
|
||||||
);
|
);
|
||||||
PluginImplementation pluginImplementation = _pluginManagementService.GetPluginByDevice(rgbDevice);
|
PluginFeature pluginFeature = _pluginManagementService.GetDeviceProviderByDevice(rgbDevice);
|
||||||
device = new ArtemisDevice(rgbDevice, pluginImplementation, surface);
|
device = new ArtemisDevice(rgbDevice, pluginFeature, surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
surface.Devices.Add(device);
|
surface.Devices.Add(device);
|
||||||
|
|||||||
@ -16,7 +16,7 @@ namespace Artemis.Core
|
|||||||
if (Registrations.Any(r => r.ConditionOperator == conditionOperator))
|
if (Registrations.Any(r => r.ConditionOperator == conditionOperator))
|
||||||
throw new ArtemisCoreException($"Condition operator store store already contains operator '{conditionOperator.Description}'");
|
throw new ArtemisCoreException($"Condition operator store store already contains operator '{conditionOperator.Description}'");
|
||||||
|
|
||||||
registration = new ConditionOperatorRegistration(conditionOperator, conditionOperator.PluginInfo.Plugin) {IsInStore = true};
|
registration = new ConditionOperatorRegistration(conditionOperator, conditionOperator.Plugin) {IsInStore = true};
|
||||||
Registrations.Add(registration);
|
Registrations.Add(registration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
lock (Registrations)
|
lock (Registrations)
|
||||||
{
|
{
|
||||||
return Registrations.FirstOrDefault(r => r.PluginImplementation.PluginInfo.Guid == pluginGuid && r.ConditionOperator.GetType().Name == type);
|
return Registrations.FirstOrDefault(r => r.Plugin.Guid == pluginGuid && r.ConditionOperator.GetType().Name == type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ namespace Artemis.Core
|
|||||||
if (Registrations.Any(r => r.DataBindingModifierType == modifierType))
|
if (Registrations.Any(r => r.DataBindingModifierType == modifierType))
|
||||||
throw new ArtemisCoreException($"Data binding modifier type store already contains modifier '{modifierType.Name}'");
|
throw new ArtemisCoreException($"Data binding modifier type store already contains modifier '{modifierType.Name}'");
|
||||||
|
|
||||||
typeRegistration = new DataBindingModifierTypeRegistration(modifierType, modifierType.PluginInfo.Plugin) { IsInStore = true };
|
typeRegistration = new DataBindingModifierTypeRegistration(modifierType, modifierType.Plugin) { IsInStore = true };
|
||||||
Registrations.Add(typeRegistration);
|
Registrations.Add(typeRegistration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
lock (Registrations)
|
lock (Registrations)
|
||||||
{
|
{
|
||||||
return Registrations.FirstOrDefault(r => r.PluginImplementation.PluginInfo.Guid == pluginGuid && r.DataBindingModifierType.GetType().Name == type);
|
return Registrations.FirstOrDefault(r => r.Plugin.Guid == pluginGuid && r.DataBindingModifierType.GetType().Name == type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ namespace Artemis.Core
|
|||||||
if (Registrations.Any(r => r.DataModel == dataModel))
|
if (Registrations.Any(r => r.DataModel == dataModel))
|
||||||
throw new ArtemisCoreException($"Data model store already contains data model '{dataModel.DataModelDescription}'");
|
throw new ArtemisCoreException($"Data model store already contains data model '{dataModel.DataModelDescription}'");
|
||||||
|
|
||||||
registration = new DataModelRegistration(dataModel, dataModel.Implementation.Instance) {IsInStore = true};
|
registration = new DataModelRegistration(dataModel, dataModel.Feature) {IsInStore = true};
|
||||||
Registrations.Add(registration);
|
Registrations.Add(registration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,11 +47,11 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DataModelRegistration Get(Guid pluginGuid)
|
public static DataModelRegistration Get(string id)
|
||||||
{
|
{
|
||||||
lock (Registrations)
|
lock (Registrations)
|
||||||
{
|
{
|
||||||
return Registrations.FirstOrDefault(d => d.PluginImplementation.PluginInfo.Guid == pluginGuid);
|
return Registrations.FirstOrDefault(d => d.PluginFeature.Id == id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ namespace Artemis.Core
|
|||||||
if (Registrations.Any(r => r.LayerBrushDescriptor == descriptor))
|
if (Registrations.Any(r => r.LayerBrushDescriptor == descriptor))
|
||||||
throw new ArtemisCoreException($"Store already contains layer brush '{descriptor.DisplayName}'");
|
throw new ArtemisCoreException($"Store already contains layer brush '{descriptor.DisplayName}'");
|
||||||
|
|
||||||
registration = new LayerBrushRegistration(descriptor, descriptor.LayerBrushProvider.PluginInfo.Plugin) {IsInStore = true};
|
registration = new LayerBrushRegistration(descriptor, descriptor.Provider) {IsInStore = true};
|
||||||
Registrations.Add(registration);
|
Registrations.Add(registration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,11 +47,11 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LayerBrushRegistration Get(Guid pluginGuid, string typeName)
|
public static LayerBrushRegistration? Get(string id, string typeName)
|
||||||
{
|
{
|
||||||
lock (Registrations)
|
lock (Registrations)
|
||||||
{
|
{
|
||||||
return Registrations.FirstOrDefault(d => d.PluginImplementation.PluginInfo.Guid == pluginGuid &&
|
return Registrations.FirstOrDefault(d => d.PluginFeature.Id == id &&
|
||||||
d.LayerBrushDescriptor.LayerBrushType.Name == typeName);
|
d.LayerBrushDescriptor.LayerBrushType.Name == typeName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,7 +17,7 @@ namespace Artemis.Core
|
|||||||
if (Registrations.Any(r => r.LayerEffectDescriptor == descriptor))
|
if (Registrations.Any(r => r.LayerEffectDescriptor == descriptor))
|
||||||
throw new ArtemisCoreException($"Store already contains layer brush '{descriptor.DisplayName}'");
|
throw new ArtemisCoreException($"Store already contains layer brush '{descriptor.DisplayName}'");
|
||||||
|
|
||||||
registration = new LayerEffectRegistration(descriptor, descriptor.LayerEffectProvider.PluginInfo.Plugin) { IsInStore = true };
|
registration = new LayerEffectRegistration(descriptor, descriptor.Provider) { IsInStore = true };
|
||||||
Registrations.Add(registration);
|
Registrations.Add(registration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,11 +47,11 @@ namespace Artemis.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LayerEffectRegistration Get(Guid pluginGuid, string typeName)
|
public static LayerEffectRegistration? Get(string providerId, string typeName)
|
||||||
{
|
{
|
||||||
lock (Registrations)
|
lock (Registrations)
|
||||||
{
|
{
|
||||||
return Registrations.FirstOrDefault(d => d.PluginImplementation.PluginInfo.Guid == pluginGuid && d.LayerEffectDescriptor.LayerEffectType.Name == typeName);
|
return Registrations.FirstOrDefault(d => d.PluginFeature.Id == providerId && d.LayerEffectDescriptor.LayerEffectType.Name == typeName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,12 +7,12 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ConditionOperatorRegistration
|
public class ConditionOperatorRegistration
|
||||||
{
|
{
|
||||||
internal ConditionOperatorRegistration(BaseConditionOperator conditionOperator, PluginImplementation pluginImplementation)
|
internal ConditionOperatorRegistration(BaseConditionOperator conditionOperator, Plugin plugin)
|
||||||
{
|
{
|
||||||
ConditionOperator = conditionOperator;
|
ConditionOperator = conditionOperator;
|
||||||
PluginImplementation = pluginImplementation;
|
Plugin = plugin;
|
||||||
|
|
||||||
PluginImplementation.Disabled += OnDisabled;
|
Plugin.Disabled += OnDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -23,7 +23,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin the condition operator is associated with
|
/// Gets the plugin the condition operator is associated with
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginImplementation PluginImplementation { get; }
|
public Plugin Plugin { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a boolean indicating whether the registration is in the internal Core store
|
/// Gets a boolean indicating whether the registration is in the internal Core store
|
||||||
@ -32,7 +32,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private void OnDisabled(object sender, EventArgs e)
|
private void OnDisabled(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
PluginImplementation.Disabled -= OnDisabled;
|
Plugin.Disabled -= OnDisabled;
|
||||||
if (IsInStore)
|
if (IsInStore)
|
||||||
ConditionOperatorStore.Remove(this);
|
ConditionOperatorStore.Remove(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,12 +7,12 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DataBindingModifierTypeRegistration
|
public class DataBindingModifierTypeRegistration
|
||||||
{
|
{
|
||||||
internal DataBindingModifierTypeRegistration(BaseDataBindingModifierType dataBindingModifierType, PluginImplementation pluginImplementation)
|
internal DataBindingModifierTypeRegistration(BaseDataBindingModifierType dataBindingModifierType, Plugin plugin)
|
||||||
{
|
{
|
||||||
DataBindingModifierType = dataBindingModifierType;
|
DataBindingModifierType = dataBindingModifierType;
|
||||||
PluginImplementation = pluginImplementation;
|
Plugin = plugin;
|
||||||
|
|
||||||
PluginImplementation.Disabled += OnDisabled;
|
Plugin.Disabled += OnDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -23,7 +23,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin the data binding modifier is associated with
|
/// Gets the plugin the data binding modifier is associated with
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginImplementation PluginImplementation { get; }
|
public Plugin Plugin { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a boolean indicating whether the registration is in the internal Core store
|
/// Gets a boolean indicating whether the registration is in the internal Core store
|
||||||
@ -32,7 +32,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private void OnDisabled(object sender, EventArgs e)
|
private void OnDisabled(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
PluginImplementation.Disabled -= OnDisabled;
|
Plugin.Disabled -= OnDisabled;
|
||||||
if (IsInStore)
|
if (IsInStore)
|
||||||
DataBindingModifierTypeStore.Remove(this);
|
DataBindingModifierTypeStore.Remove(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,12 +8,12 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class DataModelRegistration
|
public class DataModelRegistration
|
||||||
{
|
{
|
||||||
internal DataModelRegistration(DataModel dataModel, PluginImplementation pluginImplementation)
|
internal DataModelRegistration(DataModel dataModel, PluginFeature pluginFeature)
|
||||||
{
|
{
|
||||||
DataModel = dataModel;
|
DataModel = dataModel;
|
||||||
PluginImplementation = pluginImplementation;
|
PluginFeature = pluginFeature;
|
||||||
|
|
||||||
PluginImplementation.Disabled += OnDisabled;
|
PluginFeature.Disabled += OnDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -24,7 +24,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin the data model is associated with
|
/// Gets the plugin the data model is associated with
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginImplementation PluginImplementation { get; }
|
public PluginFeature PluginFeature { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a boolean indicating whether the registration is in the internal Core store
|
/// Gets a boolean indicating whether the registration is in the internal Core store
|
||||||
@ -33,7 +33,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private void OnDisabled(object sender, EventArgs e)
|
private void OnDisabled(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
PluginImplementation.Disabled -= OnDisabled;
|
PluginFeature.Disabled -= OnDisabled;
|
||||||
if (IsInStore)
|
if (IsInStore)
|
||||||
DataModelStore.Remove(this);
|
DataModelStore.Remove(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,12 +8,12 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class LayerBrushRegistration
|
public class LayerBrushRegistration
|
||||||
{
|
{
|
||||||
internal LayerBrushRegistration(LayerBrushDescriptor descriptor, PluginImplementation pluginImplementation)
|
internal LayerBrushRegistration(LayerBrushDescriptor descriptor, PluginFeature pluginFeature)
|
||||||
{
|
{
|
||||||
LayerBrushDescriptor = descriptor;
|
LayerBrushDescriptor = descriptor;
|
||||||
PluginImplementation = pluginImplementation;
|
PluginFeature = pluginFeature;
|
||||||
|
|
||||||
PluginImplementation.Disabled += OnDisabled;
|
PluginFeature.Disabled += OnDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -24,7 +24,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin the layer brush is associated with
|
/// Gets the plugin the layer brush is associated with
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginImplementation PluginImplementation { get; }
|
public PluginFeature PluginFeature { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a boolean indicating whether the registration is in the internal Core store
|
/// Gets a boolean indicating whether the registration is in the internal Core store
|
||||||
@ -33,7 +33,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private void OnDisabled(object sender, EventArgs e)
|
private void OnDisabled(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
PluginImplementation.Disabled -= OnDisabled;
|
PluginFeature.Disabled -= OnDisabled;
|
||||||
if (IsInStore)
|
if (IsInStore)
|
||||||
LayerBrushStore.Remove(this);
|
LayerBrushStore.Remove(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,12 +8,12 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class LayerEffectRegistration
|
public class LayerEffectRegistration
|
||||||
{
|
{
|
||||||
internal LayerEffectRegistration(LayerEffectDescriptor descriptor, PluginImplementation pluginImplementation)
|
internal LayerEffectRegistration(LayerEffectDescriptor descriptor, PluginFeature pluginFeature)
|
||||||
{
|
{
|
||||||
LayerEffectDescriptor = descriptor;
|
LayerEffectDescriptor = descriptor;
|
||||||
PluginImplementation = pluginImplementation;
|
PluginFeature = pluginFeature;
|
||||||
|
|
||||||
PluginImplementation.Disabled += OnDisabled;
|
PluginFeature.Disabled += OnDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -24,7 +24,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the plugin the layer effect is associated with
|
/// Gets the plugin the layer effect is associated with
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PluginImplementation PluginImplementation { get; }
|
public PluginFeature PluginFeature { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a boolean indicating whether the registration is in the internal Core store
|
/// Gets a boolean indicating whether the registration is in the internal Core store
|
||||||
@ -33,7 +33,7 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
private void OnDisabled(object sender, EventArgs e)
|
private void OnDisabled(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
PluginImplementation.Disabled -= OnDisabled;
|
PluginFeature.Disabled -= OnDisabled;
|
||||||
if (IsInStore)
|
if (IsInStore)
|
||||||
LayerEffectStore.Remove(this);
|
LayerEffectStore.Remove(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,13 +3,13 @@
|
|||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An empty plugin used by <see cref="Constants.CorePluginInfo"/>
|
/// An empty data model plugin feature used by <see cref="Constants.CorePlugin" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class CorePluginImplementation : PluginImplementation
|
internal class CorePluginFeature : DataModelPluginFeature
|
||||||
{
|
{
|
||||||
public CorePluginImplementation()
|
public CorePluginFeature()
|
||||||
{
|
{
|
||||||
Constants.CorePluginInfo.Plugin = this;
|
Constants.CorePlugin.AddFeature(this);
|
||||||
IsEnabled = true;
|
IsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
using System.Diagnostics;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using Stylet;
|
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
{
|
{
|
||||||
@ -37,8 +37,8 @@ namespace Artemis.Core
|
|||||||
if (!Debugger.IsAttached)
|
if (!Debugger.IsAttached)
|
||||||
Process.Start(info);
|
Process.Start(info);
|
||||||
|
|
||||||
// Also attempt a graceful shutdown on the UI thread
|
// Request a graceful shutdown, whatever UI we're running can pick this up
|
||||||
Execute.OnUIThread(() => Application.Current.Shutdown());
|
OnShutdownRequested();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -64,5 +64,18 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
return Process.GetCurrentProcess().MainModule.FileName;
|
return Process.GetCurrentProcess().MainModule.FileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Events
|
||||||
|
|
||||||
|
public static event EventHandler ShutdownRequested;
|
||||||
|
|
||||||
|
private static void OnShutdownRequested()
|
||||||
|
{
|
||||||
|
ShutdownRequested?.Invoke(null, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,15 +121,6 @@
|
|||||||
"System.Memory": "4.5.3"
|
"System.Memory": "4.5.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Stylet": {
|
|
||||||
"type": "Direct",
|
|
||||||
"requested": "[1.3.4, )",
|
|
||||||
"resolved": "1.3.4",
|
|
||||||
"contentHash": "bCEdA+AIi+TM9SQQGLYMsFRIfzZcDUDg2Mznyr72kOkcC/cdBj01/jel4/v2aoKwbFcxVjiqmpgnbsFgMEZ4zQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"System.Drawing.Common": "4.6.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"System.Buffers": {
|
"System.Buffers": {
|
||||||
"type": "Direct",
|
"type": "Direct",
|
||||||
"requested": "[4.5.0, )",
|
"requested": "[4.5.0, )",
|
||||||
@ -192,8 +183,8 @@
|
|||||||
},
|
},
|
||||||
"Microsoft.NETCore.Platforms": {
|
"Microsoft.NETCore.Platforms": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "3.0.0",
|
"resolved": "1.1.0",
|
||||||
"contentHash": "TsETIgVJb/AKoYfSP+iCxkuly5d3inZjTdx/ItZLk2CxY85v8083OBS3uai84kK3/baLnS5/b5XGs6zR7SuuHQ=="
|
"contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
|
||||||
},
|
},
|
||||||
"Microsoft.NETCore.Targets": {
|
"Microsoft.NETCore.Targets": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
@ -210,14 +201,6 @@
|
|||||||
"System.Runtime": "4.3.0"
|
"System.Runtime": "4.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Microsoft.Win32.SystemEvents": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.6.0",
|
|
||||||
"contentHash": "Edg+pFW5C8WJb680Za2kTV8TqUi6Ahl/WldRVoOVJ23UQLpDHFspa+umgFjkWZw24ETsU99Cg+ErZz683M4chg==",
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.NETCore.Platforms": "3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"NETStandard.Library": {
|
"NETStandard.Library": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "1.6.1",
|
"resolved": "1.6.1",
|
||||||
@ -557,15 +540,6 @@
|
|||||||
"System.Runtime": "4.3.0"
|
"System.Runtime": "4.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"System.Drawing.Common": {
|
|
||||||
"type": "Transitive",
|
|
||||||
"resolved": "4.6.0",
|
|
||||||
"contentHash": "2A3spjjoPZnvpVh/sDTzd+0H8ZqTdr+hH/6obB8MMfG81EJ85PmxCKDBxhBVQiA25PliKAZ1sKogDcq9mSnFEA==",
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.NETCore.Platforms": "3.0.0",
|
|
||||||
"Microsoft.Win32.SystemEvents": "4.6.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"System.Dynamic.Runtime": {
|
"System.Dynamic.Runtime": {
|
||||||
"type": "Transitive",
|
"type": "Transitive",
|
||||||
"resolved": "4.3.0",
|
"resolved": "4.3.0",
|
||||||
|
|||||||
@ -10,7 +10,7 @@ namespace Artemis.Storage.Entities.Module
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid PluginGuid { get; set; }
|
public string ModuleId { get; set; }
|
||||||
public int PriorityCategory { get; set; }
|
public int PriorityCategory { get; set; }
|
||||||
public int Priority { get; set; }
|
public int Priority { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,16 +8,21 @@ namespace Artemis.Storage.Entities.Plugins
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class PluginEntity
|
public class PluginEntity
|
||||||
{
|
{
|
||||||
|
public PluginEntity()
|
||||||
|
{
|
||||||
|
Features = new List<PluginFeatureEntity>();
|
||||||
|
}
|
||||||
|
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; }
|
||||||
|
|
||||||
public List<PluginImplementationEntity> Implementations { get; set; }
|
public List<PluginFeatureEntity> Features { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the configuration of a plugin implementation, each implementation has one configuration
|
/// Represents the configuration of a plugin feature, each feature has one configuration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PluginImplementationEntity
|
public class PluginFeatureEntity
|
||||||
{
|
{
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; }
|
||||||
|
|||||||
@ -5,7 +5,7 @@ namespace Artemis.Storage.Entities.Profile
|
|||||||
public class DataModelPathEntity
|
public class DataModelPathEntity
|
||||||
{
|
{
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
public Guid? DataModelGuid { get; set; }
|
public string DataModelId { get; set; }
|
||||||
|
|
||||||
public PathWrapperType WrapperType { get; set; }
|
public PathWrapperType WrapperType { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ namespace Artemis.Storage.Entities.Profile
|
|||||||
public class LayerEffectEntity
|
public class LayerEffectEntity
|
||||||
{
|
{
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid PluginGuid { get; set; }
|
public string ProviderId { get; set; }
|
||||||
public string EffectType { get; set; }
|
public string EffectType { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public bool Enabled { get; set; }
|
public bool Enabled { get; set; }
|
||||||
|
|||||||
@ -13,7 +13,7 @@ namespace Artemis.Storage.Entities.Profile
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Guid Id { get; set; }
|
public Guid Id { get; set; }
|
||||||
public Guid PluginGuid { get; set; }
|
public string ModuleId { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public bool IsActive { get; set; }
|
public bool IsActive { get; set; }
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Artemis.Storage.Entities.Profile.DataBindings;
|
using Artemis.Storage.Entities.Profile.DataBindings;
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.Profile
|
namespace Artemis.Storage.Entities.Profile
|
||||||
@ -12,7 +11,7 @@ namespace Artemis.Storage.Entities.Profile
|
|||||||
DataBindingEntities = new List<DataBindingEntity>();
|
DataBindingEntities = new List<DataBindingEntity>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Guid PluginGuid { get; set; }
|
public string FeatureId { get; set; }
|
||||||
public string Path { get; set; }
|
public string Path { get; set; }
|
||||||
|
|
||||||
public string Value { get; set; }
|
public string Value { get; set; }
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Artemis.Storage.Entities.Module;
|
using Artemis.Storage.Entities.Module;
|
||||||
|
|
||||||
namespace Artemis.Storage.Repositories.Interfaces
|
namespace Artemis.Storage.Repositories.Interfaces
|
||||||
@ -7,7 +6,7 @@ namespace Artemis.Storage.Repositories.Interfaces
|
|||||||
public interface IModuleRepository : IRepository
|
public interface IModuleRepository : IRepository
|
||||||
{
|
{
|
||||||
void Add(ModuleSettingsEntity moduleSettingsEntity);
|
void Add(ModuleSettingsEntity moduleSettingsEntity);
|
||||||
ModuleSettingsEntity GetByPluginGuid(Guid guid);
|
ModuleSettingsEntity GetByModuleId(string moduleId);
|
||||||
List<ModuleSettingsEntity> GetAll();
|
List<ModuleSettingsEntity> GetAll();
|
||||||
List<ModuleSettingsEntity> GetByCategory(int category);
|
List<ModuleSettingsEntity> GetByCategory(int category);
|
||||||
void Save(ModuleSettingsEntity moduleSettingsEntity);
|
void Save(ModuleSettingsEntity moduleSettingsEntity);
|
||||||
|
|||||||
@ -10,7 +10,7 @@ namespace Artemis.Storage.Repositories.Interfaces
|
|||||||
void Remove(ProfileEntity profileEntity);
|
void Remove(ProfileEntity profileEntity);
|
||||||
List<ProfileEntity> GetAll();
|
List<ProfileEntity> GetAll();
|
||||||
ProfileEntity Get(Guid id);
|
ProfileEntity Get(Guid id);
|
||||||
List<ProfileEntity> GetByPluginGuid(Guid pluginGuid);
|
List<ProfileEntity> GetByModuleId(string moduleId);
|
||||||
void Save(ProfileEntity profileEntity);
|
void Save(ProfileEntity profileEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -13,7 +13,7 @@ namespace Artemis.Storage.Repositories
|
|||||||
internal ModuleRepository(LiteRepository repository)
|
internal ModuleRepository(LiteRepository repository)
|
||||||
{
|
{
|
||||||
_repository = repository;
|
_repository = repository;
|
||||||
_repository.Database.GetCollection<ModuleSettingsEntity>().EnsureIndex(s => s.PluginGuid, true);
|
_repository.Database.GetCollection<ModuleSettingsEntity>().EnsureIndex(s => s.ModuleId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(ModuleSettingsEntity moduleSettingsEntity)
|
public void Add(ModuleSettingsEntity moduleSettingsEntity)
|
||||||
@ -21,9 +21,9 @@ namespace Artemis.Storage.Repositories
|
|||||||
_repository.Insert(moduleSettingsEntity);
|
_repository.Insert(moduleSettingsEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModuleSettingsEntity GetByPluginGuid(Guid guid)
|
public ModuleSettingsEntity GetByModuleId(string moduleId)
|
||||||
{
|
{
|
||||||
return _repository.FirstOrDefault<ModuleSettingsEntity>(s => s.PluginGuid == guid);
|
return _repository.FirstOrDefault<ModuleSettingsEntity>(s => s.ModuleId == moduleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ModuleSettingsEntity> GetAll()
|
public List<ModuleSettingsEntity> GetAll()
|
||||||
|
|||||||
@ -36,12 +36,12 @@ namespace Artemis.Storage.Repositories
|
|||||||
return _repository.FirstOrDefault<ProfileEntity>(p => p.Id == id);
|
return _repository.FirstOrDefault<ProfileEntity>(p => p.Id == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ProfileEntity> GetByPluginGuid(Guid pluginGuid)
|
public List<ProfileEntity> GetByModuleId(string moduleId)
|
||||||
{
|
{
|
||||||
return _repository.Query<ProfileEntity>()
|
return _repository.Query<ProfileEntity>()
|
||||||
.Include(p => p.Folders)
|
.Include(p => p.Folders)
|
||||||
.Include(p => p.Layers)
|
.Include(p => p.Layers)
|
||||||
.Where(s => s.PluginGuid == pluginGuid)
|
.Where(s => s.ModuleId == moduleId)
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=events/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=events/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=exceptions/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=exceptions/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=extensions/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=extensions/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=propertyinput/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=propertyinput/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cdatamodelvisualization/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cdatamodelvisualization/@EntryIndexedValue">True</s:Boolean>
|
||||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cdialog/@EntryIndexedValue">True</s:Boolean>
|
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=services_005Cdialog/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
|||||||
@ -11,22 +11,22 @@ namespace Artemis.UI.Shared
|
|||||||
|
|
||||||
public DataModelVisualizationRegistration(IDataModelUIService dataModelUIService,
|
public DataModelVisualizationRegistration(IDataModelUIService dataModelUIService,
|
||||||
RegistrationType registrationType,
|
RegistrationType registrationType,
|
||||||
PluginInfo pluginInfo,
|
Plugin plugin,
|
||||||
Type supportedType,
|
Type supportedType,
|
||||||
Type viewModelType)
|
Type viewModelType)
|
||||||
{
|
{
|
||||||
_dataModelUIService = dataModelUIService;
|
_dataModelUIService = dataModelUIService;
|
||||||
RegistrationType = registrationType;
|
RegistrationType = registrationType;
|
||||||
PluginInfo = pluginInfo;
|
Plugin = plugin;
|
||||||
SupportedType = supportedType;
|
SupportedType = supportedType;
|
||||||
ViewModelType = viewModelType;
|
ViewModelType = viewModelType;
|
||||||
|
|
||||||
if (PluginInfo != Constants.CorePluginInfo)
|
if (Plugin != Constants.CorePlugin)
|
||||||
PluginInfo.Plugin.Disabled += InstanceOnDisabled;
|
Plugin.Disabled += InstanceOnDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegistrationType RegistrationType { get; }
|
public RegistrationType RegistrationType { get; }
|
||||||
public PluginInfo PluginInfo { get; }
|
public Plugin Plugin { get; }
|
||||||
public Type SupportedType { get; }
|
public Type SupportedType { get; }
|
||||||
public Type ViewModelType { get; }
|
public Type ViewModelType { get; }
|
||||||
|
|
||||||
@ -34,8 +34,8 @@ namespace Artemis.UI.Shared
|
|||||||
|
|
||||||
internal void Unsubscribe()
|
internal void Unsubscribe()
|
||||||
{
|
{
|
||||||
if (PluginInfo != Constants.CorePluginInfo)
|
if (Plugin != Constants.CorePlugin)
|
||||||
PluginInfo.Plugin.Disabled -= InstanceOnDisabled;
|
Plugin.Disabled -= InstanceOnDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InstanceOnDisabled(object sender, EventArgs e)
|
private void InstanceOnDisabled(object sender, EventArgs e)
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using Stylet;
|
using Artemis.Core.LayerBrushes;
|
||||||
|
using Stylet;
|
||||||
|
|
||||||
namespace Artemis.Core.LayerBrushes
|
namespace Artemis.UI.Shared.LayerBrushes
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a view model for a brush configuration window
|
/// Represents a view model for a brush configuration window
|
||||||
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Artemis.Core.LayerBrushes;
|
||||||
|
|
||||||
namespace Artemis.Core.LayerBrushes
|
namespace Artemis.UI.Shared.LayerBrushes
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public class LayerBrushConfigurationDialog<T> : LayerBrushConfigurationDialog where T : BrushConfigurationViewModel
|
public class LayerBrushConfigurationDialog<T> : LayerBrushConfigurationDialog where T : BrushConfigurationViewModel
|
||||||
@ -12,7 +13,7 @@ namespace Artemis.Core.LayerBrushes
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Describes a UI tab for a layer brush
|
/// Describes a UI tab for a layer brush
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class LayerBrushConfigurationDialog
|
public abstract class LayerBrushConfigurationDialog : ILayerBrushConfigurationDialog
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The layer brush this dialog belongs to
|
/// The layer brush this dialog belongs to
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user