diff --git a/src/Artemis.Core/Artemis.Core.csproj b/src/Artemis.Core/Artemis.Core.csproj
index 42b2f16f6..6b20d3e22 100644
--- a/src/Artemis.Core/Artemis.Core.csproj
+++ b/src/Artemis.Core/Artemis.Core.csproj
@@ -50,7 +50,6 @@
-
diff --git a/src/Artemis.Core/Artemis.Core.csproj.DotSettings b/src/Artemis.Core/Artemis.Core.csproj.DotSettings
index 705d6dc5c..5963c6027 100644
--- a/src/Artemis.Core/Artemis.Core.csproj.DotSettings
+++ b/src/Artemis.Core/Artemis.Core.csproj.DotSettings
@@ -42,6 +42,7 @@
True
True
True
+ True
True
True
True
diff --git a/src/Artemis.Core/Constants.cs b/src/Artemis.Core/Constants.cs
index 29ecf764f..36f32cada 100644
--- a/src/Artemis.Core/Constants.cs
+++ b/src/Artemis.Core/Constants.cs
@@ -12,7 +12,7 @@ namespace Artemis.Core
///
/// The full path to the Artemis application folder
///
- public static readonly string ApplicationFolder = Path.GetDirectoryName(typeof(Constants).Assembly.Location);
+ public static readonly string ApplicationFolder = Path.GetDirectoryName(typeof(Constants).Assembly.Location)!;
///
/// The full path to the Artemis executable
@@ -34,11 +34,16 @@ namespace Artemis.Core
///
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};
- internal static readonly EffectPlaceholderPlugin EffectPlaceholderPlugin = new EffectPlaceholderPlugin {PluginInfo = CorePluginInfo};
+ ///
+ /// The plugin used by core components of Artemis
+ ///
+ 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};
///
/// A read-only collection containing all primitive numeric types
diff --git a/src/Artemis.Core/Events/Plugins/PluginFeatureEventArgs.cs b/src/Artemis.Core/Events/Plugins/PluginFeatureEventArgs.cs
new file mode 100644
index 000000000..288e46088
--- /dev/null
+++ b/src/Artemis.Core/Events/Plugins/PluginFeatureEventArgs.cs
@@ -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; }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Events/Plugins/PluginImplementationEventArgs.cs b/src/Artemis.Core/Events/Plugins/PluginImplementationEventArgs.cs
deleted file mode 100644
index 45f5639c9..000000000
--- a/src/Artemis.Core/Events/Plugins/PluginImplementationEventArgs.cs
+++ /dev/null
@@ -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; }
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.Core/Exceptions/ArtemisPluginFeatureException.cs b/src/Artemis.Core/Exceptions/ArtemisPluginFeatureException.cs
new file mode 100644
index 000000000..e15e7e313
--- /dev/null
+++ b/src/Artemis.Core/Exceptions/ArtemisPluginFeatureException.cs
@@ -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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/MVVM/CorePropertyChanged.cs b/src/Artemis.Core/MVVM/CorePropertyChanged.cs
new file mode 100644
index 000000000..d4ff0419f
--- /dev/null
+++ b/src/Artemis.Core/MVVM/CorePropertyChanged.cs
@@ -0,0 +1,72 @@
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+
+namespace Artemis.Core
+{
+ ///
+ /// Represents a basic bindable class which notifies when a property value changes.
+ ///
+ public abstract class CorePropertyChanged : INotifyPropertyChanged
+ {
+ #region Events
+
+ ///
+ /// Occurs when a property value changes.
+ ///
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// Checks if the property already matches the desirec value or needs to be updated.
+ ///
+ /// Type of the property.
+ /// Reference to the backing-filed.
+ /// Value to apply.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ protected virtual bool RequiresUpdate(ref T storage, T value)
+ {
+ return !Equals(storage, value);
+ }
+
+ ///
+ /// Checks if the property already matches the desired value and updates it if not.
+ ///
+ /// Type of the property.
+ /// Reference to the backing-filed.
+ /// Value to apply.
+ ///
+ /// Name of the property used to notify listeners. This value is optional
+ /// and can be provided automatically when invoked from compilers that support
+ /// .
+ ///
+ /// true if the value was changed, false if the existing value matched the desired value.
+ protected virtual bool SetAndNotify(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;
+ }
+
+ ///
+ /// Triggers the -event when a a property value has changed.
+ ///
+ ///
+ /// Name of the property used to notify listeners. This value is optional
+ /// and can be provided automatically when invoked from compilers that support
+ /// .
+ ///
+ protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs b/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs
index ae94b9a55..da7a0e1d7 100644
--- a/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs
+++ b/src/Artemis.Core/Models/Profile/Colors/ColorGradient.cs
@@ -5,7 +5,6 @@ using System.Linq;
using System.Runtime.CompilerServices;
using Artemis.Core.Properties;
using SkiaSharp;
-using Stylet;
namespace Artemis.Core
{
@@ -19,13 +18,13 @@ namespace Artemis.Core
///
public ColorGradient()
{
- Stops = new BindableCollection();
+ Stops = new List();
}
///
/// Gets a list of all the s in the gradient
///
- public BindableCollection Stops { get; }
+ public List Stops { get; }
///
/// Gets all the colors in the color gradient
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Abstract/BaseConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Abstract/BaseConditionOperator.cs
index e67e73d78..f99c881a7 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Abstract/BaseConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Abstract/BaseConditionOperator.cs
@@ -22,10 +22,10 @@ namespace Artemis.Core
public abstract string Icon { get; }
///
- /// Gets the plugin info this condition operator belongs to
+ /// Gets the plugin this condition operator belongs to
/// Note: Not set until after registering
///
- public PluginInfo PluginInfo { get; internal set; }
+ public Plugin Plugin { get; internal set; }
///
/// Gets the left side type of this condition operator
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPredicate.cs b/src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPredicate.cs
index f99364cd2..32bb54423 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPredicate.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Abstract/DataModelConditionPredicate.cs
@@ -346,7 +346,7 @@ namespace Artemis.Core
if (Operator != null)
{
- Entity.OperatorPluginGuid = Operator.PluginInfo.Guid;
+ Entity.OperatorPluginGuid = Operator.Plugin.Guid;
Entity.OperatorType = Operator.GetType().Name;
}
}
@@ -358,7 +358,7 @@ namespace Artemis.Core
private void ConditionOperatorStoreOnConditionOperatorAdded(object? sender, ConditionOperatorStoreEvent e)
{
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);
}
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Wrappers/EventPredicateWrapperDataModel.cs b/src/Artemis.Core/Models/Profile/Conditions/Wrappers/EventPredicateWrapperDataModel.cs
index a392ca02b..26768b06c 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Wrappers/EventPredicateWrapperDataModel.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Wrappers/EventPredicateWrapperDataModel.cs
@@ -16,7 +16,7 @@ namespace Artemis.Core
{
internal EventPredicateWrapperDataModel()
{
- Implementation = Constants.CorePluginInfo;
+ Feature = Constants.CorePluginFeature;
}
[DataModelIgnore]
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Wrappers/ListPredicateWrapperDataModel.cs b/src/Artemis.Core/Models/Profile/Conditions/Wrappers/ListPredicateWrapperDataModel.cs
index 879f3b6c6..bfa4396a5 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Wrappers/ListPredicateWrapperDataModel.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Wrappers/ListPredicateWrapperDataModel.cs
@@ -16,7 +16,7 @@ namespace Artemis.Core
{
internal ListPredicateWrapperDataModel()
{
- Implementation = Constants.CorePluginInfo;
+ Feature = Constants.CorePluginFeature;
}
[DataModelIgnore]
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/BaseDataBindingModifierType.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/BaseDataBindingModifierType.cs
index d4658d212..b3f2ec115 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/BaseDataBindingModifierType.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/BaseDataBindingModifierType.cs
@@ -12,10 +12,10 @@ namespace Artemis.Core
public abstract class BaseDataBindingModifierType
{
///
- /// Gets the plugin info this data binding modifier belongs to
+ /// Gets the plugin this data binding modifier belongs to
/// Note: Not set until after registering
///
- public PluginInfo PluginInfo { get; internal set; }
+ public Plugin Plugin { get; internal set; }
///
/// Gets the value type of this modifier type
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/DataBindingModifier.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/DataBindingModifier.cs
index 10732dfd3..02235faa2 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/DataBindingModifier.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Modes/Direct/DataBindingModifier.cs
@@ -238,7 +238,7 @@ namespace Artemis.Core
if (ModifierType != null)
{
Entity.ModifierType = ModifierType.GetType().Name;
- Entity.ModifierTypePluginGuid = ModifierType.PluginInfo.Guid;
+ Entity.ModifierTypePluginGuid = ModifierType.Plugin.Guid;
}
// General
@@ -286,7 +286,7 @@ namespace Artemis.Core
return;
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);
}
diff --git a/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs b/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs
index 090e0912f..f7ce3f942 100644
--- a/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs
+++ b/src/Artemis.Core/Models/Profile/DataModel/DataModelPath.cs
@@ -91,9 +91,9 @@ namespace Artemis.Core
public DataModel? Target { get; private set; }
///
- /// Gets the data model GUID of the if it is a
+ /// Gets the data model ID of the if it is a
///
- public Guid? DataModelGuid => Target?.Implementation.Guid;
+ public string? DataModelId => Target?.Feature.Id;
///
/// Gets the point-separated path associated with this
@@ -267,8 +267,8 @@ namespace Artemis.Core
{
Path = Entity.Path;
- if (Target == null && Entity.DataModelGuid != null)
- Target = DataModelStore.Get(Entity.DataModelGuid.Value)?.DataModel;
+ if (Target == null && Entity.DataModelId != null)
+ Target = DataModelStore.Get(Entity.DataModelId)?.DataModel;
}
///
@@ -279,7 +279,7 @@ namespace Artemis.Core
return;
Entity.Path = Path;
- Entity.DataModelGuid = DataModelGuid;
+ Entity.DataModelId = DataModelId;
Entity.WrapperType = Target switch
{
@@ -295,7 +295,7 @@ namespace Artemis.Core
private void DataModelStoreOnDataModelAdded(object? sender, DataModelStoreEvent e)
{
- if (e.Registration.DataModel.Implementation.Guid != Entity.DataModelGuid)
+ if (e.Registration.DataModel.Feature.Id != Entity.DataModelId)
return;
Target = e.Registration.DataModel;
@@ -304,7 +304,7 @@ namespace Artemis.Core
private void DataModelStoreOnDataModelRemoved(object? sender, DataModelStoreEvent e)
{
- if (e.Registration.DataModel.Implementation.Guid != Entity.DataModelGuid)
+ if (e.Registration.DataModel.Feature.Id != Entity.DataModelId)
return;
Target = null;
diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs
index f10f3a0f2..b2de34b23 100644
--- a/src/Artemis.Core/Models/Profile/Layer.cs
+++ b/src/Artemis.Core/Models/Profile/Layer.cs
@@ -190,9 +190,9 @@ namespace Artemis.Core
typeof(PropertyGroupDescriptionAttribute)
);
General.GroupDescription = (PropertyGroupDescriptionAttribute) generalAttribute;
- General.Initialize(this, "General.", Constants.CorePluginInfo);
+ General.Initialize(this, "General.", Constants.CorePluginFeature);
Transform.GroupDescription = (PropertyGroupDescriptionAttribute) transformAttribute;
- Transform.Initialize(this, "Transform.", Constants.CorePluginInfo);
+ Transform.Initialize(this, "Transform.", Constants.CorePluginFeature);
General.ShapeType.CurrentValueSet += ShapeTypeOnCurrentValueSet;
ApplyShapeType();
@@ -619,7 +619,7 @@ namespace Artemis.Core
BaseLayerBrush brush = LayerBrush;
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()
@@ -628,7 +628,7 @@ namespace Artemis.Core
if (current == null)
return;
- LayerBrushDescriptor descriptor = LayerBrushStore.Get(current.BrushPluginGuid, current.BrushType)?.LayerBrushDescriptor;
+ LayerBrushDescriptor? descriptor = LayerBrushStore.Get(current.LayerBrushProviderId, current.BrushType)?.LayerBrushDescriptor;
descriptor?.CreateInstance(this);
OnLayerBrushUpdated();
@@ -662,7 +662,7 @@ namespace Artemis.Core
return;
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)
ActivateLayerBrush();
}
diff --git a/src/Artemis.Core/Models/Profile/LayerBrushReference.cs b/src/Artemis.Core/Models/Profile/LayerBrushReference.cs
index bcad54663..e9cf6d946 100644
--- a/src/Artemis.Core/Models/Profile/LayerBrushReference.cs
+++ b/src/Artemis.Core/Models/Profile/LayerBrushReference.cs
@@ -1,5 +1,4 @@
-using System;
-using Artemis.Core.LayerBrushes;
+using Artemis.Core.LayerBrushes;
namespace Artemis.Core
{
@@ -8,24 +7,24 @@ namespace Artemis.Core
///
public class LayerBrushReference
{
- ///
- /// The GUID of the plugin the brush descriptor resides in
- ///
- public Guid BrushPluginGuid { get; set; }
-
- ///
- /// The full type name of the brush descriptor
- ///
- public string BrushType { get; set; }
-
public LayerBrushReference()
{
}
public LayerBrushReference(LayerBrushDescriptor descriptor)
{
- BrushPluginGuid = descriptor.LayerBrushProvider.PluginInfo.Guid;
+ LayerBrushProviderId = descriptor.Provider.Id;
BrushType = descriptor.LayerBrushType.Name;
}
+
+ ///
+ /// The ID of the layer brush provided the brush was provided by
+ ///
+ public string LayerBrushProviderId { get; set; }
+
+ ///
+ /// The full type name of the brush descriptor
+ ///
+ public string BrushType { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/LayerProperties/LayerPropertyKeyFrame.cs b/src/Artemis.Core/Models/Profile/LayerProperties/LayerPropertyKeyFrame.cs
index cdade5471..3afe363bd 100644
--- a/src/Artemis.Core/Models/Profile/LayerProperties/LayerPropertyKeyFrame.cs
+++ b/src/Artemis.Core/Models/Profile/LayerProperties/LayerPropertyKeyFrame.cs
@@ -1,12 +1,11 @@
using System;
-using Stylet;
namespace Artemis.Core
{
///
/// Represents a keyframe on a containing a value and a timestamp
///
- public class LayerPropertyKeyframe : PropertyChangedBase
+ public class LayerPropertyKeyframe : CorePropertyChanged
{
private LayerProperty _layerProperty;
private TimeSpan _position;
diff --git a/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs b/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs
index f27827c74..b3fbfe5ff 100644
--- a/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs
+++ b/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs
@@ -28,11 +28,11 @@ namespace Artemis.Core
/// Gets the description of this group
///
public PropertyGroupDescriptionAttribute GroupDescription { get; internal set; }
-
+
///
- /// Gets the info of the plugin this group is associated with
+ /// Gets the plugin feature this group is associated with
///
- public PluginInfo PluginInfo { get; internal set; }
+ public PluginFeature Feature { get; set; }
///
/// 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);
}
- internal void Initialize(RenderProfileElement profileElement, [NotNull] string path, PluginInfo pluginInfo)
+ internal void Initialize(RenderProfileElement profileElement, [NotNull] string path, PluginFeature feature)
{
if (path == null)
throw new ArgumentNullException(nameof(path));
- if (pluginInfo == null)
- throw new ArgumentNullException(nameof(pluginInfo));
+ if (feature == null)
+ throw new ArgumentNullException(nameof(feature));
// Doubt this will happen but let's make sure
if (PropertiesInitialized)
throw new ArtemisCoreException("Layer property group already initialized, wut");
- PluginInfo = pluginInfo;
+ Feature = feature;
ProfileElement = profileElement;
Path = path.TrimEnd('.');
@@ -246,7 +246,7 @@ namespace Artemis.Core
instance.GroupDescription = propertyGroupDescription;
instance.LayerBrush = LayerBrush;
instance.LayerEffect = LayerEffect;
- instance.Initialize(ProfileElement, $"{path}{propertyInfo.Name}.", PluginInfo);
+ instance.Initialize(ProfileElement, $"{path}{propertyInfo.Name}.", Feature);
propertyInfo.SetValue(this, instance);
_layerPropertyGroups.Add(instance);
@@ -254,11 +254,11 @@ namespace Artemis.Core
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;
if (entity == null)
{
- entity = new PropertyEntity {PluginGuid = PluginInfo.Guid, Path = path};
+ entity = new PropertyEntity {FeatureId = Feature.Id, Path = path};
profileElement.RenderElementEntity.PropertyEntities.Add(entity);
}
diff --git a/src/Artemis.Core/Models/Profile/Profile.cs b/src/Artemis.Core/Models/Profile/Profile.cs
index e92a80027..40d61fd06 100644
--- a/src/Artemis.Core/Models/Profile/Profile.cs
+++ b/src/Artemis.Core/Models/Profile/Profile.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using Artemis.Core.Modules;
using Artemis.Storage.Entities.Profile;
-using Newtonsoft.Json;
using SkiaSharp;
namespace Artemis.Core
@@ -147,7 +146,7 @@ namespace Artemis.Core
throw new ObjectDisposedException("Profile");
ProfileEntity.Id = EntityId;
- ProfileEntity.PluginGuid = Module.PluginInfo.Guid;
+ ProfileEntity.ModuleId = Module.Id;
ProfileEntity.Name = Name;
ProfileEntity.IsActive = IsActivated;
diff --git a/src/Artemis.Core/Models/Profile/ProfileElement.cs b/src/Artemis.Core/Models/Profile/ProfileElement.cs
index 85cd09919..e55851f38 100644
--- a/src/Artemis.Core/Models/Profile/ProfileElement.cs
+++ b/src/Artemis.Core/Models/Profile/ProfileElement.cs
@@ -3,11 +3,10 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using SkiaSharp;
-using Stylet;
namespace Artemis.Core
{
- public abstract class ProfileElement : PropertyChangedBase, IDisposable
+ public abstract class ProfileElement : CorePropertyChanged, IDisposable
{
private bool _enabled;
private Guid _entityId;
diff --git a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
index 302507fca..de9a7726a 100644
--- a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
+++ b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
@@ -44,7 +44,7 @@ namespace Artemis.Core
LayerEffectEntity layerEffectEntity = new LayerEffectEntity
{
Id = layerEffect.EntityId,
- PluginGuid = layerEffect.Descriptor.PlaceholderFor ?? layerEffect.PluginInfo.Guid,
+ ProviderId = layerEffect.Descriptor.PlaceholderFor ?? layerEffect.ProviderId,
EffectType = layerEffect.GetEffectTypeName(),
Name = layerEffect.Name,
Enabled = layerEffect.Enabled,
@@ -215,11 +215,11 @@ namespace Artemis.Core
foreach (LayerEffectEntity layerEffectEntity in RenderElementEntity.LayerEffects)
{
// 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)
continue;
- LayerEffectDescriptor descriptor = LayerEffectStore.Get(layerEffectEntity.PluginGuid, layerEffectEntity.EffectType)?.LayerEffectDescriptor;
+ LayerEffectDescriptor? descriptor = LayerEffectStore.Get(layerEffectEntity.ProviderId, layerEffectEntity.EffectType)?.LayerEffectDescriptor;
if (descriptor != null)
{
// 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)
{
// 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);
}
}
@@ -253,22 +253,22 @@ namespace Artemis.Core
private void LayerEffectStoreOnLayerEffectRemoved(object sender, LayerEffectStoreEvent e)
{
// If effects provided by the plugin are on the element, replace them with placeholders
- List pluginEffects = _layerEffects.Where(ef => ef.Descriptor.LayerEffectProvider != null &&
- ef.PluginInfo.Guid == e.Registration.PluginImplementation.PluginInfo.Guid).ToList();
+ List pluginEffects = _layerEffects.Where(ef => ef.Descriptor.Provider != null &&
+ ef.ProviderId == e.Registration.PluginFeature.Id).ToList();
foreach (BaseLayerEffect pluginEffect in pluginEffects)
{
LayerEffectEntity entity = RenderElementEntity.LayerEffects.First(en => en.Id == pluginEffect.EntityId);
_layerEffects.Remove(pluginEffect);
pluginEffect.Dispose();
- LayerEffectDescriptor descriptor = PlaceholderLayerEffectDescriptor.Create(pluginEffect.PluginInfo.Guid);
+ LayerEffectDescriptor descriptor = PlaceholderLayerEffectDescriptor.Create(pluginEffect.ProviderId);
descriptor.CreateInstance(this, entity);
}
}
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();
}
diff --git a/src/Artemis.Core/Models/Profile/Timeline.cs b/src/Artemis.Core/Models/Profile/Timeline.cs
index 1f94376d9..f50e7d922 100644
--- a/src/Artemis.Core/Models/Profile/Timeline.cs
+++ b/src/Artemis.Core/Models/Profile/Timeline.cs
@@ -3,14 +3,13 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Artemis.Storage.Entities.Profile;
-using Stylet;
namespace Artemis.Core
{
///
/// Represents a timeline used by profile elements
///
- public class Timeline : PropertyChangedBase, IStorageModel
+ public class Timeline : CorePropertyChanged, IStorageModel
{
private const int MaxExtraTimelines = 15;
@@ -275,20 +274,20 @@ namespace Artemis.Core
if (segment <= TimelineSegment.End)
{
if (startUpdated || segment < TimelineSegment.End)
- NotifyOfPropertyChange(nameof(EndSegmentStartPosition));
- NotifyOfPropertyChange(nameof(EndSegmentEndPosition));
+ OnPropertyChanged(nameof(EndSegmentStartPosition));
+ OnPropertyChanged(nameof(EndSegmentEndPosition));
}
if (segment <= TimelineSegment.Main)
{
if (startUpdated || segment < TimelineSegment.Main)
- NotifyOfPropertyChange(nameof(MainSegmentStartPosition));
- NotifyOfPropertyChange(nameof(MainSegmentEndPosition));
+ OnPropertyChanged(nameof(MainSegmentStartPosition));
+ OnPropertyChanged(nameof(MainSegmentEndPosition));
}
- if (segment <= TimelineSegment.Start) NotifyOfPropertyChange(nameof(StartSegmentEndPosition));
+ if (segment <= TimelineSegment.Start) OnPropertyChanged(nameof(StartSegmentEndPosition));
- NotifyOfPropertyChange(nameof(Length));
+ OnPropertyChanged(nameof(Length));
}
#endregion
diff --git a/src/Artemis.Core/Models/Surface/ArtemisDevice.cs b/src/Artemis.Core/Models/Surface/ArtemisDevice.cs
index 6a9982676..adf4e6d20 100644
--- a/src/Artemis.Core/Models/Surface/ArtemisDevice.cs
+++ b/src/Artemis.Core/Models/Surface/ArtemisDevice.cs
@@ -4,20 +4,19 @@ using System.Linq;
using Artemis.Storage.Entities.Surface;
using RGB.NET.Core;
using SkiaSharp;
-using Stylet;
namespace Artemis.Core
{
- public class ArtemisDevice : PropertyChangedBase
+ public class ArtemisDevice : CorePropertyChanged
{
private ReadOnlyCollection _leds;
private SKPath _renderPath;
private SKRect _renderRectangle;
- internal ArtemisDevice(IRGBDevice rgbDevice, PluginImplementation pluginImplementation, ArtemisSurface surface)
+ internal ArtemisDevice(IRGBDevice rgbDevice, PluginFeature pluginFeature, ArtemisSurface surface)
{
RgbDevice = rgbDevice;
- PluginImplementation = pluginImplementation;
+ PluginFeature = pluginFeature;
Surface = surface;
DeviceEntity = new DeviceEntity();
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
@@ -30,10 +29,10 @@ namespace Artemis.Core
CalculateRenderProperties();
}
- internal ArtemisDevice(IRGBDevice rgbDevice, PluginImplementation pluginImplementation, ArtemisSurface surface, DeviceEntity deviceEntity)
+ internal ArtemisDevice(IRGBDevice rgbDevice, PluginFeature pluginFeature, ArtemisSurface surface, DeviceEntity deviceEntity)
{
RgbDevice = rgbDevice;
- PluginImplementation = pluginImplementation;
+ PluginFeature = pluginFeature;
Surface = surface;
DeviceEntity = deviceEntity;
Leds = rgbDevice.Select(l => new ArtemisLed(l, this)).ToList().AsReadOnly();
@@ -52,7 +51,7 @@ namespace Artemis.Core
}
public IRGBDevice RgbDevice { get; }
- public PluginImplementation PluginImplementation { get; }
+ public PluginFeature PluginFeature { get; }
public ArtemisSurface Surface { get; }
public DeviceEntity DeviceEntity { get; }
@@ -68,7 +67,7 @@ namespace Artemis.Core
set
{
DeviceEntity.X = value;
- NotifyOfPropertyChange(nameof(X));
+ OnPropertyChanged(nameof(X));
}
}
@@ -78,7 +77,7 @@ namespace Artemis.Core
set
{
DeviceEntity.Y = value;
- NotifyOfPropertyChange(nameof(Y));
+ OnPropertyChanged(nameof(Y));
}
}
@@ -88,7 +87,7 @@ namespace Artemis.Core
set
{
DeviceEntity.Rotation = value;
- NotifyOfPropertyChange(nameof(Rotation));
+ OnPropertyChanged(nameof(Rotation));
}
}
@@ -98,7 +97,7 @@ namespace Artemis.Core
set
{
DeviceEntity.Scale = value;
- NotifyOfPropertyChange(nameof(Scale));
+ OnPropertyChanged(nameof(Scale));
}
}
@@ -108,7 +107,7 @@ namespace Artemis.Core
set
{
DeviceEntity.ZIndex = value;
- NotifyOfPropertyChange(nameof(ZIndex));
+ OnPropertyChanged(nameof(ZIndex));
}
}
diff --git a/src/Artemis.Core/Models/Surface/ArtemisLed.cs b/src/Artemis.Core/Models/Surface/ArtemisLed.cs
index d4f8f0546..0c55c356f 100644
--- a/src/Artemis.Core/Models/Surface/ArtemisLed.cs
+++ b/src/Artemis.Core/Models/Surface/ArtemisLed.cs
@@ -1,10 +1,9 @@
using RGB.NET.Core;
using SkiaSharp;
-using Stylet;
namespace Artemis.Core
{
- public class ArtemisLed : PropertyChangedBase
+ public class ArtemisLed : CorePropertyChanged
{
private SKRect _absoluteRenderRectangle;
private SKRect _renderRectangle;
diff --git a/src/Artemis.Core/Models/Surface/ArtemisSurface.cs b/src/Artemis.Core/Models/Surface/ArtemisSurface.cs
index 7b0a34376..f79040289 100644
--- a/src/Artemis.Core/Models/Surface/ArtemisSurface.cs
+++ b/src/Artemis.Core/Models/Surface/ArtemisSurface.cs
@@ -3,11 +3,10 @@ using System.Collections.Generic;
using System.Linq;
using Artemis.Storage.Entities.Surface;
using RGB.NET.Core;
-using Stylet;
namespace Artemis.Core
{
- public class ArtemisSurface : PropertyChangedBase
+ public class ArtemisSurface : CorePropertyChanged
{
private List _devices;
private bool _isActive;
diff --git a/src/Artemis.Core/Ninject/PluginSettingsProvider.cs b/src/Artemis.Core/Ninject/PluginSettingsProvider.cs
index 559fa4087..e2f303ce7 100644
--- a/src/Artemis.Core/Ninject/PluginSettingsProvider.cs
+++ b/src/Artemis.Core/Ninject/PluginSettingsProvider.cs
@@ -6,6 +6,7 @@ using Ninject.Activation;
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
{
private static readonly List PluginSettings = new List();
@@ -25,21 +26,22 @@ namespace Artemis.Core.Ninject
throw new ArtemisCoreException("PluginSettings couldn't be injected, failed to get the injection parent request");
// First try by PluginInfo parameter
- PluginInfo pluginInfo = parentRequest.Parameters.FirstOrDefault(p => p.Name == "PluginInfo")?.GetValue(context, null) as PluginInfo;
- if (pluginInfo == null)
- pluginInfo = _pluginManagementService.GetPluginByAssembly(parentRequest.Service.Assembly)?.PluginInfo;
+ Plugin? plugin = parentRequest.Parameters.FirstOrDefault(p => p.Name == "Plugin")?.GetValue(context, null) as Plugin;
// 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 " +
"or into a class defined in a plugin assembly");
lock (PluginSettings)
{
- PluginSettings? existingSettings = PluginSettings.FirstOrDefault(p => p.PluginInfo == pluginInfo);
+ PluginSettings? existingSettings = PluginSettings.FirstOrDefault(p => p.Plugin == plugin);
if (existingSettings != null)
return existingSettings;
- PluginSettings? settings = new PluginSettings(pluginInfo, _pluginRepository);
+ PluginSettings? settings = new PluginSettings(plugin, _pluginRepository);
PluginSettings.Add(settings);
return settings;
}
diff --git a/src/Artemis.Core/Ninject/SettingsServiceProvider.cs b/src/Artemis.Core/Ninject/SettingsServiceProvider.cs
index f3dcc8e2c..3a1f3efa0 100644
--- a/src/Artemis.Core/Ninject/SettingsServiceProvider.cs
+++ b/src/Artemis.Core/Ninject/SettingsServiceProvider.cs
@@ -17,7 +17,7 @@ namespace Artemis.Core.Ninject
protected override ISettingsService CreateInstance(IContext context)
{
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.");
return _instance;
diff --git a/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs b/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs
index 28f3a22cb..dfbd52efd 100644
--- a/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs
+++ b/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs
@@ -14,10 +14,10 @@ namespace Artemis.Core.DataModelExpansions
private readonly Dictionary _dynamicDataModels = new Dictionary();
///
- /// Gets the plugin implementation this data model belongs to
+ /// Gets the plugin feature this data model belongs to
///
[DataModelIgnore]
- public DataModelPluginImplementation Implementation { get; internal set; }
+ public DataModelPluginFeature Feature { get; internal set; }
///
/// Gets the describing this data model
@@ -43,9 +43,9 @@ namespace Artemis.Core.DataModelExpansions
///
public ReadOnlyCollection GetHiddenProperties()
{
- if (Implementation is ProfileModule profileModule)
+ if (Feature is ProfileModule profileModule)
return profileModule.HiddenProperties;
- if (Implementation is BaseDataModelExpansion dataModelExpansion)
+ if (Feature is BaseDataModelExpansion dataModelExpansion)
return dataModelExpansion.HiddenProperties;
return new List().AsReadOnly();
@@ -81,7 +81,7 @@ namespace Artemis.Core.DataModelExpansions
throw new ArtemisCoreException($"Cannot add a dynamic data model with key '{key}' " +
"because the key is already in use by a static property on this data model.");
- dynamicDataModel.Implementation = Implementation;
+ dynamicDataModel.Feature = Feature;
dynamicDataModel.DataModelDescription = new DataModelPropertyAttribute
{
Name = string.IsNullOrWhiteSpace(name) ? key.Humanize() : name,
diff --git a/src/Artemis.Core/Plugins/DataModelExpansions/DataModelExpansion.cs b/src/Artemis.Core/Plugins/DataModelExpansions/DataModelExpansion.cs
index f4db43abf..eca795b81 100644
--- a/src/Artemis.Core/Plugins/DataModelExpansions/DataModelExpansion.cs
+++ b/src/Artemis.Core/Plugins/DataModelExpansions/DataModelExpansion.cs
@@ -45,7 +45,7 @@ namespace Artemis.Core.DataModelExpansions
internal override void InternalEnable()
{
DataModel = Activator.CreateInstance();
- DataModel.Implementation = PluginInfo;
+ DataModel.Feature = this;
DataModel.DataModelDescription = GetDataModelDescription();
base.InternalEnable();
}
diff --git a/src/Artemis.Core/Plugins/DataModelExpansions/Internal/BaseDataModelExpansion.cs b/src/Artemis.Core/Plugins/DataModelExpansions/Internal/BaseDataModelExpansion.cs
index 3a66789bb..9ab4f034f 100644
--- a/src/Artemis.Core/Plugins/DataModelExpansions/Internal/BaseDataModelExpansion.cs
+++ b/src/Artemis.Core/Plugins/DataModelExpansions/Internal/BaseDataModelExpansion.cs
@@ -8,7 +8,7 @@ namespace Artemis.Core.DataModelExpansions
/// For internal use only, to implement your own layer property type, extend
/// instead.
///
- public abstract class BaseDataModelExpansion : DataModelPluginImplementation
+ public abstract class BaseDataModelExpansion : DataModelPluginFeature
{
///
/// Gets a list of all properties ignored at runtime using IgnoreProperty(x => x.y)
@@ -35,7 +35,7 @@ namespace Artemis.Core.DataModelExpansions
///
public virtual DataModelPropertyAttribute GetDataModelDescription()
{
- return new DataModelPropertyAttribute {Name = PluginInfo.Name, Description = PluginInfo.Description};
+ return new DataModelPropertyAttribute {Name = Plugin.Info.Name, Description = Plugin.Info.Description};
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/DataModelPluginImplementation.cs b/src/Artemis.Core/Plugins/DataModelPluginFeature.cs
similarity index 81%
rename from src/Artemis.Core/Plugins/DataModelPluginImplementation.cs
rename to src/Artemis.Core/Plugins/DataModelPluginFeature.cs
index 243e3f368..83649847a 100644
--- a/src/Artemis.Core/Plugins/DataModelPluginImplementation.cs
+++ b/src/Artemis.Core/Plugins/DataModelPluginFeature.cs
@@ -4,9 +4,9 @@ using System.Threading.Tasks;
namespace Artemis.Core
{
///
- /// 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
///
- public abstract class DataModelPluginImplementation : PluginImplementation
+ public abstract class DataModelPluginFeature : PluginFeature
{
///
/// Registers a timed update that whenever the plugin is enabled calls the provided at the
@@ -23,11 +23,11 @@ namespace Artemis.Core
{
if (action == null)
throw new ArgumentNullException(nameof(action));
- return new TimedUpdateRegistration(PluginInfo, interval, action);
+ return new TimedUpdateRegistration(this, interval, action);
}
///
- /// Registers a timed update that whenever the plugin is enabled calls the provided at the
+ /// Registers a timed update that whenever the plugin is enabled calls the provided at the
/// provided
///
///
@@ -41,7 +41,7 @@ namespace Artemis.Core
{
if (asyncAction == null)
throw new ArgumentNullException(nameof(asyncAction));
- return new TimedUpdateRegistration(PluginInfo, interval, asyncAction);
+ return new TimedUpdateRegistration(this, interval, asyncAction);
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/DeviceProviders/DeviceProvider.cs b/src/Artemis.Core/Plugins/DeviceProviders/DeviceProvider.cs
index 58edcbd94..c59446c14 100644
--- a/src/Artemis.Core/Plugins/DeviceProviders/DeviceProvider.cs
+++ b/src/Artemis.Core/Plugins/DeviceProviders/DeviceProvider.cs
@@ -10,7 +10,7 @@ namespace Artemis.Core.DeviceProviders
///
/// Allows you to implement and register your own device provider
///
- public abstract class DeviceProvider : PluginImplementation
+ public abstract class DeviceProvider : PluginFeature
{
///
/// Creates a new instance of the class
@@ -50,9 +50,9 @@ namespace Artemis.Core.DeviceProviders
{
// Start from the plugin directory
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)
- e.FinalPath = Path.Combine(PluginInfo.Directory.FullName, e.RelativePath);
+ e.FinalPath = Path.Combine(Plugin.Directory.FullName, e.RelativePath);
IRGBDeviceInfo deviceInfo = ((IRGBDevice) sender).DeviceInfo;
if (e.FileName != null && !File.Exists(e.FinalPath))
diff --git a/src/Artemis.Core/Plugins/IPluginBootstrapper.cs b/src/Artemis.Core/Plugins/IPluginBootstrapper.cs
new file mode 100644
index 000000000..af4b607d7
--- /dev/null
+++ b/src/Artemis.Core/Plugins/IPluginBootstrapper.cs
@@ -0,0 +1,20 @@
+namespace Artemis.Core
+{
+ ///
+ /// An optional entry point for your plugin
+ ///
+ public interface IPluginBootstrapper
+ {
+ ///
+ /// Called when the plugin is activated
+ ///
+ /// The plugin instance of your plugin
+ void Enable(Plugin plugin);
+
+ ///
+ /// Called when the plugin is deactivated or when Artemis shuts down
+ ///
+ /// The plugin instance of your plugin
+ void Disable(Plugin plugin);
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/IPluginConfigurationDialog.cs b/src/Artemis.Core/Plugins/IPluginConfigurationDialog.cs
new file mode 100644
index 000000000..c76d777ca
--- /dev/null
+++ b/src/Artemis.Core/Plugins/IPluginConfigurationDialog.cs
@@ -0,0 +1,7 @@
+namespace Artemis.Core
+{
+ public interface IPluginConfigurationDialog
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/IPluginConfigurationViewModel.cs b/src/Artemis.Core/Plugins/IPluginConfigurationViewModel.cs
new file mode 100644
index 000000000..f2e711397
--- /dev/null
+++ b/src/Artemis.Core/Plugins/IPluginConfigurationViewModel.cs
@@ -0,0 +1,10 @@
+namespace Artemis.Core
+{
+ ///
+ /// Represents a view model for a plugin configuration window
+ ///
+ public interface IPluginConfigurationViewModel
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/LayerBrushes/ILayerBrushConfigurationDialog.cs b/src/Artemis.Core/Plugins/LayerBrushes/ILayerBrushConfigurationDialog.cs
new file mode 100644
index 000000000..c0ad0df9d
--- /dev/null
+++ b/src/Artemis.Core/Plugins/LayerBrushes/ILayerBrushConfigurationDialog.cs
@@ -0,0 +1,9 @@
+namespace Artemis.Core.LayerBrushes
+{
+ ///
+ /// Represents the configuration dialog of a layer brush
+ ///
+ public interface ILayerBrushConfigurationDialog
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/LayerBrushes/Internal/BaseLayerBrush.cs b/src/Artemis.Core/Plugins/LayerBrushes/Internal/BaseLayerBrush.cs
index 847d5cd66..fd399e1ad 100644
--- a/src/Artemis.Core/Plugins/LayerBrushes/Internal/BaseLayerBrush.cs
+++ b/src/Artemis.Core/Plugins/LayerBrushes/Internal/BaseLayerBrush.cs
@@ -1,17 +1,15 @@
using System;
-using Artemis.Core.Services;
using SkiaSharp;
-using Stylet;
namespace Artemis.Core.LayerBrushes
{
///
/// For internal use only, please use or or instead
///
- public abstract class BaseLayerBrush : PropertyChangedBase, IDisposable
+ public abstract class BaseLayerBrush : CorePropertyChanged, IDisposable
{
private LayerBrushType _brushType;
- private LayerBrushConfigurationDialog _configurationDialog;
+ private ILayerBrushConfigurationDialog _configurationDialog;
private LayerBrushDescriptor _descriptor;
private Layer _layer;
private bool _supportsTransformation = true;
@@ -37,7 +35,7 @@ namespace Artemis.Core.LayerBrushes
///
/// Gets or sets a configuration dialog complementing the regular properties
///
- public LayerBrushConfigurationDialog ConfigurationDialog
+ public ILayerBrushConfigurationDialog ConfigurationDialog
{
get => _configurationDialog;
protected set => SetAndNotify(ref _configurationDialog, value);
@@ -53,9 +51,9 @@ namespace Artemis.Core.LayerBrushes
}
///
- /// Gets the plugin info that defined this brush
+ /// Gets the ID of the that provided this effect
///
- public PluginInfo PluginInfo => Descriptor.LayerBrushProvider.PluginInfo;
+ public string ProviderId => Descriptor?.Provider?.Id;
///
/// Gets a reference to the layer property group without knowing it's type
@@ -72,21 +70,11 @@ namespace Artemis.Core.LayerBrushes
protected set
{
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;
}
}
- ///
- public void Dispose()
- {
- DisableLayerBrush();
- BaseProperties.Dispose();
-
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
///
/// Called when the layer brush is activated
///
@@ -112,6 +100,16 @@ namespace Artemis.Core.LayerBrushes
internal virtual void Dispose(bool disposing)
{
}
+
+ ///
+ public void Dispose()
+ {
+ DisableLayerBrush();
+ BaseProperties.Dispose();
+
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
}
///
diff --git a/src/Artemis.Core/Plugins/LayerBrushes/Internal/PropertiesLayerBrush.cs b/src/Artemis.Core/Plugins/LayerBrushes/Internal/PropertiesLayerBrush.cs
index 88c2d3421..86cac67a7 100644
--- a/src/Artemis.Core/Plugins/LayerBrushes/Internal/PropertiesLayerBrush.cs
+++ b/src/Artemis.Core/Plugins/LayerBrushes/Internal/PropertiesLayerBrush.cs
@@ -37,7 +37,7 @@ namespace Artemis.Core.LayerBrushes
Properties = Activator.CreateInstance();
Properties.GroupDescription ??= new PropertyGroupDescriptionAttribute {Name = Descriptor.DisplayName, Description = Descriptor.Description};
Properties.LayerBrush = this;
- Properties.Initialize(Layer, "LayerBrush.", PluginInfo);
+ Properties.Initialize(Layer, "LayerBrush.", Descriptor.Provider);
PropertiesInitialized = true;
EnableLayerBrush();
diff --git a/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushDescriptor.cs b/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushDescriptor.cs
index b319ed448..4b1da7753 100644
--- a/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushDescriptor.cs
+++ b/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushDescriptor.cs
@@ -1,5 +1,4 @@
using System;
-using Artemis.Core.Services;
using Ninject;
namespace Artemis.Core.LayerBrushes
@@ -9,13 +8,13 @@ namespace Artemis.Core.LayerBrushes
///
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;
Description = description;
Icon = icon;
LayerBrushType = layerBrushType;
- LayerBrushProvider = layerBrushProvider;
+ Provider = provider;
}
///
@@ -42,7 +41,7 @@ namespace Artemis.Core.LayerBrushes
///
/// The plugin that provided this
///
- public LayerBrushProvider LayerBrushProvider { get; }
+ public LayerBrushProvider Provider { get; }
///
/// Determines whether the provided references to a brush provided by this descriptor
@@ -51,7 +50,8 @@ namespace Artemis.Core.LayerBrushes
{
if (reference == null)
return false;
- return LayerBrushProvider.PluginInfo.Guid == reference.BrushPluginGuid && LayerBrushType.Name == reference.BrushType;
+
+ return Provider.Id == reference.LayerBrushProviderId && LayerBrushType.Name == reference.BrushType;
}
///
@@ -62,7 +62,7 @@ namespace Artemis.Core.LayerBrushes
if (layer.LayerBrush != null)
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.Descriptor = this;
brush.Initialize();
diff --git a/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushProvider.cs b/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushProvider.cs
index 961873045..a828c8d25 100644
--- a/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushProvider.cs
+++ b/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushProvider.cs
@@ -7,7 +7,7 @@ namespace Artemis.Core.LayerBrushes
///
/// Allows you to create one or more s usable by profile layers.
///
- public abstract class LayerBrushProvider : PluginImplementation
+ public abstract class LayerBrushProvider : PluginFeature
{
private readonly List _layerBrushDescriptors;
@@ -39,7 +39,7 @@ namespace Artemis.Core.LayerBrushes
protected void RegisterLayerBrushDescriptor(string displayName, string description, string icon) where T : BaseLayerBrush
{
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);
_layerBrushDescriptors.Add(descriptor);
diff --git a/src/Artemis.Core/Plugins/LayerEffects/IEffectConfigurationViewModel.cs b/src/Artemis.Core/Plugins/LayerEffects/IEffectConfigurationViewModel.cs
new file mode 100644
index 000000000..33aa630e9
--- /dev/null
+++ b/src/Artemis.Core/Plugins/LayerEffects/IEffectConfigurationViewModel.cs
@@ -0,0 +1,6 @@
+namespace Artemis.Core.LayerEffects
+{
+ public interface IEffectConfigurationViewModel
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/LayerEffects/ILayerEffectConfigurationDialog.cs b/src/Artemis.Core/Plugins/LayerEffects/ILayerEffectConfigurationDialog.cs
new file mode 100644
index 000000000..bafe13a1d
--- /dev/null
+++ b/src/Artemis.Core/Plugins/LayerEffects/ILayerEffectConfigurationDialog.cs
@@ -0,0 +1,6 @@
+namespace Artemis.Core.LayerEffects
+{
+ public interface ILayerEffectConfigurationDialog
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs b/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs
index 7e5778301..126a1e700 100644
--- a/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs
+++ b/src/Artemis.Core/Plugins/LayerEffects/Internal/BaseLayerEffect.cs
@@ -1,16 +1,15 @@
using System;
using Artemis.Core.Services;
using SkiaSharp;
-using Stylet;
namespace Artemis.Core.LayerEffects
{
///
/// For internal use only, please use instead
///
- public abstract class BaseLayerEffect : PropertyChangedBase, IDisposable
+ public abstract class BaseLayerEffect : CorePropertyChanged, IDisposable
{
- private LayerEffectConfigurationDialog _configurationDialog;
+ private ILayerEffectConfigurationDialog _configurationDialog;
private LayerEffectDescriptor _descriptor;
private bool _enabled;
private Guid _entityId;
@@ -77,7 +76,7 @@ namespace Artemis.Core.LayerEffects
///
/// Gets the that registered this effect
///
- public LayerEffectDescriptor Descriptor
+ public LayerEffectDescriptor? Descriptor
{
get => _descriptor;
internal set => SetAndNotify(ref _descriptor, value);
@@ -86,16 +85,16 @@ namespace Artemis.Core.LayerEffects
///
/// Gets or sets a configuration dialog complementing the regular properties
///
- public LayerEffectConfigurationDialog ConfigurationDialog
+ public ILayerEffectConfigurationDialog ConfigurationDialog
{
get => _configurationDialog;
protected set => SetAndNotify(ref _configurationDialog, value);
}
///
- /// Gets the plugin info that defined this effect
+ /// Gets the ID of the that provided this effect
///
- public PluginInfo PluginInfo => Descriptor.LayerEffectProvider?.PluginInfo;
+ public string ProviderId => Descriptor?.Provider?.Id;
///
/// Gets a reference to the layer property group without knowing it's type
diff --git a/src/Artemis.Core/Plugins/LayerEffects/LayerEffect.cs b/src/Artemis.Core/Plugins/LayerEffects/LayerEffect.cs
index 180e5b1a5..75bcce09e 100644
--- a/src/Artemis.Core/Plugins/LayerEffects/LayerEffect.cs
+++ b/src/Artemis.Core/Plugins/LayerEffects/LayerEffect.cs
@@ -37,7 +37,7 @@ namespace Artemis.Core.LayerEffects
{
Properties = Activator.CreateInstance();
Properties.LayerEffect = this;
- Properties.Initialize(ProfileElement, PropertyRootPath, PluginInfo);
+ Properties.Initialize(ProfileElement, PropertyRootPath, Descriptor.Provider);
PropertiesInitialized = true;
EnableLayerEffect();
diff --git a/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs b/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs
index 97f27da49..33fafb542 100644
--- a/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs
+++ b/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs
@@ -1,7 +1,6 @@
using System;
using System.Linq;
using Artemis.Core.LayerEffects.Placeholder;
-using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile;
using Ninject;
@@ -12,13 +11,13 @@ namespace Artemis.Core.LayerEffects
///
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;
Description = description;
Icon = icon;
LayerEffectType = layerEffectType;
- LayerEffectProvider = layerEffectProvider;
+ Provider = provider;
}
///
@@ -45,12 +44,12 @@ namespace Artemis.Core.LayerEffects
///
/// The plugin that provided this
///
- public LayerEffectProvider LayerEffectProvider { get; }
+ public LayerEffectProvider? Provider { get; }
///
/// Gets the GUID this descriptor is acting as a placeholder for. If null, this descriptor is not a placeholder
///
- public Guid? PlaceholderFor { get; internal set; }
+ public string? PlaceholderFor { get; internal set; }
///
/// Creates an instance of the described effect and applies it to the render element
@@ -67,7 +66,10 @@ namespace Artemis.Core.LayerEffects
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.EntityId = entity.Id;
effect.Order = entity.Order;
@@ -83,7 +85,7 @@ namespace Artemis.Core.LayerEffects
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();
renderElement.ActivateLayerEffect(effect);
}
diff --git a/src/Artemis.Core/Plugins/LayerEffects/LayerEffectProvider.cs b/src/Artemis.Core/Plugins/LayerEffects/LayerEffectProvider.cs
index 4f60aeac1..b6b68df7a 100644
--- a/src/Artemis.Core/Plugins/LayerEffects/LayerEffectProvider.cs
+++ b/src/Artemis.Core/Plugins/LayerEffects/LayerEffectProvider.cs
@@ -7,7 +7,7 @@ namespace Artemis.Core.LayerEffects
///
/// Allows you to register one or more s usable by profile layers.
///
- public abstract class LayerEffectProvider : PluginImplementation
+ public abstract class LayerEffectProvider : PluginFeature
{
private readonly List _layerEffectDescriptors;
@@ -39,7 +39,7 @@ namespace Artemis.Core.LayerEffects
protected void RegisterLayerEffectDescriptor(string displayName, string description, string icon) where T : BaseLayerEffect
{
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);
_layerEffectDescriptors.Add(descriptor);
diff --git a/src/Artemis.Core/Plugins/LayerEffects/Placeholder/PlaceholderLayerEffect.cs b/src/Artemis.Core/Plugins/LayerEffects/Placeholder/PlaceholderLayerEffect.cs
index 6447679d0..620425a62 100644
--- a/src/Artemis.Core/Plugins/LayerEffects/Placeholder/PlaceholderLayerEffect.cs
+++ b/src/Artemis.Core/Plugins/LayerEffects/Placeholder/PlaceholderLayerEffect.cs
@@ -1,5 +1,4 @@
-using System;
-using Artemis.Storage.Entities.Profile;
+using Artemis.Storage.Entities.Profile;
using SkiaSharp;
namespace Artemis.Core.LayerEffects.Placeholder
@@ -9,7 +8,7 @@ namespace Artemis.Core.LayerEffects.Placeholder
///
internal class PlaceholderLayerEffect : LayerEffect
{
- internal PlaceholderLayerEffect(LayerEffectEntity originalEntity, Guid placeholderFor)
+ internal PlaceholderLayerEffect(LayerEffectEntity originalEntity, string placeholderFor)
{
OriginalEntity = originalEntity;
PlaceholderFor = placeholderFor;
@@ -21,8 +20,9 @@ namespace Artemis.Core.LayerEffects.Placeholder
HasBeenRenamed = OriginalEntity.HasBeenRenamed;
}
+ public string PlaceholderFor { get; }
+
internal LayerEffectEntity OriginalEntity { get; }
- public Guid PlaceholderFor { get; }
///
public override void EnableLayerEffect()
@@ -56,7 +56,7 @@ namespace Artemis.Core.LayerEffects.Placeholder
}
///
- /// This is in place so that the UI has something to show
+ /// This is in place so that the UI has something to show
///
internal class PlaceholderProperties : LayerPropertyGroup
{
diff --git a/src/Artemis.Core/Plugins/LayerEffects/Placeholder/PlaceholderLayerEffectDescriptor.cs b/src/Artemis.Core/Plugins/LayerEffects/Placeholder/PlaceholderLayerEffectDescriptor.cs
index eec2835fb..762c187d6 100644
--- a/src/Artemis.Core/Plugins/LayerEffects/Placeholder/PlaceholderLayerEffectDescriptor.cs
+++ b/src/Artemis.Core/Plugins/LayerEffects/Placeholder/PlaceholderLayerEffectDescriptor.cs
@@ -1,14 +1,12 @@
-using System;
-
-namespace Artemis.Core.LayerEffects.Placeholder
+namespace Artemis.Core.LayerEffects.Placeholder
{
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)
{
- PlaceholderFor = missingPluginGuid
+ PlaceholderFor = missingProviderId
};
return descriptor;
diff --git a/src/Artemis.Core/Plugins/Modules/IModuleViewModel.cs b/src/Artemis.Core/Plugins/Modules/IModuleViewModel.cs
new file mode 100644
index 000000000..861336edc
--- /dev/null
+++ b/src/Artemis.Core/Plugins/Modules/IModuleViewModel.cs
@@ -0,0 +1,10 @@
+namespace Artemis.Core.Modules
+{
+ ///
+ /// The base class for any view model that belongs to a module
+ ///
+ public interface IModuleViewModel
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/Modules/Module.cs b/src/Artemis.Core/Plugins/Modules/Module.cs
index 1d6364287..8c3c3ee45 100644
--- a/src/Artemis.Core/Plugins/Modules/Module.cs
+++ b/src/Artemis.Core/Plugins/Modules/Module.cs
@@ -42,13 +42,13 @@ namespace Artemis.Core.Modules
///
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()
{
DataModel = Activator.CreateInstance();
- DataModel.Implementation = PluginInfo;
+ DataModel.Feature = this;
DataModel.DataModelDescription = GetDataModelDescription();
base.InternalEnable();
}
@@ -64,7 +64,7 @@ namespace Artemis.Core.Modules
///
/// Allows you to add support for new games/applications
///
- public abstract class Module : DataModelPluginImplementation
+ public abstract class Module : DataModelPluginFeature
{
///
/// The modules display name that's shown in the menu
@@ -236,7 +236,7 @@ namespace Artemis.Core.Modules
if (Entity == null)
Entity = new ModuleSettingsEntity();
- Entity.PluginGuid = PluginInfo.Guid;
+ Entity.ModuleId = Id;
Entity.PriorityCategory = (int) PriorityCategory;
Entity.Priority = Priority;
}
diff --git a/src/Artemis.Core/Plugins/Modules/ModuleTab.cs b/src/Artemis.Core/Plugins/Modules/ModuleTab.cs
index 7c868b8bd..1c017964c 100644
--- a/src/Artemis.Core/Plugins/Modules/ModuleTab.cs
+++ b/src/Artemis.Core/Plugins/Modules/ModuleTab.cs
@@ -3,7 +3,7 @@
namespace Artemis.Core.Modules
{
///
- public class ModuleTab : ModuleTab where T : ModuleViewModel
+ public class ModuleTab : ModuleTab where T : IModuleViewModel
{
///
/// Initializes a new instance of the class
diff --git a/src/Artemis.Core/Plugins/Modules/ProfileModule.cs b/src/Artemis.Core/Plugins/Modules/ProfileModule.cs
index 8657314fb..90e04a005 100644
--- a/src/Artemis.Core/Plugins/Modules/ProfileModule.cs
+++ b/src/Artemis.Core/Plugins/Modules/ProfileModule.cs
@@ -46,7 +46,7 @@ namespace Artemis.Core.Modules
///
public virtual DataModelPropertyAttribute GetDataModelDescription()
{
- return new DataModelPropertyAttribute {Name = PluginInfo.Name, Description = PluginInfo.Description};
+ return new DataModelPropertyAttribute {Name = Plugin.Info.Name, Description = Plugin.Info.Description};
}
///
@@ -74,7 +74,7 @@ namespace Artemis.Core.Modules
internal override void InternalEnable()
{
DataModel = Activator.CreateInstance();
- DataModel.Implementation = PluginInfo;
+ DataModel.Feature = this;
DataModel.DataModelDescription = GetDataModelDescription();
base.InternalEnable();
}
@@ -184,7 +184,7 @@ namespace Artemis.Core.Modules
internal async Task ChangeActiveProfileAnimated(Profile profile, ArtemisSurface surface)
{
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)
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)
{
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)
throw new ArtemisCoreException("Cannot activate a profile on a deactivated module");
diff --git a/src/Artemis.Core/Plugins/Plugin.cs b/src/Artemis.Core/Plugins/Plugin.cs
index ec42bcdeb..481fa80f0 100644
--- a/src/Artemis.Core/Plugins/Plugin.cs
+++ b/src/Artemis.Core/Plugins/Plugin.cs
@@ -7,16 +7,15 @@ using System.Reflection;
using Artemis.Storage.Entities.Plugins;
using McMaster.NETCore.Plugins;
using Ninject;
-using Stylet;
namespace Artemis.Core
{
///
/// Represents a plugin
///
- public class Plugin : PropertyChangedBase, IDisposable
+ public class Plugin : CorePropertyChanged, IDisposable
{
- private readonly List _implementations;
+ private readonly List _features;
private bool _isEnabled;
@@ -25,7 +24,7 @@ namespace Artemis.Core
Info = info;
Directory = directory;
- _implementations = new List();
+ _features = new List();
}
///
@@ -46,8 +45,8 @@ namespace Artemis.Core
///
/// Gets or sets a configuration dialog for this plugin that is accessible in the UI under Settings > Plugins
///
- public PluginConfigurationDialog? ConfigurationDialog { get; protected set; }
-
+ public IPluginConfigurationDialog? ConfigurationDialog { get; set; }
+
///
/// Indicates whether the user enabled the plugin or not
///
@@ -58,19 +57,24 @@ namespace Artemis.Core
}
///
- /// Gets a read-only collection of all implementations this plugin provides
+ /// Gets a read-only collection of all features this plugin provides
///
- public ReadOnlyCollection Implementations => _implementations.AsReadOnly();
+ public ReadOnlyCollection Features => _features.AsReadOnly();
///
/// The assembly the plugin code lives in
///
- internal Assembly? Assembly { get; set; }
+ public Assembly? Assembly { get; internal set; }
+
+ ///
+ /// Gets the plugin bootstrapper
+ ///
+ public IPluginBootstrapper? Bootstrapper { get; internal set; }
///
/// The Ninject kernel of the plugin
///
- internal IKernel? Kernel { get; set; }
+ public IKernel? Kernel { get; internal set; }
///
/// The PluginLoader backing this plugin
@@ -80,7 +84,7 @@ namespace Artemis.Core
///
/// The entity representing the plugin
///
- internal PluginEntity? Entity { get; set; }
+ internal PluginEntity Entity { get; set; }
///
/// Resolves the relative path provided in the parameter to an absolute path
@@ -92,25 +96,15 @@ namespace Artemis.Core
return path == null ? null : Path.Combine(Directory.FullName, path);
}
- internal void ApplyToEntity()
+ ///
+ /// Looks up the instance of the feature of type
+ /// Note: This method only returns instances of enabled features
+ ///
+ /// The type of feature to find
+ /// If found, the instance of the feature
+ public T? GetFeature() where T : PluginFeature
{
- Entity.Id = Guid;
- 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");
+ return _features.FirstOrDefault(i => i is T) as T;
}
///
@@ -119,13 +113,118 @@ namespace Artemis.Core
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()
{
- foreach (PluginImplementation pluginImplementation in Implementations)
- pluginImplementation.Dispose();
+ foreach (PluginFeature feature in Features)
+ feature.Dispose();
Kernel?.Dispose();
PluginLoader?.Dispose();
+
+ _features.Clear();
+ SetEnabled(false);
}
+
+ #region Events
+
+ ///
+ /// Occurs when the plugin is enabled
+ ///
+ public event EventHandler? Enabled;
+
+ ///
+ /// Occurs when the plugin is disabled
+ ///
+ public event EventHandler? Disabled;
+
+ ///
+ /// Occurs when an feature is loaded and added to the plugin
+ ///
+ public event EventHandler? FeatureAdded;
+
+ ///
+ /// Occurs when an feature is disabled and removed from the plugin
+ ///
+ public event EventHandler? FeatureRemoved;
+
+ ///
+ /// Invokes the Enabled event
+ ///
+ protected virtual void OnEnabled()
+ {
+ Enabled?.Invoke(this, EventArgs.Empty);
+ }
+
+ ///
+ /// Invokes the Disabled event
+ ///
+ protected virtual void OnDisabled()
+ {
+ Disabled?.Invoke(this, EventArgs.Empty);
+ }
+
+ ///
+ /// Invokes the FeatureAdded event
+ ///
+ protected virtual void OnFeatureAdded(PluginFeatureEventArgs e)
+ {
+ FeatureAdded?.Invoke(this, e);
+ }
+
+ ///
+ /// Invokes the FeatureRemoved event
+ ///
+ protected virtual void OnFeatureRemoved(PluginFeatureEventArgs e)
+ {
+ FeatureRemoved?.Invoke(this, e);
+ }
+
+ #endregion
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/PluginImplementation.cs b/src/Artemis.Core/Plugins/PluginFeature.cs
similarity index 76%
rename from src/Artemis.Core/Plugins/PluginImplementation.cs
rename to src/Artemis.Core/Plugins/PluginFeature.cs
index 2b3524326..0b3f4a152 100644
--- a/src/Artemis.Core/Plugins/PluginImplementation.cs
+++ b/src/Artemis.Core/Plugins/PluginFeature.cs
@@ -1,24 +1,22 @@
using System;
using System.IO;
-using System.Threading;
using System.Threading.Tasks;
using Artemis.Storage.Entities.Plugins;
-using Stylet;
namespace Artemis.Core
{
///
- /// Represents an implementation of a certain type provided by a plugin
+ /// Represents an feature of a certain type provided by a plugin
///
- public abstract class PluginImplementation : PropertyChangedBase, IDisposable
+ public abstract class PluginFeature : CorePropertyChanged, IDisposable
{
- private Exception? _loadException;
private bool _isEnabled;
+ private Exception? _loadException;
///
- /// Gets the plugin that provides this implementation
+ /// Gets the plugin that provides this feature
///
- public Plugin? Plugin { get; internal set; }
+ public Plugin Plugin { get; internal set; }
///
/// Gets whether the plugin is enabled
@@ -38,15 +36,20 @@ namespace Artemis.Core
internal set => SetAndNotify(ref _loadException, value);
}
- internal PluginImplementationEntity? Entity { get; set; }
+ ///
+ /// Gets the identifier of this plugin feature
+ ///
+ 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; }
///
- /// Called when the implementation is activated
+ /// Called when the feature is activated
///
public abstract void Enable();
///
- /// Called when the implementation is deactivated or when Artemis shuts down
+ /// Called when the feature is deactivated or when Artemis shuts down
///
public abstract void Disable();
@@ -56,12 +59,12 @@ namespace Artemis.Core
return;
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)
{
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)
{
@@ -72,7 +75,7 @@ namespace Artemis.Core
OnDisabled();
return;
}
-
+
try
{
if (isAutoEnable && GetLockFileCreated())
@@ -89,19 +92,10 @@ namespace Artemis.Core
// 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
- ManualResetEvent wait = new ManualResetEvent(false);
- Thread work = new Thread(() =>
- {
- InternalEnable();
- wait.Set();
- });
- work.Start();
- wait.WaitOne(TimeSpan.FromSeconds(15));
- if (work.IsAlive)
- {
- work.Abort();
+ // This would've been a perfect match for Thread.Abort but that didn't make it into .NET Core
+ Task enableTask = Task.Run(InternalEnable);
+ if (!enableTask.Wait(TimeSpan.FromSeconds(15)))
throw new ArtemisPluginException(Plugin, "Plugin load timeout");
- }
LoadException = null;
OnEnabled();
@@ -144,7 +138,7 @@ namespace Artemis.Core
internal void CreateLockFile()
{
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();
}
@@ -152,7 +146,7 @@ namespace Artemis.Core
internal void DeleteLockFile()
{
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())
File.Delete(Plugin.ResolveRelativePath($"{GetType().FullName}.lock"));
@@ -161,7 +155,7 @@ namespace Artemis.Core
internal bool GetLockFileCreated()
{
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"));
}
@@ -171,17 +165,17 @@ namespace Artemis.Core
#region Events
///
- /// Occurs when the implementation is enabled
+ /// Occurs when the feature is enabled
///
public event EventHandler? Enabled;
///
- /// Occurs when the implementation is disabled
+ /// Occurs when the feature is disabled
///
public event EventHandler? Disabled;
///
- /// Triggers the PluginEnabled event
+ /// Triggers the Enabled event
///
protected virtual void OnEnabled()
{
@@ -189,7 +183,7 @@ namespace Artemis.Core
}
///
- /// Triggers the PluginDisabled event
+ /// Triggers the Disabled event
///
protected virtual void OnDisabled()
{
diff --git a/src/Artemis.Core/Plugins/PluginInfo.cs b/src/Artemis.Core/Plugins/PluginInfo.cs
index def8d63cf..26a3b7e1f 100644
--- a/src/Artemis.Core/Plugins/PluginInfo.cs
+++ b/src/Artemis.Core/Plugins/PluginInfo.cs
@@ -1,6 +1,5 @@
using System;
using Newtonsoft.Json;
-using Stylet;
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
///
[JsonObject(MemberSerialization.OptIn)]
- public class PluginInfo : PropertyChangedBase
+ public class PluginInfo : CorePropertyChanged
{
private string _description;
private Guid _guid;
diff --git a/src/Artemis.Core/Plugins/Settings/PluginSetting.cs b/src/Artemis.Core/Plugins/Settings/PluginSetting.cs
index f3b068f83..d8738dd70 100644
--- a/src/Artemis.Core/Plugins/Settings/PluginSetting.cs
+++ b/src/Artemis.Core/Plugins/Settings/PluginSetting.cs
@@ -2,7 +2,6 @@
using Artemis.Storage.Entities.Plugins;
using Artemis.Storage.Repositories.Interfaces;
using Newtonsoft.Json;
-using Stylet;
namespace Artemis.Core
{
@@ -10,17 +9,18 @@ namespace Artemis.Core
/// Represents a setting tied to a plugin of type
///
/// The value type of the setting
- public class PluginSetting : PropertyChangedBase
+ public class PluginSetting : CorePropertyChanged
{
- // ReSharper disable once NotAccessedField.Local
- private readonly PluginInfo _pluginInfo;
+ // TODO: Why? Should have included that...
+ // ReSharper disable once NotAccessedField.Local
+ private readonly Plugin _plugin;
private readonly IPluginRepository _pluginRepository;
private readonly PluginSettingEntity _pluginSettingEntity;
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;
_pluginSettingEntity = pluginSettingEntity;
@@ -52,7 +52,7 @@ namespace Artemis.Core
_value = value;
OnSettingChanged();
- NotifyOfPropertyChange(nameof(Value));
+ OnPropertyChanged(nameof(Value));
if (AutoSave)
Save();
diff --git a/src/Artemis.Core/Plugins/Settings/PluginSettings.cs b/src/Artemis.Core/Plugins/Settings/PluginSettings.cs
index f47f50a68..65a176e2c 100644
--- a/src/Artemis.Core/Plugins/Settings/PluginSettings.cs
+++ b/src/Artemis.Core/Plugins/Settings/PluginSettings.cs
@@ -14,17 +14,17 @@ namespace Artemis.Core
private readonly IPluginRepository _pluginRepository;
private readonly Dictionary _settingEntities;
- internal PluginSettings(PluginInfo pluginInfo, IPluginRepository pluginRepository)
+ internal PluginSettings(Plugin plugin, IPluginRepository pluginRepository)
{
- PluginInfo = pluginInfo;
+ Plugin = plugin;
_pluginRepository = pluginRepository;
_settingEntities = new Dictionary();
}
///
- /// Gets the info of the plugin this setting belongs to
+ /// Gets the plugin these settings belong to
///
- public PluginInfo PluginInfo { get; }
+ public Plugin Plugin { get; }
///
/// 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))
return (PluginSetting) _settingEntities[name];
// 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 (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);
}
- PluginSetting pluginSetting = new PluginSetting(PluginInfo, _pluginRepository, settingEntity);
+ PluginSetting pluginSetting = new PluginSetting(Plugin, _pluginRepository, settingEntity);
// 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
diff --git a/src/Artemis.Core/Plugins/TimedUpdateRegistration.cs b/src/Artemis.Core/Plugins/TimedUpdateRegistration.cs
index fd9bceea8..2b5720296 100644
--- a/src/Artemis.Core/Plugins/TimedUpdateRegistration.cs
+++ b/src/Artemis.Core/Plugins/TimedUpdateRegistration.cs
@@ -8,40 +8,41 @@ namespace Artemis.Core
///
/// Represents a registration for a timed plugin update
///
- public class TimedUpdateRegistration
+ public class TimedUpdateRegistration : IDisposable
{
private DateTime _lastEvent;
private Timer _timer;
+ private bool _disposed;
- internal TimedUpdateRegistration(PluginInfo pluginInfo, TimeSpan interval, Action action)
+ internal TimedUpdateRegistration(PluginFeature feature, TimeSpan interval, Action action)
{
- PluginInfo = pluginInfo;
+ Feature = feature;
Interval = interval;
Action = action;
- PluginInfo.Plugin.Enabled += InstanceOnEnabled;
- PluginInfo.Plugin.Disabled += InstanceOnDisabled;
- if (PluginInfo.Plugin.IsEnabled)
+ Feature.Enabled += FeatureOnEnabled;
+ Feature.Disabled += FeatureOnDisabled;
+ if (Feature.IsEnabled)
Start();
}
- internal TimedUpdateRegistration(PluginInfo pluginInfo, TimeSpan interval, Func asyncAction)
+ internal TimedUpdateRegistration(PluginFeature feature, TimeSpan interval, Func asyncAction)
{
- PluginInfo = pluginInfo;
+ Feature = feature;
Interval = interval;
AsyncAction = asyncAction;
-
- PluginInfo.Plugin.Enabled += InstanceOnEnabled;
- PluginInfo.Plugin.Disabled += InstanceOnDisabled;
- if (PluginInfo.Plugin.IsEnabled)
+
+ Feature.Enabled += FeatureOnEnabled;
+ Feature.Disabled += FeatureOnDisabled;
+ if (Feature.IsEnabled)
Start();
}
///
- /// Gets the plugin info of the plugin this registration is associated with
+ /// Gets the plugin feature this registration is associated with
///
- public PluginInfo PluginInfo { get; }
+ public PluginFeature Feature { get; }
///
/// Gets the interval at which the update should occur
@@ -64,10 +65,13 @@ namespace Artemis.Core
///
public void Start()
{
+ if (_disposed)
+ throw new ObjectDisposedException("TimedUpdateRegistration");
+
lock (this)
{
- if (!PluginInfo.Plugin.IsEnabled)
- throw new ArtemisPluginException("Cannot start a timed update for a disabled plugin");
+ if (!Feature.IsEnabled)
+ throw new ArtemisPluginException("Cannot start a timed update for a disabled plugin feature");
if (_timer != null)
return;
@@ -85,6 +89,9 @@ namespace Artemis.Core
///
public void Stop()
{
+ if (_disposed)
+ throw new ObjectDisposedException("TimedUpdateRegistration");
+
lock (this)
{
if (_timer == null)
@@ -99,7 +106,7 @@ namespace Artemis.Core
private void TimerOnElapsed(object sender, ElapsedEventArgs e)
{
- if (!PluginInfo.Plugin.IsEnabled)
+ if (!Feature.IsEnabled)
return;
lock (this)
@@ -108,7 +115,7 @@ namespace Artemis.Core
_lastEvent = DateTime.Now;
// 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;
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();
}
- private void InstanceOnDisabled(object sender, EventArgs e)
+ private void FeatureOnDisabled(object sender, EventArgs e)
{
Stop();
}
+
+ ///
+ public void Dispose()
+ {
+ Stop();
+
+ Feature.Enabled -= FeatureOnEnabled;
+ Feature.Disabled -= FeatureOnDisabled;
+
+ _disposed = true;
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/CoreService.cs b/src/Artemis.Core/Services/CoreService.cs
index 7189d6b98..4bb6ce3e3 100644
--- a/src/Artemis.Core/Services/CoreService.cs
+++ b/src/Artemis.Core/Services/CoreService.cs
@@ -40,7 +40,7 @@ namespace Artemis.Core.Services
IRgbService rgbService, ISurfaceService surfaceService, IProfileService profileService, IModuleService moduleService)
{
Kernel = kernel;
- Constants.CorePluginInfo.Kernel = kernel;
+ Constants.CorePlugin.Kernel = kernel;
_logger = logger;
_pluginManagementService = pluginManagementService;
@@ -133,8 +133,8 @@ namespace Artemis.Core.Services
private void UpdatePluginCache()
{
- _modules = _pluginManagementService.GetPluginsOfType().Where(p => p.IsEnabled).ToList();
- _dataModelExpansions = _pluginManagementService.GetPluginsOfType().Where(p => p.IsEnabled).ToList();
+ _modules = _pluginManagementService.GetFeaturesOfType().Where(p => p.IsEnabled).ToList();
+ _dataModelExpansions = _pluginManagementService.GetFeaturesOfType().Where(p => p.IsEnabled).ToList();
}
private void ConfigureJsonConvert()
diff --git a/src/Artemis.Core/Services/Interfaces/IPluginService.cs b/src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs
similarity index 56%
rename from src/Artemis.Core/Services/Interfaces/IPluginService.cs
rename to src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs
index acbb28b61..233da594f 100644
--- a/src/Artemis.Core/Services/Interfaces/IPluginService.cs
+++ b/src/Artemis.Core/Services/Interfaces/IPluginManagementService.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
+using Artemis.Core.DeviceProviders;
using RGB.NET.Core;
namespace Artemis.Core.Services
@@ -33,69 +34,77 @@ namespace Artemis.Core.Services
void UnloadPlugins();
///
- /// Loads the plugin defined in the provided
+ /// Loads the plugin located in the provided
///
- /// The plugin info defining the plugin to load
- void LoadPlugin(DirectoryInfo pluginInfo);
+ /// The directory where the plugin is located
+ Plugin LoadPlugin(DirectoryInfo directory);
///
- /// Unloads the plugin defined in the provided
+ /// Enables the provided
///
- /// The plugin info defining the plugin to unload
- void UnloadPlugin(PluginInfo pluginInfo);
+ /// The plugin to enable
+ void EnablePlugin(Plugin plugin, bool ignorePluginLock = false);
///
- /// Enables the provided plugin
+ /// Unloads the provided
///
- ///
+ /// The plugin to unload
+ void UnloadPlugin(Plugin plugin);
+
+ ///
+ /// Disables the provided
+ ///
+ /// The plugin to disable
+ void DisablePlugin(Plugin plugin);
+
+ ///
+ /// Enables the provided plugin feature
+ ///
+ ///
/// If true, fails if there is a lock file present
- void EnablePluginImplementation(PluginImplementation pluginImplementation, bool isAutoEnable = false);
+ void EnablePluginFeature(PluginFeature pluginFeature, bool isAutoEnable = false);
///
- /// Disables the provided plugin
+ /// Disables the provided plugin feature
///
- ///
- void DisablePluginImplementation(PluginImplementation pluginImplementation);
-
- ///
- /// Finds the plugin info related to the plugin
- ///
- /// The plugin you want to find the plugin info for
- /// The plugins PluginInfo
- PluginInfo GetPluginInfo(PluginImplementation pluginImplementation);
+ ///
+ void DisablePluginFeature(PluginFeature pluginFeature);
///
/// Gets the plugin info of all loaded plugins
///
/// A list containing all the plugin info
- List GetAllPluginInfo();
+ List GetAllPlugins();
///
- /// Finds all enabled instances of
+ /// Finds all enabled instances of
///
- /// Either or a plugin type implementing
- /// Returns a list of plugin instances of
- List GetPluginsOfType() where T : PluginImplementation;
+ ///
+ /// Either or a plugin type implementing
+ ///
+ ///
+ /// Returns a list of feature instances of
+ List GetFeaturesOfType() where T : PluginFeature;
///
/// Gets the plugin that provided the specified assembly
///
///
///
- PluginImplementation GetPluginByAssembly(Assembly assembly);
+ Plugin GetPluginByAssembly(Assembly assembly);
+
+ ///
+ /// Returns the plugin info of the current call stack
+ ///
+ /// If the current call stack contains a plugin, the plugin. Otherwise null
+ Plugin? GetCallingPlugin();
///
/// Gets the plugin that defined the specified device
///
///
///
- PluginImplementation GetPluginByDevice(IRGBDevice device);
-
- ///
- /// Returns the plugin info of the current call stack
- ///
- /// If the current call stack contains a plugin, the plugin. Otherwise null
- PluginImplementation GetCallingPlugin();
+ DeviceProvider GetDeviceProviderByDevice(IRGBDevice device);
#region Events
@@ -134,6 +143,26 @@ namespace Artemis.Core.Services
///
event EventHandler PluginDisabled;
+ ///
+ /// Occurs when a plugin feature is being enabled
+ ///
+ public event EventHandler PluginFeatureEnabling;
+
+ ///
+ /// Occurs when a plugin feature has been enabled
+ ///
+ public event EventHandler PluginFeatureEnabled;
+
+ ///
+ /// Occurs when a plugin feature could not be enabled
+ ///
+ public event EventHandler PluginFeatureEnableFailed;
+
+ ///
+ /// Occurs when a plugin feature has been disabled
+ ///
+ public event EventHandler PluginFeatureDisabled;
+
#endregion
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/ModuleService.cs b/src/Artemis.Core/Services/ModuleService.cs
index a08e06119..97ccf53ce 100644
--- a/src/Artemis.Core/Services/ModuleService.cs
+++ b/src/Artemis.Core/Services/ModuleService.cs
@@ -26,16 +26,129 @@ namespace Artemis.Core.Services
_moduleRepository = moduleRepository;
_pluginManagementService = pluginManagementService;
_profileService = profileService;
- _pluginManagementService.PluginEnabled += PluginManagementServiceOnPluginManagementEnabled;
+ _pluginManagementService.PluginFeatureEnabled += OnPluginFeatureEnabled;
Timer activationUpdateTimer = new Timer(2000);
activationUpdateTimer.Start();
activationUpdateTimer.Elapsed += ActivationUpdateTimerOnElapsed;
- foreach (Module module in _pluginManagementService.GetPluginsOfType())
+ foreach (Module module in _pluginManagementService.GetFeaturesOfType())
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 async Task SetActiveModuleOverride(Module overrideModule)
@@ -46,17 +159,19 @@ namespace Artemis.Core.Services
if (ActiveModuleOverride == overrideModule)
return;
-
+
if (overrideModule != null)
{
OverrideActivate(overrideModule);
_logger.Information($"Setting active module override to {overrideModule.DisplayName}");
}
else
+ {
_logger.Information("Clearing active module override");
+ }
// Always deactivate all other modules whenever override is called
- List modules = _pluginManagementService.GetPluginsOfType().ToList();
+ List modules = _pluginManagementService.GetFeaturesOfType().ToList();
foreach (Module module in modules.Where(m => m != overrideModule))
OverrideDeactivate(module, overrideModule != null);
@@ -83,13 +198,8 @@ namespace Artemis.Core.Services
// the principle is different for this service but not for the module
bool shouldBeActivated = ActiveModuleOverride.EvaluateActivationRequirements();
if (shouldBeActivated && ActiveModuleOverride.IsActivatedOverride)
- {
ActiveModuleOverride.Reactivate(true, false);
- }
- else if (!shouldBeActivated && !ActiveModuleOverride.IsActivatedOverride)
- {
- ActiveModuleOverride.Reactivate(false, true);
- }
+ else if (!shouldBeActivated && !ActiveModuleOverride.IsActivatedOverride) ActiveModuleOverride.Reactivate(false, true);
return;
}
@@ -97,10 +207,9 @@ namespace Artemis.Core.Services
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
- List modules = _pluginManagementService.GetPluginsOfType().ToList();
+ List modules = _pluginManagementService.GetFeaturesOfType().ToList();
List tasks = new List();
foreach (Module module in modules)
- {
lock (module)
{
bool shouldBeActivated = module.EvaluateActivationRequirements() && module.IsEnabled;
@@ -109,7 +218,6 @@ namespace Artemis.Core.Services
else if (!shouldBeActivated && module.IsActivated)
tasks.Add(DeactivateModule(module));
}
- }
await Task.WhenAll(tasks);
@@ -128,7 +236,12 @@ namespace Artemis.Core.Services
if (module.PriorityCategory == category && module.Priority == priority)
return;
- List modules = _pluginManagementService.GetPluginsOfType().Where(m => m.PriorityCategory == category).OrderBy(m => m.Priority).ToList();
+ List modules = _pluginManagementService
+ .GetFeaturesOfType()
+ .Where(m => m.PriorityCategory == category)
+ .OrderBy(m => m.Priority)
+ .ToList();
+
if (modules.Contains(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);
- }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/PluginService.cs b/src/Artemis.Core/Services/PluginManagementService.cs
similarity index 56%
rename from src/Artemis.Core/Services/PluginService.cs
rename to src/Artemis.Core/Services/PluginManagementService.cs
index 17b511c51..d64ad5d41 100644
--- a/src/Artemis.Core/Services/PluginService.cs
+++ b/src/Artemis.Core/Services/PluginManagementService.cs
@@ -41,6 +41,21 @@ namespace Artemis.Core.Services
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; }
#region Built in plugins
@@ -72,7 +87,9 @@ namespace Artemis.Core.Services
// Find the matching plugin in the plugin folder
DirectoryInfo? match = pluginDirectory.EnumerateDirectories().FirstOrDefault(d => d.Name == Path.GetFileNameWithoutExtension(zipFile.Name));
if (match == null)
+ {
CopyBuiltInPlugin(zipFile, archive);
+ }
else
{
string metadataFile = Path.Combine(match.FullName, "plugin.json");
@@ -105,6 +122,48 @@ namespace Artemis.Core.Services
#endregion
+ public List GetAllPlugins()
+ {
+ return new List(_plugins);
+ }
+
+ public List GetFeaturesOfType() where T : PluginFeature
+ {
+ return _plugins.Where(p => p.IsEnabled).SelectMany(p => p.Features.Where(i => i.IsEnabled && i is T)).Cast().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().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
public void LoadPlugins(bool ignorePluginLock)
@@ -125,7 +184,8 @@ namespace Artemis.Core.Services
{
try
{
- LoadPlugin(subDirectory);
+ Plugin plugin = LoadPlugin(subDirectory);
+ EnablePlugin(plugin, ignorePluginLock);
}
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;
}
}
@@ -165,29 +209,32 @@ namespace Artemis.Core.Services
}
}
- public void LoadPlugin(DirectoryInfo pluginDirectory)
+ public Plugin LoadPlugin(DirectoryInfo directory)
{
lock (_plugins)
{
- _logger.Debug("Loading plugin from {directory}", pluginDirectory.FullName);
+ _logger.Debug("Loading plugin from {directory}", directory.FullName);
// Load the metadata
- string metadataFile = Path.Combine(pluginDirectory.FullName, "plugin.json");
+ string metadataFile = Path.Combine(directory.FullName, "plugin.json");
if (!File.Exists(metadataFile))
_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 pluginInfo = JsonConvert.DeserializeObject(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
if (_plugins.Any(p => p.Guid == pluginInfo.Guid))
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));
// 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
string? mainFile = plugin.ResolveRelativePath(plugin.Info.Main);
@@ -210,55 +257,94 @@ namespace Artemis.Core.Services
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 implementationTypes;
- try
- {
- implementationTypes = plugin.Assembly.GetTypes().Where(t => typeof(PluginImplementation).IsAssignableFrom(t)).ToList();
- }
- catch (ReflectionTypeLoadException e)
- {
- throw new ArtemisPluginException(plugin, "Failed to initialize the plugin assembly", new AggregateException(e.LoaderExceptions));
- }
-
- // Create the Ninject child kernel and load the module
- plugin.Kernel = new ChildKernel(_kernel);
- plugin.Kernel.Load(new PluginModule(pluginInfo));
-
- if (!implementationTypes.Any())
- _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
- foreach (Type implementationType in implementationTypes)
- {
- try
- {
- PluginImplementation instance = (PluginImplementation)plugin.Kernel.Get(implementationType);
- plugin.AddImplementation(instance);
- }
- catch (Exception e)
- {
- throw new ArtemisPluginException(plugin, "Failed to load instantiate implementation", e);
- }
- }
+ List bootstrappers = plugin.Assembly.GetTypes().Where(t => typeof(IPluginBootstrapper).IsAssignableFrom(t)).ToList();
+ 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().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 featureTypes;
+ try
+ {
+ featureTypes = plugin.Assembly.GetTypes().Where(t => typeof(PluginFeature).IsAssignableFrom(t)).ToList();
+ }
+ catch (ReflectionTypeLoadException e)
+ {
+ throw new ArtemisPluginException(plugin, "Failed to initialize the plugin assembly", new AggregateException(e.LoaderExceptions));
+ }
+
+ if (!featureTypes.Any())
+ _logger.Warning("Plugin {plugin} contains no features", plugin);
+
+ // Create instances of each feature 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
+ foreach (Type featureType in featureTypes)
+ {
+ try
+ {
+ // Include Plugin as a parameter for the PluginSettingsProvider
+ 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)
+ {
+ throw new ArtemisPluginException(plugin, "Failed to load instantiate feature", e);
+ }
+ }
+
+ // Activate plugins after they are all loaded
+ 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)
{
lock (_plugins)
{
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
{
@@ -267,38 +353,59 @@ namespace Artemis.Core.Services
plugin.Dispose();
_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
+ #region Features
- #region Implementations
-
- public void EnablePluginImplementation(PluginImplementation pluginImplementation, bool isAutoEnable = false)
+ public void EnablePluginFeature(PluginFeature pluginFeature, 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)
{
+ OnPluginFeatureEnabling(new PluginFeatureEventArgs(pluginFeature));
try
{
// 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;
- pluginImplementation.PluginInfo.ApplyToEntity();
- _pluginRepository.SavePlugin(pluginImplementation.PluginInfo.PluginEntity);
+ pluginFeature.Entity.IsEnabled = true;
+ SavePlugin(pluginFeature.Plugin);
return;
}
- pluginImplementation.SetEnabled(true, isAutoEnable);
+ pluginFeature.SetEnabled(true, isAutoEnable);
+ pluginFeature.Entity.IsEnabled = true;
}
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;
}
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
// not affect the user's settings
if (isAutoEnable)
- pluginImplementation.PluginInfo.IsEnabled = true;
+ pluginFeature.Entity.IsEnabled = true;
- pluginImplementation.PluginInfo.ApplyToEntity();
- _pluginRepository.SavePlugin(pluginImplementation.PluginInfo.PluginEntity);
+ SavePlugin(pluginFeature.Plugin);
- if (pluginImplementation.PluginInfo.IsEnabled)
- _logger.Debug("Successfully enabled plugin {pluginInfo}", pluginImplementation.PluginInfo);
+ if (pluginFeature.IsEnabled)
+ {
+ _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 DisablePluginImplementation(PluginImplementation pluginImplementation)
+ public void DisablePluginFeature(PluginFeature pluginFeature)
{
lock (_plugins)
{
- _logger.Debug("Disabling plugin {pluginInfo}", pluginImplementation.PluginInfo);
-
- // Device providers cannot be disabled at runtime simply queue a disable for next restart
- if (pluginImplementation is DeviceProvider)
+ try
{
- // Don't call SetEnabled(false) but simply update enabled state and save it
- pluginImplementation.PluginInfo.IsEnabled = false;
- pluginImplementation.PluginInfo.ApplyToEntity();
- _pluginRepository.SavePlugin(pluginImplementation.PluginInfo.PluginEntity);
- return;
+ _logger.Debug("Disabling plugin feature {feature} - {plugin}", pluginFeature, pluginFeature.Plugin);
+
+ // Device providers cannot be disabled at runtime simply queue a disable for next restart
+ if (pluginFeature is DeviceProvider)
+ {
+ // Don't call SetEnabled(false) but simply update enabled state and save it
+ pluginFeature.Entity.IsEnabled = false;
+ SavePlugin(pluginFeature.Plugin);
+ return;
+ }
+
+ pluginFeature.SetEnabled(false);
}
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
+ finally
+ {
+ pluginFeature.Entity.IsEnabled = false;
+ SavePlugin(pluginFeature.Plugin);
- pluginImplementation.SetEnabled(false);
- pluginImplementation.PluginInfo.ApplyToEntity();
- _pluginRepository.SavePlugin(pluginImplementation.PluginInfo.PluginEntity);
-
- _logger.Debug("Successfully disabled plugin {pluginInfo}", pluginImplementation.PluginInfo);
+ if (!pluginFeature.IsEnabled)
+ {
+ _logger.Debug("Successfully disabled plugin feature {feature} - {plugin}", pluginFeature, pluginFeature.Plugin);
+ OnPluginFeatureDisabled(new PluginFeatureEventArgs(pluginFeature));
+ }
+ }
}
-
- OnPluginDisabled(new PluginEventArgs(pluginImplementation.PluginInfo));
}
#endregion
+ #region Storage
- public PluginInfo GetPluginInfo(PluginImplementation pluginImplementation)
+ private void SavePlugin(Plugin plugin)
{
- return _plugins.FirstOrDefault(p => p.Plugin == pluginImplementation);
- }
-
- public List GetAllPluginInfo()
- {
- return new List(_plugins);
- }
-
- public List GetPluginsOfType() where T : PluginImplementation
- {
- return _plugins.Where(p => p.IsEnabled && p.Plugin is T).Select(p => (T) p.Plugin).ToList();
- }
-
- public PluginImplementation GetPluginByAssembly(Assembly assembly)
- {
- return _plugins.FirstOrDefault(p => p.Assembly == assembly)?.Plugin;
- }
-
- public PluginImplementation GetPluginByDevice(IRGBDevice rgbDevice)
- {
- return GetPluginsOfType().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)
+ foreach (PluginFeature pluginFeature in plugin.Features)
{
- Assembly assembly = stackFrame.GetMethod().DeclaringType.Assembly;
- PluginImplementation pluginImplementation = GetPluginByAssembly(assembly);
- if (pluginImplementation != null)
- return pluginImplementation;
+ if (plugin.Entity.Features.All(i => i.Type != pluginFeature.GetType().FullName))
+ plugin.Entity.Features.Add(pluginFeature.Entity);
}
- return null;
+ _pluginRepository.SavePlugin(plugin.Entity);
}
- public void Dispose()
+ private PluginFeatureEntity GetOrCreateFeatureEntity(PluginFeature feature)
{
- UnloadPlugins();
+ return feature.Plugin.Entity.Features.FirstOrDefault(i => i.Type == feature.GetType().FullName) ??
+ new PluginFeatureEntity {IsEnabled = true, Type = feature.GetType().FullName};
}
- 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();
- }
+ #endregion
#region Events
@@ -419,8 +501,10 @@ namespace Artemis.Core.Services
public event EventHandler PluginEnabled;
public event EventHandler PluginDisabled;
- public event EventHandler PluginImplementationEnabled;
- public event EventHandler PluginImplementationDisabled;
+ public event EventHandler PluginFeatureEnabling;
+ public event EventHandler PluginFeatureEnabled;
+ public event EventHandler PluginFeatureDisabled;
+ public event EventHandler PluginFeatureEnableFailed;
protected virtual void OnCopyingBuildInPlugins()
{
@@ -457,14 +541,24 @@ namespace Artemis.Core.Services
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
diff --git a/src/Artemis.Core/Services/Registration/ConditionOperatorService.cs b/src/Artemis.Core/Services/Registration/ConditionOperatorService.cs
index a296efd4f..122b43813 100644
--- a/src/Artemis.Core/Services/Registration/ConditionOperatorService.cs
+++ b/src/Artemis.Core/Services/Registration/ConditionOperatorService.cs
@@ -12,14 +12,14 @@ namespace Artemis.Core.Services
RegisterBuiltInConditionOperators();
}
- public ConditionOperatorRegistration RegisterConditionOperator(PluginInfo pluginInfo, BaseConditionOperator conditionOperator)
+ public ConditionOperatorRegistration RegisterConditionOperator(Plugin plugin, BaseConditionOperator conditionOperator)
{
- if (pluginInfo == null)
- throw new ArgumentNullException(nameof(pluginInfo));
+ if (plugin == null)
+ throw new ArgumentNullException(nameof(plugin));
if (conditionOperator == null)
throw new ArgumentNullException(nameof(conditionOperator));
- conditionOperator.PluginInfo = pluginInfo;
+ conditionOperator.Plugin = plugin;
return ConditionOperatorStore.Add(conditionOperator);
}
@@ -43,30 +43,30 @@ namespace Artemis.Core.Services
private void RegisterBuiltInConditionOperators()
{
// General usage for any type
- RegisterConditionOperator(Constants.CorePluginInfo, new EqualsConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new NotEqualConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new EqualsConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new NotEqualConditionOperator());
// Numeric operators
- RegisterConditionOperator(Constants.CorePluginInfo, new NumberEqualsConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new NumberNotEqualConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new LessThanConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new GreaterThanConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new LessThanOrEqualConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new GreaterThanOrEqualConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new NumberEqualsConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new NumberNotEqualConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new LessThanConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new GreaterThanConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new LessThanOrEqualConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new GreaterThanOrEqualConditionOperator());
// String operators
- RegisterConditionOperator(Constants.CorePluginInfo, new StringEqualsConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new StringNotEqualConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new StringContainsConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new StringNotContainsConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new StringStartsWithConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new StringEndsWithConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new StringMatchesRegexConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new StringEqualsConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new StringNotEqualConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new StringContainsConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new StringNotContainsConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new StringStartsWithConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new StringEndsWithConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new StringMatchesRegexConditionOperator());
// Null checks, at the bottom
// TODO: Implement a priority mechanism
- RegisterConditionOperator(Constants.CorePluginInfo, new NullConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new NotNullConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new NullConditionOperator());
+ RegisterConditionOperator(Constants.CorePlugin, new NotNullConditionOperator());
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Registration/DataBindingService.cs b/src/Artemis.Core/Services/Registration/DataBindingService.cs
index 48f853641..08afb30c3 100644
--- a/src/Artemis.Core/Services/Registration/DataBindingService.cs
+++ b/src/Artemis.Core/Services/Registration/DataBindingService.cs
@@ -12,14 +12,14 @@ namespace Artemis.Core.Services
RegisterBuiltInModifiers();
}
- public DataBindingModifierTypeRegistration RegisterModifierType(PluginInfo pluginInfo, BaseDataBindingModifierType dataBindingModifierType)
+ public DataBindingModifierTypeRegistration RegisterModifierType(Plugin plugin, BaseDataBindingModifierType dataBindingModifierType)
{
- if (pluginInfo == null)
- throw new ArgumentNullException(nameof(pluginInfo));
+ if (plugin == null)
+ throw new ArgumentNullException(nameof(plugin));
if (dataBindingModifierType == null)
throw new ArgumentNullException(nameof(dataBindingModifierType));
- dataBindingModifierType.PluginInfo = pluginInfo;
+ dataBindingModifierType.Plugin = plugin;
return DataBindingModifierTypeStore.Add(dataBindingModifierType);
}
@@ -43,41 +43,41 @@ namespace Artemis.Core.Services
private void RegisterBuiltInModifiers()
{
// Numbers - General
- RegisterModifierType(Constants.CorePluginInfo, new SumModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new SubtractModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new MultiplicationModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new DivideModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new PercentageOfModifierType());
+ RegisterModifierType(Constants.CorePlugin, new SumModifierType());
+ RegisterModifierType(Constants.CorePlugin, new SubtractModifierType());
+ RegisterModifierType(Constants.CorePlugin, new MultiplicationModifierType());
+ RegisterModifierType(Constants.CorePlugin, new DivideModifierType());
+ RegisterModifierType(Constants.CorePlugin, new PercentageOfModifierType());
// Numbers - Advanced
- RegisterModifierType(Constants.CorePluginInfo, new MaxModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new MinModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new ModuloModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new AbsoluteModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new PowerModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new SquareRootModifierType());
+ RegisterModifierType(Constants.CorePlugin, new MaxModifierType());
+ RegisterModifierType(Constants.CorePlugin, new MinModifierType());
+ RegisterModifierType(Constants.CorePlugin, new ModuloModifierType());
+ RegisterModifierType(Constants.CorePlugin, new AbsoluteModifierType());
+ RegisterModifierType(Constants.CorePlugin, new PowerModifierType());
+ RegisterModifierType(Constants.CorePlugin, new SquareRootModifierType());
// Numbers - Rounding
- RegisterModifierType(Constants.CorePluginInfo, new FloorModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new RoundModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new CeilingModifierType());
+ RegisterModifierType(Constants.CorePlugin, new FloorModifierType());
+ RegisterModifierType(Constants.CorePlugin, new RoundModifierType());
+ RegisterModifierType(Constants.CorePlugin, new CeilingModifierType());
// Numbers - Trigonometric
- RegisterModifierType(Constants.CorePluginInfo, new SineModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new CosineModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new TangentModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new CotangentModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new SecantModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new CosecantModifierType());
+ RegisterModifierType(Constants.CorePlugin, new SineModifierType());
+ RegisterModifierType(Constants.CorePlugin, new CosineModifierType());
+ RegisterModifierType(Constants.CorePlugin, new TangentModifierType());
+ RegisterModifierType(Constants.CorePlugin, new CotangentModifierType());
+ RegisterModifierType(Constants.CorePlugin, new SecantModifierType());
+ RegisterModifierType(Constants.CorePlugin, new CosecantModifierType());
// Colors
- RegisterModifierType(Constants.CorePluginInfo, new SKColorSumModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new SKColorSaturateModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new SKColorDesaturateModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new SKColorBrightenModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new SKColorDarkenModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new SKColorRotateHueModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new SKColorInvertModifierType());
+ RegisterModifierType(Constants.CorePlugin, new SKColorSumModifierType());
+ RegisterModifierType(Constants.CorePlugin, new SKColorSaturateModifierType());
+ RegisterModifierType(Constants.CorePlugin, new SKColorDesaturateModifierType());
+ RegisterModifierType(Constants.CorePlugin, new SKColorBrightenModifierType());
+ RegisterModifierType(Constants.CorePlugin, new SKColorDarkenModifierType());
+ RegisterModifierType(Constants.CorePlugin, new SKColorRotateHueModifierType());
+ RegisterModifierType(Constants.CorePlugin, new SKColorInvertModifierType());
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Registration/DataModelService.cs b/src/Artemis.Core/Services/Registration/DataModelService.cs
index acfb0f1bf..b583439be 100644
--- a/src/Artemis.Core/Services/Registration/DataModelService.cs
+++ b/src/Artemis.Core/Services/Registration/DataModelService.cs
@@ -11,15 +11,16 @@ namespace Artemis.Core.Services
public DataModelService(IPluginManagementService pluginManagementService)
{
// Add data models of already loaded plugins
- foreach (Module module in pluginManagementService.GetPluginsOfType().Where(p => p.IsEnabled))
+ foreach (Module module in pluginManagementService.GetFeaturesOfType().Where(p => p.IsEnabled))
AddModuleDataModel(module);
- foreach (BaseDataModelExpansion dataModelExpansion in pluginManagementService.GetPluginsOfType().Where(p => p.IsEnabled))
+ foreach (BaseDataModelExpansion dataModelExpansion in pluginManagementService.GetFeaturesOfType().Where(p => p.IsEnabled))
AddDataModelExpansionDataModel(dataModelExpansion);
// Add data models of new plugins when they get enabled
- pluginManagementService.PluginEnabled += PluginServiceOnPluginEnabled;
+ pluginManagementService.PluginFeatureEnabled += OnPluginFeatureEnabled;
}
+
public DataModelRegistration RegisterDataModel(DataModel dataModel)
{
if (dataModel == null)
@@ -44,21 +45,16 @@ namespace Artemis.Core.Services
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;
- }
-
- private void PluginServiceOnPluginEnabled(object sender, PluginEventArgs e)
- {
- if (e.PluginInfo.Plugin is Module module)
+ if (e.PluginFeature is Module module)
AddModuleDataModel(module);
- else if (e.PluginInfo.Plugin is BaseDataModelExpansion dataModelExpansion)
+ else if (e.PluginFeature is BaseDataModelExpansion dataModelExpansion)
AddDataModelExpansionDataModel(dataModelExpansion);
}
@@ -68,7 +64,7 @@ namespace Artemis.Core.Services
return;
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;
RegisterDataModel(module.InternalDataModel);
@@ -77,7 +73,7 @@ namespace Artemis.Core.Services
private void AddDataModelExpansionDataModel(BaseDataModelExpansion dataModelExpansion)
{
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;
RegisterDataModel(dataModelExpansion.InternalDataModel);
diff --git a/src/Artemis.Core/Services/Registration/Interfaces/IConditionOperatorService.cs b/src/Artemis.Core/Services/Registration/Interfaces/IConditionOperatorService.cs
index 49cf60b16..359fec8d9 100644
--- a/src/Artemis.Core/Services/Registration/Interfaces/IConditionOperatorService.cs
+++ b/src/Artemis.Core/Services/Registration/Interfaces/IConditionOperatorService.cs
@@ -12,9 +12,9 @@ namespace Artemis.Core.Services
///
/// Registers a new condition operator for use in layer conditions
///
- /// The PluginInfo of the plugin this condition operator belongs to
+ /// The plugin this condition operator belongs to
/// The condition operator to register
- ConditionOperatorRegistration RegisterConditionOperator([NotNull] PluginInfo pluginInfo, [NotNull] BaseConditionOperator conditionOperator);
+ ConditionOperatorRegistration RegisterConditionOperator([NotNull] Plugin plugin, [NotNull] BaseConditionOperator conditionOperator);
///
/// Removes a condition operator so it is no longer available for use in layer conditions
diff --git a/src/Artemis.Core/Services/Registration/Interfaces/IDataBindingService.cs b/src/Artemis.Core/Services/Registration/Interfaces/IDataBindingService.cs
index bf33b1867..27ca01ab3 100644
--- a/src/Artemis.Core/Services/Registration/Interfaces/IDataBindingService.cs
+++ b/src/Artemis.Core/Services/Registration/Interfaces/IDataBindingService.cs
@@ -12,9 +12,9 @@ namespace Artemis.Core.Services
///
/// Registers a new modifier type for use in data bindings
///
- /// The PluginInfo of the plugin this modifier type belongs to
+ /// The plugin this modifier type belongs to
/// The modifier type to register
- DataBindingModifierTypeRegistration RegisterModifierType([NotNull] PluginInfo pluginInfo, [NotNull] BaseDataBindingModifierType dataBindingModifierType);
+ DataBindingModifierTypeRegistration RegisterModifierType([NotNull] Plugin plugin, [NotNull] BaseDataBindingModifierType dataBindingModifierType);
///
/// Removes a modifier type so it is no longer available for use in data bindings
diff --git a/src/Artemis.Core/Services/Registration/Interfaces/IDataModelService.cs b/src/Artemis.Core/Services/Registration/Interfaces/IDataModelService.cs
index 81f374a50..2f07006b6 100644
--- a/src/Artemis.Core/Services/Registration/Interfaces/IDataModelService.cs
+++ b/src/Artemis.Core/Services/Registration/Interfaces/IDataModelService.cs
@@ -34,13 +34,7 @@ namespace Artemis.Core.Services
///
/// If found, returns the data model of the provided plugin
///
- /// The plugin to find the data model of
- DataModel GetPluginDataModel(PluginImplementation pluginImplementation);
-
- ///
- /// If found, returns the data model of the provided plugin GUID
- ///
- /// The GUID of the plugin to find the data model of
- DataModel GetPluginDataModel(Guid pluginGuid);
+ /// The plugin to find the data model of
+ DataModel? GetPluginDataModel(PluginFeature pluginFeature);
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Registration/LayerBrushService.cs b/src/Artemis.Core/Services/Registration/LayerBrushService.cs
index 0ddca99ec..de738d6c4 100644
--- a/src/Artemis.Core/Services/Registration/LayerBrushService.cs
+++ b/src/Artemis.Core/Services/Registration/LayerBrushService.cs
@@ -38,11 +38,11 @@ namespace Artemis.Core.Services
{
PluginSetting defaultReference = _settingsService.GetSetting("ProfileEditor.DefaultLayerBrushDescriptor", new LayerBrushReference
{
- BrushPluginGuid = Guid.Parse("92a9d6ba-6f7a-4937-94d5-c1d715b4141a"),
+ LayerBrushProviderId = "Artemis.Plugins.LayerBrushes.Color.ColorBrushProvider-92a9d6ba",
BrushType = "ColorBrush"
});
- return LayerBrushStore.Get(defaultReference.Value.BrushPluginGuid, defaultReference.Value.BrushType)?.LayerBrushDescriptor;
+ return LayerBrushStore.Get(defaultReference.Value.LayerBrushProviderId, defaultReference.Value.BrushType)?.LayerBrushDescriptor;
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/SettingsService.cs b/src/Artemis.Core/Services/SettingsService.cs
index 24b267e63..b00f5cee4 100644
--- a/src/Artemis.Core/Services/SettingsService.cs
+++ b/src/Artemis.Core/Services/SettingsService.cs
@@ -9,7 +9,7 @@ namespace Artemis.Core.Services
internal SettingsService(IPluginRepository pluginRepository)
{
- _pluginSettings = new PluginSettings(Constants.CorePluginInfo, pluginRepository);
+ _pluginSettings = new PluginSettings(Constants.CorePlugin, pluginRepository);
}
public PluginSetting GetSetting(string name, T defaultValue = default)
diff --git a/src/Artemis.Core/Services/Storage/ProfileService.cs b/src/Artemis.Core/Services/Storage/ProfileService.cs
index 469526f73..e142952d5 100644
--- a/src/Artemis.Core/Services/Storage/ProfileService.cs
+++ b/src/Artemis.Core/Services/Storage/ProfileService.cs
@@ -38,13 +38,13 @@ namespace Artemis.Core.Services
public List GetProfileDescriptors(ProfileModule module)
{
- List profileEntities = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid);
+ List profileEntities = _profileRepository.GetByModuleId(module.Id);
return profileEntities.Select(e => new ProfileDescriptor(module, e)).ToList();
}
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);
return new ProfileDescriptor(module, profileEntity);
@@ -258,7 +258,7 @@ namespace Artemis.Core.Services
public ProfileDescriptor GetLastActiveProfile(ProfileModule module)
{
- List moduleProfiles = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid);
+ List moduleProfiles = _profileRepository.GetByModuleId(module.Id);
if (!moduleProfiles.Any())
return CreateProfileDescriptor(module, "Default");
@@ -271,7 +271,7 @@ namespace Artemis.Core.Services
if (module.ActiveProfile == null)
return;
- List profileEntities = _profileRepository.GetByPluginGuid(module.PluginInfo.Guid);
+ List profileEntities = _profileRepository.GetByModuleId(module.Id);
foreach (ProfileEntity profileEntity in profileEntities)
{
profileEntity.IsActive = module.ActiveProfile.EntityId == profileEntity.Id;
@@ -285,7 +285,7 @@ namespace Artemis.Core.Services
///
private void ActiveProfilesPopulateLeds(ArtemisSurface surface)
{
- List profileModules = _pluginManagementService.GetPluginsOfType();
+ List profileModules = _pluginManagementService.GetFeaturesOfType();
foreach (ProfileModule profileModule in profileModules.Where(p => p.ActiveProfile != null).ToList())
profileModule.ActiveProfile.PopulateLeds(surface);
}
diff --git a/src/Artemis.Core/Services/Storage/SurfaceService.cs b/src/Artemis.Core/Services/Storage/SurfaceService.cs
index 24265e06e..6b1fc1861 100644
--- a/src/Artemis.Core/Services/Storage/SurfaceService.cs
+++ b/src/Artemis.Core/Services/Storage/SurfaceService.cs
@@ -44,8 +44,8 @@ namespace Artemis.Core.Services
// Add all current devices
foreach (IRGBDevice rgbDevice in _rgbService.LoadedDevices)
{
- PluginImplementation pluginImplementation = _pluginManagementService.GetPluginByDevice(rgbDevice);
- configuration.Devices.Add(new ArtemisDevice(rgbDevice, pluginImplementation, configuration));
+ PluginFeature pluginFeature = _pluginManagementService.GetDeviceProviderByDevice(rgbDevice);
+ configuration.Devices.Add(new ArtemisDevice(rgbDevice, pluginFeature, configuration));
}
lock (_surfaceConfigurations)
@@ -136,8 +136,8 @@ namespace Artemis.Core.Services
IRGBDevice device = _rgbService.Surface.Devices.FirstOrDefault(d => d.GetDeviceIdentifier() == position.DeviceIdentifier);
if (device != null)
{
- PluginImplementation pluginImplementation = _pluginManagementService.GetPluginByDevice(device);
- surfaceConfiguration.Devices.Add(new ArtemisDevice(device, pluginImplementation, surfaceConfiguration, position));
+ PluginFeature pluginFeature = _pluginManagementService.GetDeviceProviderByDevice(device);
+ 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);
if (existingDeviceConfig != null)
{
- PluginImplementation pluginImplementation = _pluginManagementService.GetPluginByDevice(rgbDevice);
- device = new ArtemisDevice(rgbDevice, pluginImplementation, surface, existingDeviceConfig);
+ PluginFeature pluginFeature = _pluginManagementService.GetDeviceProviderByDevice(rgbDevice);
+ device = new ArtemisDevice(rgbDevice, pluginFeature, surface, existingDeviceConfig);
}
// Fall back on creating a new device
else
@@ -189,8 +189,8 @@ namespace Artemis.Core.Services
rgbDevice.DeviceInfo,
deviceIdentifier
);
- PluginImplementation pluginImplementation = _pluginManagementService.GetPluginByDevice(rgbDevice);
- device = new ArtemisDevice(rgbDevice, pluginImplementation, surface);
+ PluginFeature pluginFeature = _pluginManagementService.GetDeviceProviderByDevice(rgbDevice);
+ device = new ArtemisDevice(rgbDevice, pluginFeature, surface);
}
surface.Devices.Add(device);
diff --git a/src/Artemis.Core/Stores/ConditionOperatorStore.cs b/src/Artemis.Core/Stores/ConditionOperatorStore.cs
index 0873bafa9..3247d648d 100644
--- a/src/Artemis.Core/Stores/ConditionOperatorStore.cs
+++ b/src/Artemis.Core/Stores/ConditionOperatorStore.cs
@@ -16,7 +16,7 @@ namespace Artemis.Core
if (Registrations.Any(r => r.ConditionOperator == conditionOperator))
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);
}
@@ -42,7 +42,7 @@ namespace Artemis.Core
{
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);
}
}
diff --git a/src/Artemis.Core/Stores/DataBindingModifierTypeStore.cs b/src/Artemis.Core/Stores/DataBindingModifierTypeStore.cs
index bb83a7aef..302f32241 100644
--- a/src/Artemis.Core/Stores/DataBindingModifierTypeStore.cs
+++ b/src/Artemis.Core/Stores/DataBindingModifierTypeStore.cs
@@ -16,7 +16,7 @@ namespace Artemis.Core
if (Registrations.Any(r => r.DataBindingModifierType == modifierType))
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);
}
@@ -42,7 +42,7 @@ namespace Artemis.Core
{
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);
}
}
diff --git a/src/Artemis.Core/Stores/DataModelStore.cs b/src/Artemis.Core/Stores/DataModelStore.cs
index 30c1da751..713ee90c2 100644
--- a/src/Artemis.Core/Stores/DataModelStore.cs
+++ b/src/Artemis.Core/Stores/DataModelStore.cs
@@ -17,7 +17,7 @@ namespace Artemis.Core
if (Registrations.Any(r => r.DataModel == dataModel))
throw new ArtemisCoreException($"Data model store already contains data model '{dataModel.DataModelDescription}'");
- registration = new DataModelRegistration(dataModel, dataModel.Implementation.Instance) {IsInStore = true};
+ registration = new DataModelRegistration(dataModel, dataModel.Feature) {IsInStore = true};
Registrations.Add(registration);
}
@@ -47,11 +47,11 @@ namespace Artemis.Core
}
}
- public static DataModelRegistration Get(Guid pluginGuid)
+ public static DataModelRegistration Get(string id)
{
lock (Registrations)
{
- return Registrations.FirstOrDefault(d => d.PluginImplementation.PluginInfo.Guid == pluginGuid);
+ return Registrations.FirstOrDefault(d => d.PluginFeature.Id == id);
}
}
diff --git a/src/Artemis.Core/Stores/LayerBrushStore.cs b/src/Artemis.Core/Stores/LayerBrushStore.cs
index 3d5c59c96..fb05da802 100644
--- a/src/Artemis.Core/Stores/LayerBrushStore.cs
+++ b/src/Artemis.Core/Stores/LayerBrushStore.cs
@@ -17,7 +17,7 @@ namespace Artemis.Core
if (Registrations.Any(r => r.LayerBrushDescriptor == descriptor))
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);
}
@@ -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)
{
- return Registrations.FirstOrDefault(d => d.PluginImplementation.PluginInfo.Guid == pluginGuid &&
+ return Registrations.FirstOrDefault(d => d.PluginFeature.Id == id &&
d.LayerBrushDescriptor.LayerBrushType.Name == typeName);
}
}
diff --git a/src/Artemis.Core/Stores/LayerEffectStore.cs b/src/Artemis.Core/Stores/LayerEffectStore.cs
index 420edb464..ac3060bd9 100644
--- a/src/Artemis.Core/Stores/LayerEffectStore.cs
+++ b/src/Artemis.Core/Stores/LayerEffectStore.cs
@@ -17,7 +17,7 @@ namespace Artemis.Core
if (Registrations.Any(r => r.LayerEffectDescriptor == descriptor))
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);
}
@@ -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)
{
- 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);
}
}
diff --git a/src/Artemis.Core/Stores/Registrations/ConditionOperatorRegistration.cs b/src/Artemis.Core/Stores/Registrations/ConditionOperatorRegistration.cs
index d9ac7775e..46cb22068 100644
--- a/src/Artemis.Core/Stores/Registrations/ConditionOperatorRegistration.cs
+++ b/src/Artemis.Core/Stores/Registrations/ConditionOperatorRegistration.cs
@@ -7,12 +7,12 @@ namespace Artemis.Core
///
public class ConditionOperatorRegistration
{
- internal ConditionOperatorRegistration(BaseConditionOperator conditionOperator, PluginImplementation pluginImplementation)
+ internal ConditionOperatorRegistration(BaseConditionOperator conditionOperator, Plugin plugin)
{
ConditionOperator = conditionOperator;
- PluginImplementation = pluginImplementation;
+ Plugin = plugin;
- PluginImplementation.Disabled += OnDisabled;
+ Plugin.Disabled += OnDisabled;
}
///
@@ -23,7 +23,7 @@ namespace Artemis.Core
///
/// Gets the plugin the condition operator is associated with
///
- public PluginImplementation PluginImplementation { get; }
+ public Plugin Plugin { get; }
///
/// 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)
{
- PluginImplementation.Disabled -= OnDisabled;
+ Plugin.Disabled -= OnDisabled;
if (IsInStore)
ConditionOperatorStore.Remove(this);
}
diff --git a/src/Artemis.Core/Stores/Registrations/DataBindingModifierTypeRegistration.cs b/src/Artemis.Core/Stores/Registrations/DataBindingModifierTypeRegistration.cs
index 2a556dda2..b0ff66088 100644
--- a/src/Artemis.Core/Stores/Registrations/DataBindingModifierTypeRegistration.cs
+++ b/src/Artemis.Core/Stores/Registrations/DataBindingModifierTypeRegistration.cs
@@ -7,12 +7,12 @@ namespace Artemis.Core
///
public class DataBindingModifierTypeRegistration
{
- internal DataBindingModifierTypeRegistration(BaseDataBindingModifierType dataBindingModifierType, PluginImplementation pluginImplementation)
+ internal DataBindingModifierTypeRegistration(BaseDataBindingModifierType dataBindingModifierType, Plugin plugin)
{
DataBindingModifierType = dataBindingModifierType;
- PluginImplementation = pluginImplementation;
+ Plugin = plugin;
- PluginImplementation.Disabled += OnDisabled;
+ Plugin.Disabled += OnDisabled;
}
///
@@ -23,7 +23,7 @@ namespace Artemis.Core
///
/// Gets the plugin the data binding modifier is associated with
///
- public PluginImplementation PluginImplementation { get; }
+ public Plugin Plugin { get; }
///
/// 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)
{
- PluginImplementation.Disabled -= OnDisabled;
+ Plugin.Disabled -= OnDisabled;
if (IsInStore)
DataBindingModifierTypeStore.Remove(this);
}
diff --git a/src/Artemis.Core/Stores/Registrations/DataModelRegistration.cs b/src/Artemis.Core/Stores/Registrations/DataModelRegistration.cs
index 879c81ff2..7a1812e02 100644
--- a/src/Artemis.Core/Stores/Registrations/DataModelRegistration.cs
+++ b/src/Artemis.Core/Stores/Registrations/DataModelRegistration.cs
@@ -8,12 +8,12 @@ namespace Artemis.Core
///
public class DataModelRegistration
{
- internal DataModelRegistration(DataModel dataModel, PluginImplementation pluginImplementation)
+ internal DataModelRegistration(DataModel dataModel, PluginFeature pluginFeature)
{
DataModel = dataModel;
- PluginImplementation = pluginImplementation;
+ PluginFeature = pluginFeature;
- PluginImplementation.Disabled += OnDisabled;
+ PluginFeature.Disabled += OnDisabled;
}
///
@@ -24,7 +24,7 @@ namespace Artemis.Core
///
/// Gets the plugin the data model is associated with
///
- public PluginImplementation PluginImplementation { get; }
+ public PluginFeature PluginFeature { get; }
///
/// 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)
{
- PluginImplementation.Disabled -= OnDisabled;
+ PluginFeature.Disabled -= OnDisabled;
if (IsInStore)
DataModelStore.Remove(this);
}
diff --git a/src/Artemis.Core/Stores/Registrations/LayerBrushRegistration.cs b/src/Artemis.Core/Stores/Registrations/LayerBrushRegistration.cs
index 15e2bf422..8e35bf905 100644
--- a/src/Artemis.Core/Stores/Registrations/LayerBrushRegistration.cs
+++ b/src/Artemis.Core/Stores/Registrations/LayerBrushRegistration.cs
@@ -8,12 +8,12 @@ namespace Artemis.Core
///
public class LayerBrushRegistration
{
- internal LayerBrushRegistration(LayerBrushDescriptor descriptor, PluginImplementation pluginImplementation)
+ internal LayerBrushRegistration(LayerBrushDescriptor descriptor, PluginFeature pluginFeature)
{
LayerBrushDescriptor = descriptor;
- PluginImplementation = pluginImplementation;
+ PluginFeature = pluginFeature;
- PluginImplementation.Disabled += OnDisabled;
+ PluginFeature.Disabled += OnDisabled;
}
///
@@ -24,7 +24,7 @@ namespace Artemis.Core
///
/// Gets the plugin the layer brush is associated with
///
- public PluginImplementation PluginImplementation { get; }
+ public PluginFeature PluginFeature { get; }
///
/// 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)
{
- PluginImplementation.Disabled -= OnDisabled;
+ PluginFeature.Disabled -= OnDisabled;
if (IsInStore)
LayerBrushStore.Remove(this);
}
diff --git a/src/Artemis.Core/Stores/Registrations/LayerEffectRegistration.cs b/src/Artemis.Core/Stores/Registrations/LayerEffectRegistration.cs
index 693985560..0b74524f0 100644
--- a/src/Artemis.Core/Stores/Registrations/LayerEffectRegistration.cs
+++ b/src/Artemis.Core/Stores/Registrations/LayerEffectRegistration.cs
@@ -8,12 +8,12 @@ namespace Artemis.Core
///
public class LayerEffectRegistration
{
- internal LayerEffectRegistration(LayerEffectDescriptor descriptor, PluginImplementation pluginImplementation)
+ internal LayerEffectRegistration(LayerEffectDescriptor descriptor, PluginFeature pluginFeature)
{
LayerEffectDescriptor = descriptor;
- PluginImplementation = pluginImplementation;
+ PluginFeature = pluginFeature;
- PluginImplementation.Disabled += OnDisabled;
+ PluginFeature.Disabled += OnDisabled;
}
///
@@ -24,7 +24,7 @@ namespace Artemis.Core
///
/// Gets the plugin the layer effect is associated with
///
- public PluginImplementation PluginImplementation { get; }
+ public PluginFeature PluginFeature { get; }
///
/// 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)
{
- PluginImplementation.Disabled -= OnDisabled;
+ PluginFeature.Disabled -= OnDisabled;
if (IsInStore)
LayerEffectStore.Remove(this);
}
diff --git a/src/Artemis.Core/Utilities/CorePluginImplementation.cs b/src/Artemis.Core/Utilities/CorePluginFeature.cs
similarity index 70%
rename from src/Artemis.Core/Utilities/CorePluginImplementation.cs
rename to src/Artemis.Core/Utilities/CorePluginFeature.cs
index f7a5d4310..897c46b88 100644
--- a/src/Artemis.Core/Utilities/CorePluginImplementation.cs
+++ b/src/Artemis.Core/Utilities/CorePluginFeature.cs
@@ -3,13 +3,13 @@
namespace Artemis.Core
{
///
- /// An empty plugin used by
+ /// An empty data model plugin feature used by
///
- internal class CorePluginImplementation : PluginImplementation
+ internal class CorePluginFeature : DataModelPluginFeature
{
- public CorePluginImplementation()
+ public CorePluginFeature()
{
- Constants.CorePluginInfo.Plugin = this;
+ Constants.CorePlugin.AddFeature(this);
IsEnabled = true;
}
diff --git a/src/Artemis.Core/Utilities/CurrentProcessUtilities.cs b/src/Artemis.Core/Utilities/CurrentProcessUtilities.cs
index 464aa628f..4c3a03463 100644
--- a/src/Artemis.Core/Utilities/CurrentProcessUtilities.cs
+++ b/src/Artemis.Core/Utilities/CurrentProcessUtilities.cs
@@ -1,6 +1,6 @@
-using System.Diagnostics;
+using System;
+using System.Diagnostics;
using System.Windows;
-using Stylet;
namespace Artemis.Core
{
@@ -37,8 +37,8 @@ namespace Artemis.Core
if (!Debugger.IsAttached)
Process.Start(info);
- // Also attempt a graceful shutdown on the UI thread
- Execute.OnUIThread(() => Application.Current.Shutdown());
+ // Request a graceful shutdown, whatever UI we're running can pick this up
+ OnShutdownRequested();
}
///
@@ -64,5 +64,18 @@ namespace Artemis.Core
{
return Process.GetCurrentProcess().MainModule.FileName;
}
+
+ #region Events
+
+ public static event EventHandler ShutdownRequested;
+
+ private static void OnShutdownRequested()
+ {
+ ShutdownRequested?.Invoke(null, EventArgs.Empty);
+ }
+
+ #endregion
+
+
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/packages.lock.json b/src/Artemis.Core/packages.lock.json
index e6ecc5b44..253535ea9 100644
--- a/src/Artemis.Core/packages.lock.json
+++ b/src/Artemis.Core/packages.lock.json
@@ -121,15 +121,6 @@
"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": {
"type": "Direct",
"requested": "[4.5.0, )",
@@ -192,8 +183,8 @@
},
"Microsoft.NETCore.Platforms": {
"type": "Transitive",
- "resolved": "3.0.0",
- "contentHash": "TsETIgVJb/AKoYfSP+iCxkuly5d3inZjTdx/ItZLk2CxY85v8083OBS3uai84kK3/baLnS5/b5XGs6zR7SuuHQ=="
+ "resolved": "1.1.0",
+ "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A=="
},
"Microsoft.NETCore.Targets": {
"type": "Transitive",
@@ -210,14 +201,6 @@
"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": {
"type": "Transitive",
"resolved": "1.6.1",
@@ -557,15 +540,6 @@
"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": {
"type": "Transitive",
"resolved": "4.3.0",
diff --git a/src/Artemis.Storage/Entities/Module/ModuleSettingsEntity.cs b/src/Artemis.Storage/Entities/Module/ModuleSettingsEntity.cs
index 296a5ca8a..3cddf93b7 100644
--- a/src/Artemis.Storage/Entities/Module/ModuleSettingsEntity.cs
+++ b/src/Artemis.Storage/Entities/Module/ModuleSettingsEntity.cs
@@ -10,7 +10,7 @@ namespace Artemis.Storage.Entities.Module
}
public Guid Id { get; set; }
- public Guid PluginGuid { get; set; }
+ public string ModuleId { get; set; }
public int PriorityCategory { get; set; }
public int Priority { get; set; }
}
diff --git a/src/Artemis.Storage/Entities/Plugins/PluginEntity.cs b/src/Artemis.Storage/Entities/Plugins/PluginEntity.cs
index 3cfa1088e..4ac4db668 100644
--- a/src/Artemis.Storage/Entities/Plugins/PluginEntity.cs
+++ b/src/Artemis.Storage/Entities/Plugins/PluginEntity.cs
@@ -8,16 +8,21 @@ namespace Artemis.Storage.Entities.Plugins
///
public class PluginEntity
{
+ public PluginEntity()
+ {
+ Features = new List();
+ }
+
public Guid Id { get; set; }
public bool IsEnabled { get; set; }
- public List Implementations { get; set; }
+ public List Features { get; set; }
}
///
- /// Represents the configuration of a plugin implementation, each implementation has one configuration
+ /// Represents the configuration of a plugin feature, each feature has one configuration
///
- public class PluginImplementationEntity
+ public class PluginFeatureEntity
{
public string Type { get; set; }
public bool IsEnabled { get; set; }
diff --git a/src/Artemis.Storage/Entities/Profile/DataModelPathEntity.cs b/src/Artemis.Storage/Entities/Profile/DataModelPathEntity.cs
index b4a2b03b5..7ab2806db 100644
--- a/src/Artemis.Storage/Entities/Profile/DataModelPathEntity.cs
+++ b/src/Artemis.Storage/Entities/Profile/DataModelPathEntity.cs
@@ -5,7 +5,7 @@ namespace Artemis.Storage.Entities.Profile
public class DataModelPathEntity
{
public string Path { get; set; }
- public Guid? DataModelGuid { get; set; }
+ public string DataModelId { get; set; }
public PathWrapperType WrapperType { get; set; }
}
diff --git a/src/Artemis.Storage/Entities/Profile/LayerEffectEntity.cs b/src/Artemis.Storage/Entities/Profile/LayerEffectEntity.cs
index d6dce29be..6c8503e42 100644
--- a/src/Artemis.Storage/Entities/Profile/LayerEffectEntity.cs
+++ b/src/Artemis.Storage/Entities/Profile/LayerEffectEntity.cs
@@ -5,7 +5,7 @@ namespace Artemis.Storage.Entities.Profile
public class LayerEffectEntity
{
public Guid Id { get; set; }
- public Guid PluginGuid { get; set; }
+ public string ProviderId { get; set; }
public string EffectType { get; set; }
public string Name { get; set; }
public bool Enabled { get; set; }
diff --git a/src/Artemis.Storage/Entities/Profile/ProfileEntity.cs b/src/Artemis.Storage/Entities/Profile/ProfileEntity.cs
index ecd08497b..177d8c00b 100644
--- a/src/Artemis.Storage/Entities/Profile/ProfileEntity.cs
+++ b/src/Artemis.Storage/Entities/Profile/ProfileEntity.cs
@@ -13,7 +13,7 @@ namespace Artemis.Storage.Entities.Profile
}
public Guid Id { get; set; }
- public Guid PluginGuid { get; set; }
+ public string ModuleId { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
diff --git a/src/Artemis.Storage/Entities/Profile/PropertyEntity.cs b/src/Artemis.Storage/Entities/Profile/PropertyEntity.cs
index c26baa1ce..6c04025d4 100644
--- a/src/Artemis.Storage/Entities/Profile/PropertyEntity.cs
+++ b/src/Artemis.Storage/Entities/Profile/PropertyEntity.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using Artemis.Storage.Entities.Profile.DataBindings;
namespace Artemis.Storage.Entities.Profile
@@ -12,7 +11,7 @@ namespace Artemis.Storage.Entities.Profile
DataBindingEntities = new List();
}
- public Guid PluginGuid { get; set; }
+ public string FeatureId { get; set; }
public string Path { get; set; }
public string Value { get; set; }
diff --git a/src/Artemis.Storage/Repositories/Interfaces/IModuleRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IModuleRepository.cs
index 5780e7bc0..918efb361 100644
--- a/src/Artemis.Storage/Repositories/Interfaces/IModuleRepository.cs
+++ b/src/Artemis.Storage/Repositories/Interfaces/IModuleRepository.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using Artemis.Storage.Entities.Module;
namespace Artemis.Storage.Repositories.Interfaces
@@ -7,7 +6,7 @@ namespace Artemis.Storage.Repositories.Interfaces
public interface IModuleRepository : IRepository
{
void Add(ModuleSettingsEntity moduleSettingsEntity);
- ModuleSettingsEntity GetByPluginGuid(Guid guid);
+ ModuleSettingsEntity GetByModuleId(string moduleId);
List GetAll();
List GetByCategory(int category);
void Save(ModuleSettingsEntity moduleSettingsEntity);
diff --git a/src/Artemis.Storage/Repositories/Interfaces/IProfileRepository.cs b/src/Artemis.Storage/Repositories/Interfaces/IProfileRepository.cs
index d0f559b16..a42c74966 100644
--- a/src/Artemis.Storage/Repositories/Interfaces/IProfileRepository.cs
+++ b/src/Artemis.Storage/Repositories/Interfaces/IProfileRepository.cs
@@ -10,7 +10,7 @@ namespace Artemis.Storage.Repositories.Interfaces
void Remove(ProfileEntity profileEntity);
List GetAll();
ProfileEntity Get(Guid id);
- List GetByPluginGuid(Guid pluginGuid);
+ List GetByModuleId(string moduleId);
void Save(ProfileEntity profileEntity);
}
}
\ No newline at end of file
diff --git a/src/Artemis.Storage/Repositories/ModuleRepository.cs b/src/Artemis.Storage/Repositories/ModuleRepository.cs
index 6f3ad34b7..ff9d4953b 100644
--- a/src/Artemis.Storage/Repositories/ModuleRepository.cs
+++ b/src/Artemis.Storage/Repositories/ModuleRepository.cs
@@ -13,7 +13,7 @@ namespace Artemis.Storage.Repositories
internal ModuleRepository(LiteRepository repository)
{
_repository = repository;
- _repository.Database.GetCollection().EnsureIndex(s => s.PluginGuid, true);
+ _repository.Database.GetCollection().EnsureIndex(s => s.ModuleId, true);
}
public void Add(ModuleSettingsEntity moduleSettingsEntity)
@@ -21,9 +21,9 @@ namespace Artemis.Storage.Repositories
_repository.Insert(moduleSettingsEntity);
}
- public ModuleSettingsEntity GetByPluginGuid(Guid guid)
+ public ModuleSettingsEntity GetByModuleId(string moduleId)
{
- return _repository.FirstOrDefault(s => s.PluginGuid == guid);
+ return _repository.FirstOrDefault(s => s.ModuleId == moduleId);
}
public List GetAll()
diff --git a/src/Artemis.Storage/Repositories/ProfileRepository.cs b/src/Artemis.Storage/Repositories/ProfileRepository.cs
index 5ca90ea2e..288b40fcb 100644
--- a/src/Artemis.Storage/Repositories/ProfileRepository.cs
+++ b/src/Artemis.Storage/Repositories/ProfileRepository.cs
@@ -36,12 +36,12 @@ namespace Artemis.Storage.Repositories
return _repository.FirstOrDefault(p => p.Id == id);
}
- public List GetByPluginGuid(Guid pluginGuid)
+ public List GetByModuleId(string moduleId)
{
return _repository.Query()
.Include(p => p.Folders)
.Include(p => p.Layers)
- .Where(s => s.PluginGuid == pluginGuid)
+ .Where(s => s.ModuleId == moduleId)
.ToList();
}
diff --git a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj.DotSettings b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj.DotSettings
index 1292ea906..5229191ac 100644
--- a/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj.DotSettings
+++ b/src/Artemis.UI.Shared/Artemis.UI.Shared.csproj.DotSettings
@@ -8,6 +8,7 @@
True
True
True
+ True
True
True
True
diff --git a/src/Artemis.UI.Shared/DataModelVisualization/DataModelVisualizationRegistration.cs b/src/Artemis.UI.Shared/DataModelVisualization/DataModelVisualizationRegistration.cs
index e3a66bc8a..5ed47be76 100644
--- a/src/Artemis.UI.Shared/DataModelVisualization/DataModelVisualizationRegistration.cs
+++ b/src/Artemis.UI.Shared/DataModelVisualization/DataModelVisualizationRegistration.cs
@@ -11,22 +11,22 @@ namespace Artemis.UI.Shared
public DataModelVisualizationRegistration(IDataModelUIService dataModelUIService,
RegistrationType registrationType,
- PluginInfo pluginInfo,
+ Plugin plugin,
Type supportedType,
Type viewModelType)
{
_dataModelUIService = dataModelUIService;
RegistrationType = registrationType;
- PluginInfo = pluginInfo;
+ Plugin = plugin;
SupportedType = supportedType;
ViewModelType = viewModelType;
- if (PluginInfo != Constants.CorePluginInfo)
- PluginInfo.Plugin.Disabled += InstanceOnDisabled;
+ if (Plugin != Constants.CorePlugin)
+ Plugin.Disabled += InstanceOnDisabled;
}
public RegistrationType RegistrationType { get; }
- public PluginInfo PluginInfo { get; }
+ public Plugin Plugin { get; }
public Type SupportedType { get; }
public Type ViewModelType { get; }
@@ -34,8 +34,8 @@ namespace Artemis.UI.Shared
internal void Unsubscribe()
{
- if (PluginInfo != Constants.CorePluginInfo)
- PluginInfo.Plugin.Disabled -= InstanceOnDisabled;
+ if (Plugin != Constants.CorePlugin)
+ Plugin.Disabled -= InstanceOnDisabled;
}
private void InstanceOnDisabled(object sender, EventArgs e)
diff --git a/src/Artemis.Core/Plugins/LayerBrushes/BrushConfigurationViewModel.cs b/src/Artemis.UI.Shared/Plugins/LayerBrushes/BrushConfigurationViewModel.cs
similarity index 92%
rename from src/Artemis.Core/Plugins/LayerBrushes/BrushConfigurationViewModel.cs
rename to src/Artemis.UI.Shared/Plugins/LayerBrushes/BrushConfigurationViewModel.cs
index 34a928f94..0c61885b0 100644
--- a/src/Artemis.Core/Plugins/LayerBrushes/BrushConfigurationViewModel.cs
+++ b/src/Artemis.UI.Shared/Plugins/LayerBrushes/BrushConfigurationViewModel.cs
@@ -1,6 +1,7 @@
-using Stylet;
+using Artemis.Core.LayerBrushes;
+using Stylet;
-namespace Artemis.Core.LayerBrushes
+namespace Artemis.UI.Shared.LayerBrushes
{
///
/// Represents a view model for a brush configuration window
diff --git a/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushConfigurationDialog.cs b/src/Artemis.UI.Shared/Plugins/LayerBrushes/LayerBrushConfigurationDialog.cs
similarity index 80%
rename from src/Artemis.Core/Plugins/LayerBrushes/LayerBrushConfigurationDialog.cs
rename to src/Artemis.UI.Shared/Plugins/LayerBrushes/LayerBrushConfigurationDialog.cs
index 5074e8d02..ed20b670b 100644
--- a/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushConfigurationDialog.cs
+++ b/src/Artemis.UI.Shared/Plugins/LayerBrushes/LayerBrushConfigurationDialog.cs
@@ -1,6 +1,7 @@
using System;
+using Artemis.Core.LayerBrushes;
-namespace Artemis.Core.LayerBrushes
+namespace Artemis.UI.Shared.LayerBrushes
{
///
public class LayerBrushConfigurationDialog : LayerBrushConfigurationDialog where T : BrushConfigurationViewModel
@@ -12,7 +13,7 @@ namespace Artemis.Core.LayerBrushes
///
/// Describes a UI tab for a layer brush
///
- public abstract class LayerBrushConfigurationDialog
+ public abstract class LayerBrushConfigurationDialog : ILayerBrushConfigurationDialog
{
///
/// The layer brush this dialog belongs to
diff --git a/src/Artemis.Core/Plugins/LayerEffects/EffectConfigurationViewModel.cs b/src/Artemis.UI.Shared/Plugins/LayerEffects/EffectConfigurationViewModel.cs
similarity index 92%
rename from src/Artemis.Core/Plugins/LayerEffects/EffectConfigurationViewModel.cs
rename to src/Artemis.UI.Shared/Plugins/LayerEffects/EffectConfigurationViewModel.cs
index effc967a3..aac795039 100644
--- a/src/Artemis.Core/Plugins/LayerEffects/EffectConfigurationViewModel.cs
+++ b/src/Artemis.UI.Shared/Plugins/LayerEffects/EffectConfigurationViewModel.cs
@@ -1,6 +1,7 @@
-using Stylet;
+using Artemis.Core.LayerEffects;
+using Stylet;
-namespace Artemis.Core.LayerEffects
+namespace Artemis.UI.Shared.LayerEffects
{
///
/// Represents a view model for an effect configuration window
diff --git a/src/Artemis.Core/Plugins/LayerEffects/LayerEffectConfigurationDialog.cs b/src/Artemis.UI.Shared/Plugins/LayerEffects/LayerEffectConfigurationDialog.cs
similarity index 80%
rename from src/Artemis.Core/Plugins/LayerEffects/LayerEffectConfigurationDialog.cs
rename to src/Artemis.UI.Shared/Plugins/LayerEffects/LayerEffectConfigurationDialog.cs
index 674d3897e..604214b8c 100644
--- a/src/Artemis.Core/Plugins/LayerEffects/LayerEffectConfigurationDialog.cs
+++ b/src/Artemis.UI.Shared/Plugins/LayerEffects/LayerEffectConfigurationDialog.cs
@@ -1,6 +1,7 @@
using System;
+using Artemis.Core.LayerEffects;
-namespace Artemis.Core.LayerEffects
+namespace Artemis.UI.Shared.LayerEffects
{
///
public class LayerEffectConfigurationDialog : LayerEffectConfigurationDialog where T : EffectConfigurationViewModel
@@ -12,7 +13,7 @@ namespace Artemis.Core.LayerEffects
///
/// Describes a UI tab for a specific layer effect
///
- public abstract class LayerEffectConfigurationDialog
+ public abstract class LayerEffectConfigurationDialog : ILayerEffectConfigurationDialog
{
///
/// The layer effect this dialog belongs to
diff --git a/src/Artemis.Core/Plugins/Modules/ModuleViewModel.cs b/src/Artemis.UI.Shared/Plugins/Modules/ModuleViewModel.cs
similarity index 83%
rename from src/Artemis.Core/Plugins/Modules/ModuleViewModel.cs
rename to src/Artemis.UI.Shared/Plugins/Modules/ModuleViewModel.cs
index 7aeed4311..05222aed1 100644
--- a/src/Artemis.Core/Plugins/Modules/ModuleViewModel.cs
+++ b/src/Artemis.UI.Shared/Plugins/Modules/ModuleViewModel.cs
@@ -1,11 +1,12 @@
-using Stylet;
+using Artemis.Core.Modules;
+using Stylet;
-namespace Artemis.Core.Modules
+namespace Artemis.UI.Shared.Modules
{
///
/// The base class for any view model that belongs to a module
///
- public abstract class ModuleViewModel : Screen
+ public abstract class ModuleViewModel : Screen, IModuleViewModel
{
///
/// The base class for any view model that belongs to a module
diff --git a/src/Artemis.Core/Plugins/PluginConfigurationDialog.cs b/src/Artemis.UI.Shared/Plugins/PluginConfigurationDialog.cs
similarity index 76%
rename from src/Artemis.Core/Plugins/PluginConfigurationDialog.cs
rename to src/Artemis.UI.Shared/Plugins/PluginConfigurationDialog.cs
index 288caefa8..7c7e62886 100644
--- a/src/Artemis.Core/Plugins/PluginConfigurationDialog.cs
+++ b/src/Artemis.UI.Shared/Plugins/PluginConfigurationDialog.cs
@@ -1,6 +1,7 @@
using System;
+using Artemis.Core;
-namespace Artemis.Core
+namespace Artemis.UI.Shared
{
///
public class PluginConfigurationDialog : PluginConfigurationDialog where T : PluginConfigurationViewModel
@@ -12,12 +13,12 @@ namespace Artemis.Core
///
/// Describes a configuration dialog for a specific plugin
///
- public abstract class PluginConfigurationDialog
+ public abstract class PluginConfigurationDialog : IPluginConfigurationDialog
{
///
/// The layer brush this dialog belongs to
///
- internal PluginImplementation PluginImplementation { get; set; }
+ internal PluginFeature PluginFeature { get; set; }
///
/// The type of view model the tab contains
diff --git a/src/Artemis.Core/Plugins/PluginConfigurationViewModel.cs b/src/Artemis.UI.Shared/Plugins/PluginConfigurationViewModel.cs
similarity index 50%
rename from src/Artemis.Core/Plugins/PluginConfigurationViewModel.cs
rename to src/Artemis.UI.Shared/Plugins/PluginConfigurationViewModel.cs
index e4a60afbc..61e88a503 100644
--- a/src/Artemis.Core/Plugins/PluginConfigurationViewModel.cs
+++ b/src/Artemis.UI.Shared/Plugins/PluginConfigurationViewModel.cs
@@ -1,34 +1,35 @@
-using Stylet;
+using Artemis.Core;
+using Stylet;
-namespace Artemis.Core
+namespace Artemis.UI.Shared
{
///
/// Represents a view model for a plugin configuration window
///
- public abstract class PluginConfigurationViewModel : Screen
+ public abstract class PluginConfigurationViewModel : Screen, IPluginConfigurationViewModel
{
///
/// Creates a new instance of the class
///
- ///
- protected PluginConfigurationViewModel(PluginImplementation pluginImplementation)
+ ///
+ protected PluginConfigurationViewModel(Plugin plugin)
{
- PluginImplementation = pluginImplementation;
+ Plugin = plugin;
}
///
/// Creates a new instance of the class with a validator
///
- ///
+ ///
///
- protected PluginConfigurationViewModel(PluginImplementation pluginImplementation, IModelValidator validator) : base(validator)
+ protected PluginConfigurationViewModel(Plugin plugin, IModelValidator validator) : base(validator)
{
- PluginImplementation = pluginImplementation;
+ Plugin = plugin;
}
///
/// Gets the plugin this configuration view model is associated with
///
- public PluginImplementation PluginImplementation { get; }
+ public Plugin Plugin { get; }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI.Shared/PropertyInput/PropertyInputRegistration.cs b/src/Artemis.UI.Shared/PropertyInput/PropertyInputRegistration.cs
index cebb27fcc..3db1233fc 100644
--- a/src/Artemis.UI.Shared/PropertyInput/PropertyInputRegistration.cs
+++ b/src/Artemis.UI.Shared/PropertyInput/PropertyInputRegistration.cs
@@ -8,25 +8,25 @@ namespace Artemis.UI.Shared
{
private readonly IProfileEditorService _profileEditorService;
- internal PropertyInputRegistration(IProfileEditorService profileEditorService, PluginInfo pluginInfo, Type supportedType, Type viewModelType)
+ internal PropertyInputRegistration(IProfileEditorService profileEditorService, Plugin plugin, Type supportedType, Type viewModelType)
{
_profileEditorService = profileEditorService;
- PluginInfo = pluginInfo;
+ Plugin = plugin;
SupportedType = supportedType;
ViewModelType = viewModelType;
- if (PluginInfo != Constants.CorePluginInfo)
- PluginInfo.Plugin.Disabled += InstanceOnDisabled;
+ if (Plugin != Constants.CorePlugin)
+ Plugin.Disabled += InstanceOnDisabled;
}
- public PluginInfo PluginInfo { get; }
+ public Plugin Plugin { get; }
public Type SupportedType { get; }
public Type ViewModelType { get; }
internal void Unsubscribe()
{
- if (PluginInfo != Constants.CorePluginInfo)
- PluginInfo.Plugin.Disabled -= InstanceOnDisabled;
+ if (Plugin != Constants.CorePlugin)
+ Plugin.Disabled -= InstanceOnDisabled;
}
private void InstanceOnDisabled(object sender, EventArgs e)
diff --git a/src/Artemis.UI.Shared/Services/DataModelUIService.cs b/src/Artemis.UI.Shared/Services/DataModelUIService.cs
index 1493fbd2d..d2399a3b8 100644
--- a/src/Artemis.UI.Shared/Services/DataModelUIService.cs
+++ b/src/Artemis.UI.Shared/Services/DataModelUIService.cs
@@ -42,24 +42,24 @@ namespace Artemis.UI.Shared.Services
return viewModel;
}
- public DataModelPropertiesViewModel GetPluginDataModelVisualization(PluginImplementation pluginImplementation, bool includeMainDataModel)
+ public DataModelPropertiesViewModel GetPluginDataModelVisualization(PluginFeature pluginFeature, bool includeMainDataModel)
{
if (includeMainDataModel)
{
DataModelPropertiesViewModel mainDataModel = GetMainDataModelVisualization();
// If the main data model already includes the plugin data model we're done
- if (mainDataModel.Children.Any(c => c.DataModel.Implementation.Instance == pluginImplementation))
+ if (mainDataModel.Children.Any(c => c.DataModel.Feature == pluginFeature))
return mainDataModel;
// Otherwise get just the plugin data model and add it
- DataModelPropertiesViewModel pluginDataModel = GetPluginDataModelVisualization(pluginImplementation, false);
+ DataModelPropertiesViewModel pluginDataModel = GetPluginDataModelVisualization(pluginFeature, false);
if (pluginDataModel != null)
mainDataModel.Children.Add(pluginDataModel);
return mainDataModel;
}
- DataModel dataModel = _dataModelService.GetPluginDataModel(pluginImplementation);
+ DataModel dataModel = _dataModelService.GetPluginDataModel(pluginFeature);
if (dataModel == null)
return null;
@@ -72,7 +72,7 @@ namespace Artemis.UI.Shared.Services
return viewModel;
}
- public DataModelVisualizationRegistration RegisterDataModelInput(PluginInfo pluginInfo, IReadOnlyCollection compatibleConversionTypes = null) where T : DataModelInputViewModel
+ public DataModelVisualizationRegistration RegisterDataModelInput(Plugin plugin, IReadOnlyCollection compatibleConversionTypes = null) where T : DataModelInputViewModel
{
if (compatibleConversionTypes == null)
compatibleConversionTypes = new List();
@@ -83,19 +83,16 @@ namespace Artemis.UI.Shared.Services
DataModelVisualizationRegistration existing = _registeredDataModelEditors.FirstOrDefault(r => r.SupportedType == supportedType);
if (existing != null)
{
- if (existing.PluginInfo != pluginInfo)
- {
- throw new ArtemisPluginException($"Cannot register data model input for type {supportedType.Name} " +
- $"because an editor was already registered by {pluginInfo.Name}");
- }
-
+ if (existing.Plugin != plugin)
+ throw new ArtemisPluginException($"Cannot register data model input for type {supportedType.Name} because an editor was already" +
+ $" registered by {existing.Plugin}");
return existing;
}
_kernel.Bind(viewModelType).ToSelf();
// Create the registration
- DataModelVisualizationRegistration registration = new DataModelVisualizationRegistration(this, RegistrationType.Input, pluginInfo, supportedType, viewModelType)
+ DataModelVisualizationRegistration registration = new DataModelVisualizationRegistration(this, RegistrationType.Input, plugin, supportedType, viewModelType)
{
// Apply the compatible conversion types to the registration
CompatibleConversionTypes = compatibleConversionTypes
@@ -106,7 +103,7 @@ namespace Artemis.UI.Shared.Services
}
}
- public DataModelVisualizationRegistration RegisterDataModelDisplay(PluginInfo pluginInfo) where T : DataModelDisplayViewModel
+ public DataModelVisualizationRegistration RegisterDataModelDisplay(Plugin plugin) where T : DataModelDisplayViewModel
{
Type viewModelType = typeof(T);
lock (_registeredDataModelDisplays)
@@ -115,17 +112,14 @@ namespace Artemis.UI.Shared.Services
DataModelVisualizationRegistration existing = _registeredDataModelDisplays.FirstOrDefault(r => r.SupportedType == supportedType);
if (existing != null)
{
- if (existing.PluginInfo != pluginInfo)
- {
- throw new ArtemisPluginException($"Cannot register data model display for type {supportedType.Name} " +
- $"because an editor was already registered by {pluginInfo.Name}");
- }
-
+ if (existing.Plugin != plugin)
+ throw new ArtemisPluginException($"Cannot register data model display for type {supportedType.Name} because an editor was already" +
+ $" registered by {existing.Plugin}");
return existing;
}
_kernel.Bind(viewModelType).ToSelf();
- DataModelVisualizationRegistration registration = new DataModelVisualizationRegistration(this, RegistrationType.Display, pluginInfo, supportedType, viewModelType);
+ DataModelVisualizationRegistration registration = new DataModelVisualizationRegistration(this, RegistrationType.Display, plugin, supportedType, viewModelType);
_registeredDataModelDisplays.Add(registration);
return registration;
}
@@ -167,7 +161,7 @@ namespace Artemis.UI.Shared.Services
DataModelVisualizationRegistration match = _registeredDataModelDisplays.FirstOrDefault(d => d.SupportedType == propertyType);
if (match != null)
- result = (DataModelDisplayViewModel) match.PluginInfo.Kernel.Get(match.ViewModelType);
+ result = (DataModelDisplayViewModel) match.Plugin.Kernel.Get(match.ViewModelType);
else if (!fallBackToDefault)
result = null;
else
@@ -220,11 +214,12 @@ namespace Artemis.UI.Shared.Services
if (initialValue != null && initialValue.GetType() != registration.SupportedType)
initialValue = Convert.ChangeType(initialValue, registration.SupportedType);
- IParameter[] parameters = {
+ IParameter[] parameters =
+ {
new ConstructorArgument("targetDescription", description),
new ConstructorArgument("initialValue", initialValue)
};
- DataModelInputViewModel viewModel = (DataModelInputViewModel) registration.PluginInfo.Kernel.Get(registration.ViewModelType, parameters);
+ DataModelInputViewModel viewModel = (DataModelInputViewModel) registration.Plugin.Kernel.Get(registration.ViewModelType, parameters);
viewModel.CompatibleConversionTypes = registration.CompatibleConversionTypes;
return viewModel;
}
diff --git a/src/Artemis.UI.Shared/Services/Dialog/DialogService.cs b/src/Artemis.UI.Shared/Services/Dialog/DialogService.cs
index 25066daff..a62dcf014 100644
--- a/src/Artemis.UI.Shared/Services/Dialog/DialogService.cs
+++ b/src/Artemis.UI.Shared/Services/Dialog/DialogService.cs
@@ -109,11 +109,12 @@ namespace Artemis.UI.Shared.Services
private async Task
- ///
+ ///
///
- PropertyInputRegistration RegisterPropertyInput(PluginInfo pluginInfo) where T : PropertyInputViewModel;
+ PropertyInputRegistration RegisterPropertyInput(Plugin plugin) where T : PropertyInputViewModel;
///
/// Registers a new property input view model used in the profile editor for the generic type defined in
@@ -81,9 +81,9 @@ namespace Artemis.UI.Shared.Services
/// Note: Registration will remove itself on plugin disable so you don't have to
///
///
- ///
+ ///
///
- PropertyInputRegistration RegisterPropertyInput(Type viewModelType, PluginInfo pluginInfo);
+ PropertyInputRegistration RegisterPropertyInput(Type viewModelType, Plugin plugin);
void RemovePropertyInput(PropertyInputRegistration registration);
diff --git a/src/Artemis.UI.Shared/Services/ProfileEditorService.cs b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
index f50b80185..0dca8e593 100644
--- a/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
+++ b/src/Artemis.UI.Shared/Services/ProfileEditorService.cs
@@ -177,12 +177,12 @@ namespace Artemis.UI.Shared.Services
return true;
}
- public PropertyInputRegistration RegisterPropertyInput(PluginInfo pluginInfo) where T : PropertyInputViewModel
+ public PropertyInputRegistration RegisterPropertyInput(Plugin plugin) where T : PropertyInputViewModel
{
- return RegisterPropertyInput(typeof(T), pluginInfo);
+ return RegisterPropertyInput(typeof(T), plugin);
}
- public PropertyInputRegistration RegisterPropertyInput(Type viewModelType, PluginInfo pluginInfo)
+ public PropertyInputRegistration RegisterPropertyInput(Type viewModelType, Plugin plugin)
{
if (!typeof(PropertyInputViewModel).IsAssignableFrom(viewModelType))
throw new ArtemisSharedUIException($"Property input VM type must implement {nameof(PropertyInputViewModel)}");
@@ -201,13 +201,14 @@ namespace Artemis.UI.Shared.Services
PropertyInputRegistration existing = _registeredPropertyEditors.FirstOrDefault(r => r.SupportedType == supportedType);
if (existing != null)
{
- if (existing.PluginInfo != pluginInfo)
- throw new ArtemisPluginException($"Cannot register property editor for type {supportedType.Name} because an editor was already registered by {existing.PluginInfo.Name}");
+ if (existing.Plugin != plugin)
+ throw new ArtemisPluginException($"Cannot register property editor for type {supportedType.Name} because an editor was already " +
+ $"registered by {existing.Plugin}");
return existing;
}
Kernel.Bind(viewModelType).ToSelf();
- PropertyInputRegistration registration = new PropertyInputRegistration(this, pluginInfo, supportedType, viewModelType);
+ PropertyInputRegistration registration = new PropertyInputRegistration(this, plugin, supportedType, viewModelType);
_registeredPropertyEditors.Add(registration);
return registration;
}
@@ -281,7 +282,7 @@ namespace Artemis.UI.Shared.Services
return null;
ConstructorArgument parameter = new ConstructorArgument("layerProperty", layerProperty);
- IKernel kernel = registration != null ? registration.PluginInfo.Kernel : Kernel;
+ IKernel kernel = registration != null ? registration.Plugin.Kernel : Kernel;
return (PropertyInputViewModel) kernel.Get(viewModelType, parameter);
}
diff --git a/src/Artemis.UI.Shared/Utilities/PluginUtilities.cs b/src/Artemis.UI.Shared/Utilities/PluginUtilities.cs
index 140b104bd..cdf75ad1c 100644
--- a/src/Artemis.UI.Shared/Utilities/PluginUtilities.cs
+++ b/src/Artemis.UI.Shared/Utilities/PluginUtilities.cs
@@ -14,13 +14,13 @@ namespace Artemis.UI.Shared
///
/// Transforms the provided icon so that it is usable by the control
///
- /// The info of the plugin the icon belongs to
+ /// The plugin the icon belongs to
///
/// The icon, may be a string representation of a or a relative path
/// pointing to a .svg file
///
///
- public static object GetPluginIcon(PluginInfo pluginInfo, string icon)
+ public static object GetPluginIcon(Plugin plugin, string icon)
{
if (icon == null)
return PackIconKind.QuestionMarkCircle;
@@ -28,7 +28,7 @@ namespace Artemis.UI.Shared
// Icon is provided as a path
if (icon.EndsWith(".svg"))
{
- string iconPath = pluginInfo.ResolveRelativePath(icon);
+ string iconPath = plugin.ResolveRelativePath(icon);
if (!File.Exists(iconPath))
return PackIconKind.QuestionMarkCircle;
return iconPath;
diff --git a/src/Artemis.UI.Shared/packages.lock.json b/src/Artemis.UI.Shared/packages.lock.json
index 6f3d41d90..7df90fbc1 100644
--- a/src/Artemis.UI.Shared/packages.lock.json
+++ b/src/Artemis.UI.Shared/packages.lock.json
@@ -1300,7 +1300,6 @@
"Serilog.Sinks.Debug": "1.0.1",
"Serilog.Sinks.File": "4.1.0",
"SkiaSharp": "1.68.3",
- "Stylet": "1.3.4",
"System.Buffers": "4.5.0",
"System.Numerics.Vectors": "4.5.0",
"System.Reflection.Metadata": "1.8.0",
diff --git a/src/Artemis.UI/Bootstrapper.cs b/src/Artemis.UI/Bootstrapper.cs
index dbced1ec0..7eb1fec3f 100644
--- a/src/Artemis.UI/Bootstrapper.cs
+++ b/src/Artemis.UI/Bootstrapper.cs
@@ -39,6 +39,8 @@ namespace Artemis.UI
protected override void Launch()
{
+ Core.Utilities.ShutdownRequested += UtilitiesOnShutdownRequested;
+
ILogger logger = Kernel.Get();
IViewManager viewManager = Kernel.Get();
@@ -84,6 +86,11 @@ namespace Artemis.UI
});
}
+ private void UtilitiesOnShutdownRequested(object? sender, EventArgs e)
+ {
+ Execute.OnUIThread(() => Application.Current.Shutdown());
+ }
+
protected override void ConfigureIoC(IKernel kernel)
{
kernel.Settings.InjectNonPublic = true;
diff --git a/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputViewModel.cs b/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputViewModel.cs
index a7a3b0e53..9f4699243 100644
--- a/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputViewModel.cs
+++ b/src/Artemis.UI/DefaultTypes/PropertyInput/BrushPropertyInputViewModel.cs
@@ -39,7 +39,7 @@ namespace Artemis.UI.PropertyInput
public void UpdateEnumValues()
{
- List layerBrushProviders = _pluginManagementService.GetPluginsOfType();
+ List layerBrushProviders = _pluginManagementService.GetFeaturesOfType();
Descriptors = new BindableCollection(layerBrushProviders.SelectMany(l => l.LayerBrushDescriptors));
NotifyOfPropertyChange(nameof(SelectedDescriptor));
}
diff --git a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
index 3115c8e19..b73ccea26 100644
--- a/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
+++ b/src/Artemis.UI/Ninject/Factories/IVMFactory.cs
@@ -35,7 +35,8 @@ namespace Artemis.UI.Ninject.Factories
public interface ISettingsVmFactory : IVmFactory
{
- PluginSettingsViewModel CreatePluginSettingsViewModel(PluginImplementation pluginImplementation);
+ PluginSettingsViewModel CreatePluginSettingsViewModel(Plugin plugin);
+ PluginFeatureViewModel CreatePluginFeatureViewModel(PluginFeature feature);
DeviceSettingsViewModel CreateDeviceSettingsViewModel(ArtemisDevice device);
}
diff --git a/src/Artemis.UI/Ninject/PluginUIModule.cs b/src/Artemis.UI/Ninject/PluginUIModule.cs
index 5cccc2033..ae4d0d409 100644
--- a/src/Artemis.UI/Ninject/PluginUIModule.cs
+++ b/src/Artemis.UI/Ninject/PluginUIModule.cs
@@ -10,19 +10,19 @@ namespace Artemis.UI.Ninject
{
public class PluginUIModule : NinjectModule
{
- public PluginUIModule(PluginInfo pluginInfo)
+ public PluginUIModule(Plugin plugin)
{
- PluginInfo = pluginInfo ?? throw new ArgumentNullException(nameof(pluginInfo));
+ Plugin = plugin ?? throw new ArgumentNullException(nameof(plugin));
}
- public PluginInfo PluginInfo { get; }
+ public Plugin Plugin { get; }
public override void Load()
{
Bind(typeof(IModelValidator<>)).To(typeof(FluentValidationAdapter<>));
Kernel.Bind(x =>
{
- x.From(PluginInfo.Assembly)
+ x.From(Plugin.Assembly)
.SelectAllClasses()
.InheritedFrom()
.BindAllInterfaces();
diff --git a/src/Artemis.UI/Screens/Modules/ModuleRootViewModel.cs b/src/Artemis.UI/Screens/Modules/ModuleRootViewModel.cs
index 1986f77b0..90b7e1330 100644
--- a/src/Artemis.UI/Screens/Modules/ModuleRootViewModel.cs
+++ b/src/Artemis.UI/Screens/Modules/ModuleRootViewModel.cs
@@ -2,6 +2,7 @@
using System.Linq;
using Artemis.Core.Modules;
using Artemis.UI.Ninject.Factories;
+using Artemis.UI.Shared.Modules;
using Ninject;
using Ninject.Parameters;
using Stylet;
@@ -45,7 +46,7 @@ namespace Artemis.UI.Screens.Modules
ConstructorArgument module = new ConstructorArgument("module", Module);
ConstructorArgument displayName = new ConstructorArgument("displayName", DisplayName);
- ModuleViewModel viewModel = (ModuleViewModel) Module.PluginInfo.Kernel.Get(moduleTab.Type, module, displayName);
+ ModuleViewModel viewModel = (ModuleViewModel) Module.Plugin.Kernel.Get(moduleTab.Type, module, displayName);
Items.Add(viewModel);
}
}
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerEffects/EffectsViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerEffects/EffectsViewModel.cs
index 8ab195a6f..c3e43e965 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerEffects/EffectsViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/LayerEffects/EffectsViewModel.cs
@@ -35,7 +35,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.LayerEffects
public void PopulateDescriptors()
{
- List layerBrushProviders = _pluginManagementService.GetPluginsOfType();
+ List layerBrushProviders = _pluginManagementService.GetFeaturesOfType();
List descriptors = layerBrushProviders.SelectMany(l => l.LayerEffectDescriptors).ToList();
Items.AddRange(descriptors.Except(Items));
Items.RemoveRange(Items.Except(descriptors));
diff --git a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreeGroupViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreeGroupViewModel.cs
index 48d37fe72..a78c57aae 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreeGroupViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/LayerProperties/Tree/TreeGroupViewModel.cs
@@ -9,6 +9,8 @@ using Artemis.Core.LayerEffects;
using Artemis.UI.Exceptions;
using Artemis.UI.Screens.ProfileEditor.Dialogs;
using Artemis.UI.Screens.ProfileEditor.Windows;
+using Artemis.UI.Shared.LayerBrushes;
+using Artemis.UI.Shared.LayerEffects;
using Artemis.UI.Shared.Services;
using Ninject;
using Ninject.Parameters;
@@ -18,6 +20,15 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
{
public class TreeGroupViewModel : PropertyChangedBase
{
+ public enum LayerPropertyGroupType
+ {
+ General,
+ Transform,
+ LayerBrushRoot,
+ LayerEffectRoot,
+ None
+ }
+
private readonly IDialogService _dialogService;
private readonly IKernel _kernel;
private readonly IProfileEditorService _profileEditorService;
@@ -55,7 +66,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
public void OpenBrushSettings()
{
BaseLayerBrush layerBrush = LayerPropertyGroup.LayerBrush;
- LayerBrushConfigurationDialog configurationViewModel = layerBrush.ConfigurationDialog;
+ LayerBrushConfigurationDialog configurationViewModel = (LayerBrushConfigurationDialog) layerBrush.ConfigurationDialog;
if (configurationViewModel == null)
return;
@@ -69,7 +80,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
// Find the BaseLayerBrush parameter, it is required by the base constructor so its there for sure
ParameterInfo brushParameter = constructors.First().GetParameters().First(p => typeof(BaseLayerBrush).IsAssignableFrom(p.ParameterType));
ConstructorArgument argument = new ConstructorArgument(brushParameter.Name, layerBrush);
- BrushConfigurationViewModel viewModel = (BrushConfigurationViewModel) layerBrush.PluginInfo.Kernel.Get(configurationViewModel.Type, argument);
+ BrushConfigurationViewModel viewModel = (BrushConfigurationViewModel) layerBrush.Descriptor.Provider.Plugin.Kernel.Get(configurationViewModel.Type, argument);
_windowManager.ShowDialog(new LayerBrushSettingsWindowViewModel(viewModel));
}
@@ -82,7 +93,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
public void OpenEffectSettings()
{
BaseLayerEffect layerEffect = LayerPropertyGroup.LayerEffect;
- LayerEffectConfigurationDialog configurationViewModel = layerEffect.ConfigurationDialog;
+ LayerEffectConfigurationDialog configurationViewModel = (LayerEffectConfigurationDialog) layerEffect.ConfigurationDialog;
if (configurationViewModel == null)
return;
@@ -95,7 +106,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
ParameterInfo effectParameter = constructors.First().GetParameters().First(p => typeof(BaseLayerEffect).IsAssignableFrom(p.ParameterType));
ConstructorArgument argument = new ConstructorArgument(effectParameter.Name, layerEffect);
- EffectConfigurationViewModel viewModel = (EffectConfigurationViewModel) layerEffect.PluginInfo.Kernel.Get(configurationViewModel.Type, argument);
+ EffectConfigurationViewModel viewModel = (EffectConfigurationViewModel) layerEffect.Descriptor.Provider.Plugin.Kernel.Get(configurationViewModel.Type, argument);
_windowManager.ShowDialog(new LayerEffectSettingsWindowViewModel(viewModel));
}
catch (Exception e)
@@ -169,14 +180,5 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.Tree
else
GroupType = LayerPropertyGroupType.None;
}
-
- public enum LayerPropertyGroupType
- {
- General,
- Transform,
- LayerBrushRoot,
- LayerEffectRoot,
- None
- }
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Windows/LayerBrushSettingsWindowViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Windows/LayerBrushSettingsWindowViewModel.cs
index a1601ce90..682be6025 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Windows/LayerBrushSettingsWindowViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/Windows/LayerBrushSettingsWindowViewModel.cs
@@ -1,5 +1,5 @@
using System;
-using Artemis.Core.LayerBrushes;
+using Artemis.UI.Shared.LayerBrushes;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.Windows
diff --git a/src/Artemis.UI/Screens/ProfileEditor/Windows/LayerEffectSettingsWindowViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/Windows/LayerEffectSettingsWindowViewModel.cs
index cf759dde2..6d2438bdf 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/Windows/LayerEffectSettingsWindowViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/Windows/LayerEffectSettingsWindowViewModel.cs
@@ -1,5 +1,5 @@
using System;
-using Artemis.Core.LayerEffects;
+using Artemis.UI.Shared.LayerEffects;
using Stylet;
namespace Artemis.UI.Screens.ProfileEditor.Windows
diff --git a/src/Artemis.UI/Screens/Settings/Debug/DeviceDebugViewModel.cs b/src/Artemis.UI/Screens/Settings/Debug/DeviceDebugViewModel.cs
index 198d0f846..f5b534518 100644
--- a/src/Artemis.UI/Screens/Settings/Debug/DeviceDebugViewModel.cs
+++ b/src/Artemis.UI/Screens/Settings/Debug/DeviceDebugViewModel.cs
@@ -55,7 +55,7 @@ namespace Artemis.UI.Screens.Settings.Debug
{
try
{
- Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Device.PluginImplementation.PluginInfo.Directory.FullName);
+ Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Device.PluginFeature.Plugin.Directory.FullName);
}
catch (Exception e)
{
diff --git a/src/Artemis.UI/Screens/Settings/Debug/Tabs/DataModelDebugViewModel.cs b/src/Artemis.UI/Screens/Settings/Debug/Tabs/DataModelDebugViewModel.cs
index 2bd2a2b79..9b1e61659 100644
--- a/src/Artemis.UI/Screens/Settings/Debug/Tabs/DataModelDebugViewModel.cs
+++ b/src/Artemis.UI/Screens/Settings/Debug/Tabs/DataModelDebugViewModel.cs
@@ -117,7 +117,7 @@ namespace Artemis.UI.Screens.Settings.Debug.Tabs
private void PopulateModules()
{
- Modules = _pluginManagementService.GetPluginsOfType().Where(p => p.IsEnabled).ToList();
+ Modules = _pluginManagementService.GetFeaturesOfType().Where(p => p.IsEnabled).ToList();
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsViewModel.cs
index 5093f01df..a89933790 100644
--- a/src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsViewModel.cs
+++ b/src/Artemis.UI/Screens/Settings/Tabs/Devices/DeviceSettingsViewModel.cs
@@ -60,7 +60,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Devices
{
try
{
- Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Device.PluginImplementation.PluginInfo.Directory.FullName);
+ Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Device.PluginFeature.Plugin.Directory.FullName);
}
catch (Exception e)
{
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs
index d9d405546..06c65f3c4 100644
--- a/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs
+++ b/src/Artemis.UI/Screens/Settings/Tabs/General/GeneralSettingsTabViewModel.cs
@@ -46,12 +46,12 @@ namespace Artemis.UI.Screens.Settings.Tabs.General
// Anything else is kinda broken right now
SampleSizes = new List {1, 9};
- List layerBrushProviders = pluginManagementService.GetPluginsOfType();
+ List layerBrushProviders = pluginManagementService.GetFeaturesOfType();
LayerBrushDescriptors = new BindableCollection(layerBrushProviders.SelectMany(l => l.LayerBrushDescriptors));
_defaultLayerBrushDescriptor = _settingsService.GetSetting("ProfileEditor.DefaultLayerBrushDescriptor", new LayerBrushReference
{
- BrushPluginGuid = Guid.Parse("92a9d6ba-6f7a-4937-94d5-c1d715b4141a"),
+ LayerBrushProviderId = "Artemis.Plugins.LayerBrushes.Color.ColorBrushProvider-92a9d6ba",
BrushType = "ColorBrush"
});
}
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabViewModel.cs
index a0e92df46..ec0d8ad41 100644
--- a/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabViewModel.cs
+++ b/src/Artemis.UI/Screens/Settings/Tabs/Modules/ModuleOrderTabViewModel.cs
@@ -20,7 +20,7 @@ namespace Artemis.UI.Screens.Settings.Tabs.Modules
_pluginManagementService = pluginManagementService;
_moduleService = moduleService;
- _modules = new List(pluginManagementService.GetPluginsOfType().Select(m => new ModuleOrderModuleViewModel(m)));
+ _modules = new List(pluginManagementService.GetFeaturesOfType().Select(m => new ModuleOrderModuleViewModel(m)));
_defaultDropHandler = new DefaultDropHandler();
NormalModules = new BindableCollection();
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginFeatureView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginFeatureView.xaml
new file mode 100644
index 000000000..8ef815d40
--- /dev/null
+++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginFeatureView.xaml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Feature enabled
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginFeatureViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginFeatureViewModel.cs
new file mode 100644
index 000000000..9ee01e301
--- /dev/null
+++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginFeatureViewModel.cs
@@ -0,0 +1,160 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Threading.Tasks;
+using Artemis.Core;
+using Artemis.Core.DataModelExpansions;
+using Artemis.Core.DeviceProviders;
+using Artemis.Core.LayerBrushes;
+using Artemis.Core.LayerEffects;
+using Artemis.Core.Modules;
+using Artemis.Core.Services;
+using Artemis.UI.Shared.Services;
+using Humanizer;
+using MaterialDesignThemes.Wpf;
+using Stylet;
+
+namespace Artemis.UI.Screens.Settings.Tabs.Plugins
+{
+ public class PluginFeatureViewModel : Screen
+ {
+ private readonly IDialogService _dialogService;
+ private readonly IPluginManagementService _pluginManagementService;
+ private readonly ISnackbarMessageQueue _snackbarMessageQueue;
+ private bool _enabling;
+ private bool _isEnabled;
+
+ public PluginFeatureViewModel(PluginFeature feature,
+ IDialogService dialogService,
+ IPluginManagementService pluginManagementService,
+ ISnackbarMessageQueue snackbarMessageQueue)
+ {
+ _dialogService = dialogService;
+ _pluginManagementService = pluginManagementService;
+ _snackbarMessageQueue = snackbarMessageQueue;
+
+ Feature = feature;
+ Icon = GetIconKind();
+
+ IsEnabled = Feature.IsEnabled;
+ }
+
+ public PluginFeature Feature { get; }
+ public PackIconKind Icon { get; }
+
+ public string Name => Feature.GetType().Name.Humanize();
+
+ public Exception LoadException => Feature.LoadException;
+
+ public bool Enabling
+ {
+ get => _enabling;
+ set => SetAndNotify(ref _enabling, value);
+ }
+
+ public bool IsEnabled
+ {
+ get => _isEnabled;
+ set => SetAndNotify(ref _isEnabled, value);
+ }
+
+ public void ShowLogsFolder()
+ {
+ try
+ {
+ Process.Start(Environment.GetEnvironmentVariable("WINDIR") + @"\explorer.exe", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"));
+ }
+ catch (Exception e)
+ {
+ _dialogService.ShowExceptionDialog("Welp, we couldn\'t open the logs folder for you", e);
+ }
+ }
+
+ protected override void OnInitialActivate()
+ {
+ base.OnInitialActivate();
+ _pluginManagementService.PluginFeatureEnabling += OnFeatureEnabling;
+ _pluginManagementService.PluginFeatureEnabled += OnFeatureEnableStopped;
+ _pluginManagementService.PluginFeatureEnableFailed += OnFeatureEnableStopped;
+ }
+
+ protected override void OnClose()
+ {
+ base.OnClose();
+ _pluginManagementService.PluginFeatureEnabling -= OnFeatureEnabling;
+ _pluginManagementService.PluginFeatureEnabled -= OnFeatureEnableStopped;
+ _pluginManagementService.PluginFeatureEnableFailed -= OnFeatureEnableStopped;
+ }
+
+ private async Task UpdateEnabled(bool enable)
+ {
+ if (IsEnabled == enable)
+ {
+ NotifyOfPropertyChange(nameof(IsEnabled));
+ return;
+ }
+
+ if (enable)
+ {
+ Enabling = true;
+
+ try
+ {
+ await Task.Run(() => _pluginManagementService.EnablePluginFeature(Feature));
+ }
+ catch (Exception e)
+ {
+ _snackbarMessageQueue.Enqueue($"Failed to enable {Name}\r\n{e.Message}", "VIEW LOGS", ShowLogsFolder);
+ }
+ finally
+ {
+ Enabling = false;
+ }
+ }
+ else
+ {
+ _pluginManagementService.DisablePluginFeature(Feature);
+ }
+ }
+
+ private PackIconKind GetIconKind()
+ {
+ switch (Feature)
+ {
+ case BaseDataModelExpansion _:
+ return PackIconKind.TableAdd;
+ case DeviceProvider _:
+ return PackIconKind.Devices;
+ case ProfileModule _:
+ return PackIconKind.VectorRectangle;
+ case Module _:
+ return PackIconKind.GearBox;
+ case LayerBrushProvider _:
+ return PackIconKind.Brush;
+ case LayerEffectProvider _:
+ return PackIconKind.AutoAwesome;
+ }
+
+ return PackIconKind.Plugin;
+ }
+
+ #region Event handlers
+
+ private void OnFeatureEnabling(object? sender, PluginFeatureEventArgs e)
+ {
+ if (e.PluginFeature != Feature) return;
+ Enabling = true;
+ }
+
+ private void OnFeatureEnableStopped(object? sender, PluginFeatureEventArgs e)
+ {
+ if (e.PluginFeature != Feature) return;
+ Enabling = false;
+ IsEnabled = e.PluginFeature.IsEnabled;
+
+ NotifyOfPropertyChange(nameof(LoadException));
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabViewModel.cs
index 82488df16..34861783a 100644
--- a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabViewModel.cs
+++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsTabViewModel.cs
@@ -11,7 +11,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
{
private readonly IPluginManagementService _pluginManagementService;
private readonly ISettingsVmFactory _settingsVmFactory;
- private BindableCollection _plugins;
public PluginSettingsTabViewModel(IPluginManagementService pluginManagementService, ISettingsVmFactory settingsVmFactory)
{
@@ -29,8 +28,8 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
Items.Clear();
await Task.Delay(200);
- List instances = _pluginManagementService.GetAllPluginInfo().Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p.Plugin)).ToList();
- foreach (PluginSettingsViewModel pluginSettingsViewModel in instances)
+ List instances = _pluginManagementService.GetAllPlugins().Select(p => _settingsVmFactory.CreatePluginSettingsViewModel(p)).ToList();
+ foreach (PluginSettingsViewModel pluginSettingsViewModel in instances.OrderBy(i => i.Plugin.Info.Name))
Items.Add(pluginSettingsViewModel);
});
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml
index 0a5b1baf8..ac3de8a64 100644
--- a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml
+++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsView.xaml
@@ -6,17 +6,19 @@
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:devices="clr-namespace:Artemis.UI.Screens.Settings.Tabs.Plugins"
+ xmlns:controls="clr-namespace:Artemis.UI.Shared.Controls;assembly=Artemis.UI.Shared"
d:DataContext="{d:DesignInstance devices:PluginSettingsViewModel}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
-
+
-
+
+
-
+
@@ -24,45 +26,27 @@
-
-
-
-
-
-
+
+
+
@@ -82,6 +66,23 @@
Visibility="{Binding Enabling, Converter={x:Static s:BoolToVisibilityConverter.Instance}, Mode=OneWay}">
+
+
+
+ Plugin features
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsViewModel.cs
index 69f9076da..a67c87fe4 100644
--- a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsViewModel.cs
+++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsViewModel.cs
@@ -2,64 +2,50 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
-using System.Reflection;
using System.Threading.Tasks;
using Artemis.Core;
-using Artemis.Core.DataModelExpansions;
-using Artemis.Core.DeviceProviders;
-using Artemis.Core.LayerBrushes;
-using Artemis.Core.LayerEffects;
-using Artemis.Core.Modules;
using Artemis.Core.Services;
-using Artemis.UI.Exceptions;
+using Artemis.UI.Ninject.Factories;
+using Artemis.UI.Shared;
using Artemis.UI.Shared.Services;
using MaterialDesignThemes.Wpf;
using Ninject;
-using Ninject.Parameters;
-using Serilog;
using Stylet;
-using Module = Artemis.Core.Modules.Module;
namespace Artemis.UI.Screens.Settings.Tabs.Plugins
{
- public class PluginSettingsViewModel : PropertyChangedBase
+ public class PluginSettingsViewModel : Conductor.Collection.AllActive
{
private readonly IDialogService _dialogService;
- private readonly ILogger _logger;
private readonly IPluginManagementService _pluginManagementService;
+ private readonly ISettingsVmFactory _settingsVmFactory;
private readonly ISnackbarMessageQueue _snackbarMessageQueue;
private readonly IWindowManager _windowManager;
private bool _enabling;
- private PluginImplementation _pluginImplementation;
- private PluginInfo _pluginInfo;
+ private Plugin _plugin;
- public PluginSettingsViewModel(PluginImplementation pluginImplementation,
- ILogger logger,
+ public PluginSettingsViewModel(Plugin plugin,
+ ISettingsVmFactory settingsVmFactory,
IWindowManager windowManager,
IDialogService dialogService,
IPluginManagementService pluginManagementService,
ISnackbarMessageQueue snackbarMessageQueue)
{
- PluginImplementation = pluginImplementation;
- PluginInfo = pluginImplementation.PluginInfo;
+ Plugin = plugin;
- _logger = logger;
+ _settingsVmFactory = settingsVmFactory;
_windowManager = windowManager;
_dialogService = dialogService;
_pluginManagementService = pluginManagementService;
_snackbarMessageQueue = snackbarMessageQueue;
+
+ Icon = PluginUtilities.GetPluginIcon(Plugin, Plugin.Info.Icon);
}
- public PluginImplementation PluginImplementation
+ public Plugin Plugin
{
- get => _pluginImplementation;
- set => SetAndNotify(ref _pluginImplementation, value);
- }
-
- public PluginInfo PluginInfo
- {
- get => _pluginInfo;
- set => SetAndNotify(ref _pluginInfo, value);
+ get => _plugin;
+ set => SetAndNotify(ref _plugin, value);
}
public bool Enabling
@@ -68,34 +54,25 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
set => SetAndNotify(ref _enabling, value);
}
- public PackIconKind Icon => GetIconKind();
- public string Type => PluginImplementation.GetType().BaseType?.Name ?? PluginImplementation.GetType().Name;
- public bool CanOpenSettings => IsEnabled && PluginImplementation.ConfigurationDialog != null;
- public bool DisplayLoadFailed => !Enabling && PluginInfo.LoadException != null;
- public bool RequiresRestart => PluginImplementation.IsEnabled && !PluginInfo.IsEnabled;
+ public object Icon { get; set; }
+ public string Type => Plugin.GetType().BaseType?.Name ?? Plugin.GetType().Name;
+ public bool CanOpenSettings => IsEnabled && Plugin.ConfigurationDialog != null;
public bool IsEnabled
{
- get => PluginImplementation.PluginInfo.IsEnabled;
+ get => Plugin.IsEnabled;
set => Task.Run(() => UpdateEnabled(value));
}
public void OpenSettings()
{
- PluginConfigurationDialog configurationViewModel = PluginImplementation.ConfigurationDialog;
+ PluginConfigurationDialog configurationViewModel = (PluginConfigurationDialog) Plugin.ConfigurationDialog;
if (configurationViewModel == null)
return;
try
{
- // Limit to one constructor, there's no need to have more and it complicates things anyway
- ConstructorInfo[] constructors = configurationViewModel.Type.GetConstructors();
- if (constructors.Length != 1)
- throw new ArtemisUIException("Plugin configuration dialogs must have exactly one constructor");
-
- ParameterInfo pluginParameter = constructors.First().GetParameters().First(p => typeof(PluginImplementation).IsAssignableFrom(p.ParameterType));
- ConstructorArgument plugin = new ConstructorArgument(pluginParameter.Name, PluginImplementation);
- PluginConfigurationViewModel viewModel = (PluginConfigurationViewModel) PluginInfo.Kernel.Get(configurationViewModel.Type, plugin);
+ PluginConfigurationViewModel viewModel = (PluginConfigurationViewModel) Plugin.Kernel.Get(configurationViewModel.Type);
_windowManager.ShowDialog(new PluginSettingsWindowViewModel(viewModel, Icon));
}
catch (Exception e)
@@ -117,49 +94,22 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
}
}
- public void ShowLoadException()
+ protected override void OnInitialActivate()
{
- if (PluginInfo.LoadException == null)
- return;
+ Plugin.FeatureAdded += PluginOnFeatureAdded;
+ Plugin.FeatureRemoved += PluginOnFeatureRemoved;
+ foreach (PluginFeature pluginFeature in Plugin.Features)
+ Items.Add(_settingsVmFactory.CreatePluginFeatureViewModel(pluginFeature));
- _dialogService.ShowExceptionDialog("The plugin failed to load: " + PluginInfo.LoadException.Message, PluginInfo.LoadException);
+ base.OnInitialActivate();
}
- public async Task Restart()
+ protected override void OnClose()
{
- _logger.Debug("Restarting for device provider disable {pluginInfo}", PluginImplementation.PluginInfo);
+ Plugin.FeatureAdded -= PluginOnFeatureAdded;
+ Plugin.FeatureRemoved -= PluginOnFeatureRemoved;
- // Give the logger a chance to write, might not always be enough but oh well
- await Task.Delay(500);
- Core.Utilities.Shutdown(2, true);
- }
-
- private PackIconKind GetIconKind()
- {
- if (PluginInfo.Icon != null)
- {
- bool parsedIcon = Enum.TryParse(PluginInfo.Icon, true, out PackIconKind iconEnum);
- if (parsedIcon)
- return iconEnum;
- }
-
- switch (PluginImplementation)
- {
- case BaseDataModelExpansion _:
- return PackIconKind.TableAdd;
- case DeviceProvider _:
- return PackIconKind.Devices;
- case ProfileModule _:
- return PackIconKind.VectorRectangle;
- case Module _:
- return PackIconKind.GearBox;
- case LayerBrushProvider _:
- return PackIconKind.Brush;
- case LayerEffectProvider _:
- return PackIconKind.AutoAwesome;
- }
-
- return PackIconKind.Plugin;
+ base.OnClose();
}
private async Task UpdateEnabled(bool enable)
@@ -170,24 +120,17 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
return;
}
- if (!enable && PluginImplementation is DeviceProvider)
- {
- await DisableDeviceProvider();
- return;
- }
-
if (enable)
{
Enabling = true;
- NotifyOfPropertyChange(nameof(DisplayLoadFailed));
try
{
- _pluginManagementService.EnablePluginImplementation(PluginImplementation);
+ await Task.Run(() => _pluginManagementService.EnablePlugin(Plugin));
}
catch (Exception e)
{
- _snackbarMessageQueue.Enqueue($"Failed to enable plugin {PluginInfo.Name}\r\n{e.Message}", "VIEW LOGS", ShowLogsFolder);
+ _snackbarMessageQueue.Enqueue($"Failed to enable plugin {Plugin.Info.Name}\r\n{e.Message}", "VIEW LOGS", ShowLogsFolder);
}
finally
{
@@ -195,44 +138,24 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
}
}
else
- _pluginManagementService.DisablePluginImplementation(PluginImplementation);
+ {
+ _pluginManagementService.DisablePlugin(Plugin);
+ }
NotifyOfPropertyChange(nameof(IsEnabled));
NotifyOfPropertyChange(nameof(CanOpenSettings));
- NotifyOfPropertyChange(nameof(RequiresRestart));
- NotifyOfPropertyChange(nameof(DisplayLoadFailed));
}
- private async Task DisableDeviceProvider()
+ private void PluginOnFeatureRemoved(object? sender, PluginFeatureEventArgs e)
{
- bool restart = false;
+ PluginFeatureViewModel viewModel = Items.FirstOrDefault(i => i.Feature == e.PluginFeature);
+ if (viewModel != null)
+ Items.Remove(viewModel);
+ }
- // If any plugin already requires a restart, don't ask the user again
- bool restartQueued = _pluginManagementService.GetAllPluginInfo().Any(p => p.Plugin != null && !p.IsEnabled && p.Plugin.IsEnabled);
- // If the plugin isn't enabled (load failed), it can be disabled without a restart
- if (!restartQueued && PluginImplementation.IsEnabled)
- {
- restart = await _dialogService.ShowConfirmDialog(
- "Disable device provider",
- "You are disabling a device provider, Artemis has to restart to \r\nfully disable this type of plugin",
- "Restart now",
- "Restart later"
- );
- }
-
- _pluginManagementService.DisablePluginImplementation(PluginImplementation);
- if (restart)
- {
- _logger.Debug("Restarting for device provider disable {pluginInfo}", PluginImplementation.PluginInfo);
-
- // Give the logger a chance to write, might not always be enough but oh well
- await Task.Delay(500);
- Core.Utilities.Shutdown(2, true);
- }
-
- NotifyOfPropertyChange(nameof(IsEnabled));
- NotifyOfPropertyChange(nameof(RequiresRestart));
- NotifyOfPropertyChange(nameof(DisplayLoadFailed));
+ private void PluginOnFeatureAdded(object? sender, PluginFeatureEventArgs e)
+ {
+ Items.Add(_settingsVmFactory.CreatePluginFeatureViewModel(e.PluginFeature));
}
}
}
\ No newline at end of file
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowView.xaml b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowView.xaml
index 87d080ca3..f8bbfa6a6 100644
--- a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowView.xaml
+++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowView.xaml
@@ -23,7 +23,7 @@
Identifier="PluginSettingsDialog"
DialogTheme="Inherit">
-
+
diff --git a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowViewModel.cs
index 4693ebba6..7f4a229f8 100644
--- a/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowViewModel.cs
+++ b/src/Artemis.UI/Screens/Settings/Tabs/Plugins/PluginSettingsWindowViewModel.cs
@@ -1,6 +1,5 @@
using System;
-using Artemis.Core;
-using MaterialDesignThemes.Wpf;
+using Artemis.UI.Shared;
using Stylet;
namespace Artemis.UI.Screens.Settings.Tabs.Plugins
@@ -9,12 +8,14 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
{
private readonly PluginConfigurationViewModel _configurationViewModel;
- public PluginSettingsWindowViewModel(PluginConfigurationViewModel configurationViewModel, PackIconKind icon)
+ public PluginSettingsWindowViewModel(PluginConfigurationViewModel configurationViewModel, object icon)
{
_configurationViewModel = configurationViewModel ?? throw new ArgumentNullException(nameof(configurationViewModel));
Icon = icon;
}
+ public object Icon { get; }
+
protected override void OnInitialActivate()
{
ActiveItem = _configurationViewModel;
@@ -23,8 +24,6 @@ namespace Artemis.UI.Screens.Settings.Tabs.Plugins
base.OnInitialActivate();
}
- public PackIconKind Icon { get; }
-
private void ActiveItemOnClosed(object sender, CloseEventArgs e)
{
ActiveItem.Closed -= ActiveItemOnClosed;
diff --git a/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs b/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs
index 6b77f99bf..b18d39f74 100644
--- a/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs
+++ b/src/Artemis.UI/Screens/Sidebar/SidebarViewModel.cs
@@ -1,10 +1,8 @@
using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
-using System.Windows.Media.Imaging;
using Artemis.Core;
using Artemis.Core.Modules;
using Artemis.Core.Services;
@@ -49,8 +47,8 @@ namespace Artemis.UI.Screens.Sidebar
_activeModulesUpdateTimer.Start();
_activeModulesUpdateTimer.Elapsed += ActiveModulesUpdateTimerOnElapsed;
- _pluginManagementService.PluginEnabled += PluginManagementServiceOnPluginManagementEnabled;
- _pluginManagementService.PluginDisabled += PluginManagementServiceOnPluginManagementDisabled;
+ _pluginManagementService.PluginFeatureEnabled += OnFeatureEnabled;
+ _pluginManagementService.PluginFeatureDisabled += OnFeatureDisabled;
SetupSidebar();
eventAggregator.Subscribe(this);
@@ -91,18 +89,6 @@ namespace Artemis.UI.Screens.Sidebar
}
}
- public void Dispose()
- {
- SelectedItem?.Deactivate();
- SelectedItem = null;
-
- _pluginManagementService.PluginEnabled -= PluginManagementServiceOnPluginManagementEnabled;
- _pluginManagementService.PluginDisabled -= PluginManagementServiceOnPluginManagementDisabled;
-
- _activeModulesUpdateTimer.Stop();
- _activeModulesUpdateTimer.Elapsed -= ActiveModulesUpdateTimerOnElapsed;
- }
-
public void SetupSidebar()
{
SidebarItems.Clear();
@@ -118,7 +104,7 @@ namespace Artemis.UI.Screens.Sidebar
// Add all activated modules
SidebarItems.Add(new DividerNavigationItem());
SidebarItems.Add(new SubheaderNavigationItem {Subheader = "Modules"});
- List modules = _pluginManagementService.GetPluginsOfType().ToList();
+ List modules = _pluginManagementService.GetFeaturesOfType().ToList();
foreach (Module module in modules)
AddModule(module);
@@ -146,7 +132,7 @@ namespace Artemis.UI.Screens.Sidebar
FirstLevelNavigationItem sidebarItem = new FirstLevelNavigationItem
{
- Icon = PluginUtilities.GetPluginIcon(module.PluginInfo, module.DisplayIcon),
+ Icon = PluginUtilities.GetPluginIcon(module.Plugin, module.DisplayIcon),
Label = module.DisplayName
};
SidebarItems.Add(sidebarItem);
@@ -208,17 +194,29 @@ namespace Artemis.UI.Screens.Sidebar
SelectedItem = SidebarModules.ContainsKey(sidebarItem) ? _moduleVmFactory.CreateModuleRootViewModel(SidebarModules[sidebarItem]) : null;
}
+ public void Dispose()
+ {
+ SelectedItem?.Deactivate();
+ SelectedItem = null;
+
+ _pluginManagementService.PluginFeatureEnabled -= OnFeatureEnabled;
+ _pluginManagementService.PluginFeatureDisabled -= OnFeatureDisabled;
+
+ _activeModulesUpdateTimer.Stop();
+ _activeModulesUpdateTimer.Elapsed -= ActiveModulesUpdateTimerOnElapsed;
+ }
+
#region Event handlers
- private void PluginManagementServiceOnPluginManagementEnabled(object sender, PluginEventArgs e)
+ private void OnFeatureEnabled(object? sender, PluginFeatureEventArgs e)
{
- if (e.PluginInfo.Plugin is Module module)
+ if (e.PluginFeature is Module module)
AddModule(module);
}
- private void PluginManagementServiceOnPluginManagementDisabled(object sender, PluginEventArgs e)
+ private void OnFeatureDisabled(object? sender, PluginFeatureEventArgs e)
{
- if (e.PluginInfo.Plugin is Module module)
+ if (e.PluginFeature is Module module)
RemoveModule(module);
}
diff --git a/src/Artemis.UI/Screens/Splash/SplashViewModel.cs b/src/Artemis.UI/Screens/Splash/SplashViewModel.cs
index e4fc1c2a4..dcb747bf6 100644
--- a/src/Artemis.UI/Screens/Splash/SplashViewModel.cs
+++ b/src/Artemis.UI/Screens/Splash/SplashViewModel.cs
@@ -2,6 +2,7 @@
using System.Windows.Input;
using Artemis.Core;
using Artemis.Core.Services;
+using Humanizer;
using MaterialDesignExtensions.Controls;
using Stylet;
@@ -42,6 +43,8 @@ namespace Artemis.UI.Screens.Splash
_pluginManagementService.PluginLoaded += OnPluginManagementServiceOnPluginManagementLoaded;
_pluginManagementService.PluginEnabling += PluginManagementServiceOnPluginManagementEnabling;
_pluginManagementService.PluginEnabled += PluginManagementServiceOnPluginManagementEnabled;
+ _pluginManagementService.PluginFeatureEnabling += PluginManagementServiceOnPluginFeatureEnabling;
+ _pluginManagementService.PluginFeatureEnabled += PluginManagementServiceOnPluginFeatureEnabled;
base.OnInitialActivate();
}
@@ -53,6 +56,8 @@ namespace Artemis.UI.Screens.Splash
_pluginManagementService.PluginLoaded -= OnPluginManagementServiceOnPluginManagementLoaded;
_pluginManagementService.PluginEnabling -= PluginManagementServiceOnPluginManagementEnabling;
_pluginManagementService.PluginEnabled -= PluginManagementServiceOnPluginManagementEnabled;
+ _pluginManagementService.PluginFeatureEnabling -= PluginManagementServiceOnPluginFeatureEnabling;
+ _pluginManagementService.PluginFeatureEnabled -= PluginManagementServiceOnPluginFeatureEnabled;
base.OnClose();
}
@@ -63,7 +68,7 @@ namespace Artemis.UI.Screens.Splash
private void OnPluginManagementServiceOnPluginManagementLoading(object sender, PluginEventArgs args)
{
- Status = "Loading plugin: " + args.PluginInfo.Name;
+ Status = "Loading plugin: " + args.Plugin.Info.Name;
}
private void PluginManagementServiceOnPluginManagementEnabled(object sender, PluginEventArgs args)
@@ -73,7 +78,17 @@ namespace Artemis.UI.Screens.Splash
private void PluginManagementServiceOnPluginManagementEnabling(object sender, PluginEventArgs args)
{
- Status = "Enabling plugin: " + args.PluginInfo.Name;
+ Status = "Enabling plugin: " + args.Plugin.Info.Name;
+ }
+
+ private void PluginManagementServiceOnPluginFeatureEnabling(object? sender, PluginFeatureEventArgs e)
+ {
+ Status = "Enabling: " + e.PluginFeature.GetType().Name.Humanize();
+ }
+
+ private void PluginManagementServiceOnPluginFeatureEnabled(object? sender, PluginFeatureEventArgs e)
+ {
+ Status = "Initializing UI";
}
private void OnPluginManagementServiceOnCopyingBuildInPluginsManagement(object sender, EventArgs args)
diff --git a/src/Artemis.UI/Services/RegistrationService.cs b/src/Artemis.UI/Services/RegistrationService.cs
index c60671476..d70fb3db7 100644
--- a/src/Artemis.UI/Services/RegistrationService.cs
+++ b/src/Artemis.UI/Services/RegistrationService.cs
@@ -33,7 +33,7 @@ namespace Artemis.UI.Services
if (_registeredBuiltInDataModelDisplays)
return;
- _dataModelUIService.RegisterDataModelDisplay(Constants.CorePluginInfo);
+ _dataModelUIService.RegisterDataModelDisplay(Constants.CorePlugin);
_registeredBuiltInDataModelDisplays = true;
}
@@ -43,12 +43,12 @@ namespace Artemis.UI.Services
if (_registeredBuiltInDataModelInputs)
return;
- _dataModelUIService.RegisterDataModelInput(Constants.CorePluginInfo, Constants.FloatNumberTypes);
- _dataModelUIService.RegisterDataModelInput(Constants.CorePluginInfo, Constants.IntegralNumberTypes);
- _dataModelUIService.RegisterDataModelInput(Constants.CorePluginInfo, null);
- _dataModelUIService.RegisterDataModelInput(Constants.CorePluginInfo, null);
- _dataModelUIService.RegisterDataModelInput(Constants.CorePluginInfo, null);
- _dataModelUIService.RegisterDataModelInput(Constants.CorePluginInfo, null);
+ _dataModelUIService.RegisterDataModelInput(Constants.CorePlugin, Constants.FloatNumberTypes);
+ _dataModelUIService.RegisterDataModelInput(Constants.CorePlugin, Constants.IntegralNumberTypes);
+ _dataModelUIService.RegisterDataModelInput(Constants.CorePlugin, null);
+ _dataModelUIService.RegisterDataModelInput(Constants.CorePlugin, null);
+ _dataModelUIService.RegisterDataModelInput(Constants.CorePlugin, null);
+ _dataModelUIService.RegisterDataModelInput(Constants.CorePlugin, null);
_registeredBuiltInDataModelInputs = true;
}
@@ -58,30 +58,30 @@ namespace Artemis.UI.Services
if (_registeredBuiltInPropertyEditors)
return;
- _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo);
- _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo);
- _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo);
- _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo);
- _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo);
- _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo);
- _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo);
- _profileEditorService.RegisterPropertyInput(typeof(EnumPropertyInputViewModel<>), Constants.CorePluginInfo);
- _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo);
- _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo);
- _profileEditorService.RegisterPropertyInput(Constants.CorePluginInfo);
+ _profileEditorService.RegisterPropertyInput(Constants.CorePlugin);
+ _profileEditorService.RegisterPropertyInput(Constants.CorePlugin);
+ _profileEditorService.RegisterPropertyInput(Constants.CorePlugin);
+ _profileEditorService.RegisterPropertyInput(Constants.CorePlugin);
+ _profileEditorService.RegisterPropertyInput(Constants.CorePlugin);
+ _profileEditorService.RegisterPropertyInput(Constants.CorePlugin);
+ _profileEditorService.RegisterPropertyInput(Constants.CorePlugin);
+ _profileEditorService.RegisterPropertyInput(typeof(EnumPropertyInputViewModel<>), Constants.CorePlugin);
+ _profileEditorService.RegisterPropertyInput(Constants.CorePlugin);
+ _profileEditorService.RegisterPropertyInput(Constants.CorePlugin);
+ _profileEditorService.RegisterPropertyInput(Constants.CorePlugin);
_registeredBuiltInPropertyEditors = true;
}
private void PluginServiceOnPluginLoaded(object? sender, PluginEventArgs e)
{
- e.PluginInfo.Kernel.Load(new[] { new PluginUIModule(e.PluginInfo) });
+ e.Plugin.Kernel.Load(new[] {new PluginUIModule(e.Plugin)});
}
private void LoadPluginModules()
{
- foreach (PluginInfo pluginInfo in _pluginManagementService.GetAllPluginInfo())
- pluginInfo.Kernel.Load(new[] { new PluginUIModule(pluginInfo) });
+ foreach (Plugin plugin in _pluginManagementService.GetAllPlugins())
+ plugin.Kernel.Load(new[] {new PluginUIModule(plugin)});
}
}
diff --git a/src/Artemis.UI/packages.lock.json b/src/Artemis.UI/packages.lock.json
index 49487b577..4a4eefa79 100644
--- a/src/Artemis.UI/packages.lock.json
+++ b/src/Artemis.UI/packages.lock.json
@@ -1363,7 +1363,6 @@
"Serilog.Sinks.Debug": "1.0.1",
"Serilog.Sinks.File": "4.1.0",
"SkiaSharp": "1.68.3",
- "Stylet": "1.3.4",
"System.Buffers": "4.5.0",
"System.Numerics.Vectors": "4.5.0",
"System.Reflection.Metadata": "1.8.0",
diff --git a/src/Artemis.sln.DotSettings b/src/Artemis.sln.DotSettings
index d11049d68..2df38068d 100644
--- a/src/Artemis.sln.DotSettings
+++ b/src/Artemis.sln.DotSettings
@@ -222,4 +222,7 @@
True
True
True
+ True
+
+
True
\ No newline at end of file