1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Merge pull request #502 from Artemis-RGB/feature/plugin-implementations

Added plugin features
This commit is contained in:
Robert Beekman 2020-11-13 20:45:42 +01:00 committed by GitHub
commit 7735edea1e
230 changed files with 3227 additions and 1912 deletions

View File

@ -50,7 +50,6 @@
<PackageReference Include="Serilog.Sinks.Debug" Version="1.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
<PackageReference Include="SkiaSharp" Version="1.68.3" />
<PackageReference Include="Stylet" Version="1.3.4" />
<PackageReference Include="System.Buffers" Version="4.5.0" />
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<PackageReference Include="System.Reflection.Metadata" Version="1.8.0" />

View File

@ -1,4 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=defaulttypes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cconditions_005Cwrappers/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cmodes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Cdatabindings_005Cmodes_005Cconditional/@EntryIndexedValue">True</s:Boolean>
@ -42,6 +43,7 @@
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Clayerproperties_005Ctypes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cprofile_005Clayershapes/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Csurface/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=mvvm/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=placeholders/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=plugins_005Cdatamodelexpansions_005Cattributes/@EntryIndexedValue">True</s:Boolean>

View File

@ -12,7 +12,7 @@ namespace Artemis.Core
/// <summary>
/// The full path to the Artemis application folder
/// </summary>
public static readonly string ApplicationFolder = Path.GetDirectoryName(typeof(Constants).Assembly.Location);
public static readonly string ApplicationFolder = Path.GetDirectoryName(typeof(Constants).Assembly.Location)!;
/// <summary>
/// The full path to the Artemis executable
@ -34,11 +34,16 @@ namespace Artemis.Core
/// </summary>
public static readonly PluginInfo CorePluginInfo = new PluginInfo
{
Guid = Guid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff"), Name = "Artemis Core", Enabled = true
Guid = Guid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff"), Name = "Artemis Core"
};
internal static readonly CorePlugin CorePlugin = new CorePlugin {PluginInfo = CorePluginInfo};
internal static readonly EffectPlaceholderPlugin EffectPlaceholderPlugin = new EffectPlaceholderPlugin {PluginInfo = CorePluginInfo};
/// <summary>
/// The plugin used by core components of Artemis
/// </summary>
public static readonly Plugin CorePlugin = new Plugin(CorePluginInfo, new DirectoryInfo(ApplicationFolder));
internal static readonly CorePluginFeature CorePluginFeature = new CorePluginFeature {Plugin = CorePlugin};
internal static readonly EffectPlaceholderPlugin EffectPlaceholderPlugin = new EffectPlaceholderPlugin {Plugin = CorePlugin};
/// <summary>
/// A read-only collection containing all primitive numeric types

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class EqualsConditionOperator : ConditionOperator<object, object>
{

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class GreaterThanConditionOperator : ConditionOperator<double, double>
{

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class GreaterThanOrEqualConditionOperator : ConditionOperator<double, double>
{

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class LessThanConditionOperator : ConditionOperator<double, double>
{

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class LessThanOrEqualConditionOperator : ConditionOperator<double, double>
{

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class NotEqualConditionOperator : ConditionOperator<object, object>
{

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class NotNullConditionOperator : ConditionOperator<object>
{

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class NullConditionOperator : ConditionOperator<object>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class NumberEqualsConditionOperator : ConditionOperator<double, double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class NumberNotEqualConditionOperator : ConditionOperator<double, double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class StringContainsConditionOperator : ConditionOperator<string, string>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class StringEndsWithConditionOperator : ConditionOperator<string, string>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class StringEqualsConditionOperator : ConditionOperator<string, string>
{

View File

@ -1,6 +1,6 @@
using System.Text.RegularExpressions;
namespace Artemis.Core.DefaultTypes {
namespace Artemis.Core {
internal class StringMatchesRegexConditionOperator : ConditionOperator<string, string>
{
public override string Description => "Matches Regex";

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class StringNotContainsConditionOperator : ConditionOperator<string, string>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class StringNotEqualConditionOperator : ConditionOperator<string, string>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class StringStartsWithConditionOperator : ConditionOperator<string, string>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <inheritdoc />
public class FloatDataBindingConverter : FloatDataBindingConverter<float>

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <summary>
/// Represents a generic data binding converter that acts as the bridge between a

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <inheritdoc />
public class IntDataBindingConverter : IntDataBindingConverter<int>

View File

@ -1,6 +1,6 @@
using SkiaSharp;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <inheritdoc />
public class SKColorDataBindingConverter : DataBindingConverter<SKColor, SKColor>

View File

@ -1,6 +1,6 @@
using SkiaSharp;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class SKColorBrightenModifierType : DataBindingModifierType<SKColor, float>
{

View File

@ -1,6 +1,6 @@
using SkiaSharp;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class SKColorDarkenModifierType : DataBindingModifierType<SKColor, float>
{

View File

@ -1,7 +1,7 @@
using System;
using SkiaSharp;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class SKColorDesaturateModifierType : DataBindingModifierType<SKColor, float>
{

View File

@ -1,6 +1,6 @@
using SkiaSharp;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class SKColorInvertModifierType : DataBindingModifierType<SKColor>
{

View File

@ -1,6 +1,6 @@
using SkiaSharp;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class SKColorRotateHueModifierType : DataBindingModifierType<SKColor, float>
{

View File

@ -1,7 +1,7 @@
using System;
using SkiaSharp;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class SKColorSaturateModifierType : DataBindingModifierType<SKColor, float>
{

View File

@ -1,6 +1,6 @@
using SkiaSharp;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class SKColorSumModifierType : DataBindingModifierType<SKColor, SKColor>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class AbsoluteModifierType : DataBindingModifierType<double>
{

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class DivideModifierType : DataBindingModifierType<double, double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class MaxModifierType : DataBindingModifierType<double, double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class MinModifierType : DataBindingModifierType<double, double>
{

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class ModuloModifierType : DataBindingModifierType<double, double>
{

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class MultiplicationModifierType : DataBindingModifierType<double, double>
{

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class PercentageOfModifierType : DataBindingModifierType<double, double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class PowerModifierType : DataBindingModifierType<double, double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class CeilingModifierType : DataBindingModifierType<double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class FloorModifierType : DataBindingModifierType<double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class RoundModifierType : DataBindingModifierType<double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class SquareRootModifierType : DataBindingModifierType<double>
{

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class SubtractModifierType : DataBindingModifierType<double, double>
{

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class SumModifierType : DataBindingModifierType<double, double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class CosecantModifierType : DataBindingModifierType<double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class CosineModifierType : DataBindingModifierType<double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class CotangentModifierType : DataBindingModifierType<double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class SecantModifierType : DataBindingModifierType<double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class SineModifierType : DataBindingModifierType<double>
{

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
internal class TangentModifierType : DataBindingModifierType<double>
{

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <inheritdoc />
public class BoolLayerProperty : LayerProperty<bool>

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <inheritdoc />
public class ColorGradientLayerProperty : LayerProperty<ColorGradient>

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <inheritdoc />
public class EnumLayerProperty<T> : LayerProperty<T> where T : Enum

View File

@ -1,6 +1,4 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <inheritdoc />
public class FloatLayerProperty : LayerProperty<float>

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <inheritdoc />
public class FloatRangeLayerProperty : LayerProperty<FloatRange>

View File

@ -1,6 +1,6 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <inheritdoc />
public class IntLayerProperty : LayerProperty<int>

View File

@ -1,6 +1,4 @@
using System;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <inheritdoc />
public class IntRangeLayerProperty : LayerProperty<IntRange>

View File

@ -1,4 +1,4 @@
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <summary>
/// A special layer property used to configure the selected layer brush

View File

@ -1,6 +1,6 @@
using SkiaSharp;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <inheritdoc />
public class SKColorLayerProperty : LayerProperty<SKColor>

View File

@ -1,6 +1,6 @@
using SkiaSharp;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <inheritdoc />
public class SKPointLayerProperty : LayerProperty<SKPoint>

View File

@ -1,6 +1,6 @@
using SkiaSharp;
namespace Artemis.Core.DefaultTypes
namespace Artemis.Core
{
/// <inheritdoc />
public class SKSizeLayerProperty : LayerProperty<SKSize>

View File

@ -8,11 +8,11 @@ namespace Artemis.Core
{
}
public PluginEventArgs(PluginInfo pluginInfo)
public PluginEventArgs(Plugin plugin)
{
PluginInfo = pluginInfo;
Plugin = plugin;
}
public PluginInfo PluginInfo { get; }
public Plugin Plugin { get; }
}
}

View File

@ -0,0 +1,18 @@
using System;
namespace Artemis.Core
{
public class PluginFeatureEventArgs : EventArgs
{
public PluginFeatureEventArgs()
{
}
public PluginFeatureEventArgs(PluginFeature pluginFeature)
{
PluginFeature = pluginFeature;
}
public PluginFeature PluginFeature { get; }
}
}

View File

@ -4,19 +4,19 @@ namespace Artemis.Core
{
public class ArtemisPluginException : Exception
{
public ArtemisPluginException(PluginInfo pluginInfo)
public ArtemisPluginException(Plugin plugin)
{
PluginInfo = pluginInfo;
Plugin = plugin;
}
public ArtemisPluginException(PluginInfo pluginInfo, string message) : base(message)
public ArtemisPluginException(Plugin plugin, string message) : base(message)
{
PluginInfo = pluginInfo;
Plugin = plugin;
}
public ArtemisPluginException(PluginInfo pluginInfo, string message, Exception inner) : base(message, inner)
public ArtemisPluginException(Plugin plugin, string message, Exception inner) : base(message, inner)
{
PluginInfo = pluginInfo;
Plugin = plugin;
}
public ArtemisPluginException(string message) : base(message)
@ -27,6 +27,6 @@ namespace Artemis.Core
{
}
public PluginInfo PluginInfo { get; }
public Plugin Plugin { get; }
}
}

View File

@ -0,0 +1,24 @@
using System;
namespace Artemis.Core
{
public class ArtemisPluginFeatureException : Exception
{
public PluginFeature PluginFeature { get; }
public ArtemisPluginFeatureException(PluginFeature pluginFeature)
{
PluginFeature = pluginFeature;
}
public ArtemisPluginFeatureException(PluginFeature pluginFeature, string message) : base(message)
{
PluginFeature = pluginFeature;
}
public ArtemisPluginFeatureException(PluginFeature pluginFeature, string message, Exception inner) : base(message, inner)
{
PluginFeature = pluginFeature;
}
}
}

View File

@ -0,0 +1,72 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace Artemis.Core
{
/// <summary>
/// Represents a basic bindable class which notifies when a property value changes.
/// </summary>
public abstract class CorePropertyChanged : INotifyPropertyChanged
{
#region Events
/// <summary>
/// Occurs when a property value changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region Methods
/// <summary>
/// Checks if the property already matches the desirec value or needs to be updated.
/// </summary>
/// <typeparam name="T">Type of the property.</typeparam>
/// <param name="storage">Reference to the backing-filed.</param>
/// <param name="value">Value to apply.</param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected virtual bool RequiresUpdate<T>(ref T storage, T value)
{
return !Equals(storage, value);
}
/// <summary>
/// Checks if the property already matches the desired value and updates it if not.
/// </summary>
/// <typeparam name="T">Type of the property.</typeparam>
/// <param name="storage">Reference to the backing-filed.</param>
/// <param name="value">Value to apply.</param>
/// <param name="propertyName">
/// Name of the property used to notify listeners. This value is optional
/// and can be provided automatically when invoked from compilers that support <see cref="CallerMemberNameAttribute" />
/// .
/// </param>
/// <returns><c>true</c> if the value was changed, <c>false</c> if the existing value matched the desired value.</returns>
protected virtual bool SetAndNotify<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (!RequiresUpdate(ref storage, value)) return false;
storage = value;
// ReSharper disable once ExplicitCallerInfoArgument
OnPropertyChanged(propertyName);
return true;
}
/// <summary>
/// Triggers the <see cref="PropertyChanged" />-event when a a property value has changed.
/// </summary>
/// <param name="propertyName">
/// Name of the property used to notify listeners. This value is optional
/// and can be provided automatically when invoked from compilers that support <see cref="CallerMemberNameAttribute" />
/// .
/// </param>
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}

View File

@ -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
/// </summary>
public ColorGradient()
{
Stops = new BindableCollection<ColorGradientStop>();
Stops = new List<ColorGradientStop>();
}
/// <summary>
/// Gets a list of all the <see cref="ColorGradientStop" />s in the gradient
/// </summary>
public BindableCollection<ColorGradientStop> Stops { get; }
public List<ColorGradientStop> Stops { get; }
/// <summary>
/// Gets all the colors in the color gradient

View File

@ -22,10 +22,10 @@ namespace Artemis.Core
public abstract string Icon { get; }
/// <summary>
/// Gets the plugin info this condition operator belongs to
/// Gets the plugin this condition operator belongs to
/// <para>Note: Not set until after registering</para>
/// </summary>
public PluginInfo PluginInfo { get; internal set; }
public Plugin Plugin { get; internal set; }
/// <summary>
/// Gets the left side type of this condition operator

View File

@ -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);
}

View File

@ -16,7 +16,7 @@ namespace Artemis.Core
{
internal EventPredicateWrapperDataModel()
{
PluginInfo = Constants.CorePluginInfo;
Feature = Constants.CorePluginFeature;
}
[DataModelIgnore]

View File

@ -16,7 +16,7 @@ namespace Artemis.Core
{
internal ListPredicateWrapperDataModel()
{
PluginInfo = Constants.CorePluginInfo;
Feature = Constants.CorePluginFeature;
}
[DataModelIgnore]

View File

@ -12,10 +12,10 @@ namespace Artemis.Core
public abstract class BaseDataBindingModifierType
{
/// <summary>
/// Gets the plugin info this data binding modifier belongs to
/// Gets the plugin this data binding modifier belongs to
/// <para>Note: Not set until after registering</para>
/// </summary>
public PluginInfo PluginInfo { get; internal set; }
public Plugin Plugin { get; internal set; }
/// <summary>
/// Gets the value type of this modifier type

View File

@ -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);
}

View File

@ -91,9 +91,9 @@ namespace Artemis.Core
public DataModel? Target { get; private set; }
/// <summary>
/// Gets the data model GUID of the <see cref="Target" /> if it is a <see cref="DataModel" />
/// Gets the data model ID of the <see cref="Target" /> if it is a <see cref="DataModel" />
/// </summary>
public Guid? DataModelGuid => Target?.PluginInfo.Guid;
public string? DataModelId => Target?.Feature.Id;
/// <summary>
/// Gets the point-separated path associated with this <see cref="DataModelPath" />
@ -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;
}
/// <inheritdoc />
@ -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.PluginInfo.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.PluginInfo.Guid != Entity.DataModelGuid)
if (e.Registration.DataModel.Feature.Id != Entity.DataModelId)
return;
Target = null;

View File

@ -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.Plugin.PluginInfo.Guid == current.BrushPluginGuid &&
if (e.Registration.PluginFeature.Id == current.LayerBrushProviderId &&
e.Registration.LayerBrushDescriptor.LayerBrushType.Name == current.BrushType)
ActivateLayerBrush();
}

View File

@ -1,5 +1,4 @@
using System;
using Artemis.Core.LayerBrushes;
using Artemis.Core.LayerBrushes;
namespace Artemis.Core
{
@ -8,24 +7,24 @@ namespace Artemis.Core
/// </summary>
public class LayerBrushReference
{
/// <summary>
/// The GUID of the plugin the brush descriptor resides in
/// </summary>
public Guid BrushPluginGuid { get; set; }
/// <summary>
/// The full type name of the brush descriptor
/// </summary>
public string BrushType { get; set; }
public LayerBrushReference()
{
}
public LayerBrushReference(LayerBrushDescriptor descriptor)
{
BrushPluginGuid = descriptor.LayerBrushProvider.PluginInfo.Guid;
LayerBrushProviderId = descriptor.Provider.Id;
BrushType = descriptor.LayerBrushType.Name;
}
/// <summary>
/// The ID of the layer brush provided the brush was provided by
/// </summary>
public string LayerBrushProviderId { get; set; }
/// <summary>
/// The full type name of the brush descriptor
/// </summary>
public string BrushType { get; set; }
}
}

View File

@ -1,5 +1,4 @@
using Artemis.Core.DefaultTypes;
using SkiaSharp;
using SkiaSharp;
namespace Artemis.Core
{

View File

@ -1,12 +1,11 @@
using System;
using Stylet;
namespace Artemis.Core
{
/// <summary>
/// Represents a keyframe on a <see cref="LayerProperty{T}" /> containing a value and a timestamp
/// </summary>
public class LayerPropertyKeyframe<T> : PropertyChangedBase
public class LayerPropertyKeyframe<T> : CorePropertyChanged
{
private LayerProperty<T> _layerProperty;
private TimeSpan _position;

View File

@ -28,11 +28,11 @@ namespace Artemis.Core
/// Gets the description of this group
/// </summary>
public PropertyGroupDescriptionAttribute GroupDescription { get; internal set; }
/// <summary>
/// Gets the info of the plugin this group is associated with
/// Gets the plugin feature this group is associated with
/// </summary>
public PluginInfo PluginInfo { get; internal set; }
public PluginFeature Feature { get; set; }
/// <summary>
/// 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);
}

View File

@ -1,5 +1,4 @@
using Artemis.Core.DefaultTypes;
using SkiaSharp;
using SkiaSharp;
namespace Artemis.Core
{

View File

@ -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;

View File

@ -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;

View File

@ -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<BaseLayerEffect> pluginEffects = _layerEffects.Where(ef => ef.Descriptor.LayerEffectProvider != null &&
ef.PluginInfo.Guid == e.Registration.Plugin.PluginInfo.Guid).ToList();
List<BaseLayerEffect> 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.Plugin.PluginInfo.Guid))
if (RenderElementEntity.LayerEffects.Any(ef => ef.ProviderId == e.Registration.PluginFeature.Id))
ActivateEffects();
}

View File

@ -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
{
/// <summary>
/// Represents a timeline used by profile elements
/// </summary>
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

View File

@ -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<ArtemisLed> _leds;
private SKPath _renderPath;
private SKRect _renderRectangle;
internal ArtemisDevice(IRGBDevice rgbDevice, Plugin plugin, ArtemisSurface surface)
internal ArtemisDevice(IRGBDevice rgbDevice, PluginFeature pluginFeature, ArtemisSurface surface)
{
RgbDevice = rgbDevice;
Plugin = plugin;
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, Plugin plugin, ArtemisSurface surface, DeviceEntity deviceEntity)
internal ArtemisDevice(IRGBDevice rgbDevice, PluginFeature pluginFeature, ArtemisSurface surface, DeviceEntity deviceEntity)
{
RgbDevice = rgbDevice;
Plugin = plugin;
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 Plugin Plugin { 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));
}
}

View File

@ -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;

View File

@ -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<ArtemisDevice> _devices;
private bool _isActive;

View File

@ -7,6 +7,7 @@ using LiteDB;
using Ninject.Activation;
using Ninject.Extensions.Conventions;
using Ninject.Modules;
using Ninject.Planning.Bindings.Resolvers;
using Serilog;
namespace Artemis.Core.Ninject
@ -22,6 +23,8 @@ namespace Artemis.Core.Ninject
if (Kernel == null)
throw new ArtemisCoreException("Failed to bind Ninject Core module, kernel is null.");
Kernel.Components.Remove<IMissingBindingResolver, SelfBindingResolver>();
// Bind all services as singletons
Kernel.Bind(x =>
{
@ -88,6 +91,7 @@ namespace Artemis.Core.Ninject
Kernel.Bind<PluginSettings>().ToProvider<PluginSettingsProvider>();
Kernel.Bind<ILogger>().ToProvider<LoggerProvider>();
Kernel.Bind<LoggerProvider>().ToSelf();
}
private bool HasAccessToProtectedService(IRequest r)

View File

@ -1,19 +1,52 @@
using System;
using Artemis.Core.Services;
using Ninject.Extensions.Conventions;
using Ninject.Modules;
using Ninject.Planning.Bindings.Resolvers;
namespace Artemis.Core.Ninject
{
internal class PluginModule : NinjectModule
{
public PluginModule(PluginInfo pluginInfo)
public PluginModule(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()
{
if (Kernel == null)
throw new ArtemisCoreException("Failed to bind plugin child module, kernel is null.");
Kernel.Components.Remove<IMissingBindingResolver, SelfBindingResolver>();
Kernel.Bind<Plugin>().ToConstant(Plugin);
// Bind plugin service interfaces
Kernel.Bind(x =>
{
x.From(Plugin.Assembly)
.IncludingNonPublicTypes()
.SelectAllClasses()
.InheritedFrom<IPluginService>()
.BindAllInterfaces()
.Configure(c => c.InSingletonScope());
});
// Plugin developers may not use an interface so bind the plugin services to themselves
// Sadly if they do both, the kernel will treat the interface and the base type as two different singletons
// perhaps we can avoid that, but I'm not sure how
Kernel.Bind(x =>
{
x.From(Plugin.Assembly)
.IncludingNonPublicTypes()
.SelectAllClasses()
.InheritedFrom<IPluginService>()
.BindToSelf()
.Configure(c => c.InSingletonScope());
});
}
}
}

View File

@ -6,16 +6,17 @@ 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<PluginSettings>
{
private static readonly List<PluginSettings> PluginSettings = new List<PluginSettings>();
private readonly IPluginRepository _pluginRepository;
private readonly IPluginService _pluginService;
private readonly IPluginManagementService _pluginManagementService;
internal PluginSettingsProvider(IPluginRepository pluginRepository, IPluginService pluginService)
public PluginSettingsProvider(IPluginRepository pluginRepository, IPluginManagementService pluginManagementService)
{
_pluginRepository = pluginRepository;
_pluginService = pluginService;
_pluginManagementService = pluginManagementService;
}
protected override PluginSettings CreateInstance(IContext context)
@ -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 = _pluginService.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;
}

View File

@ -17,7 +17,7 @@ namespace Artemis.Core.Ninject
protected override ISettingsService CreateInstance(IContext context)
{
IRequest parentRequest = context.Request.ParentRequest;
if (parentRequest == null || typeof(Plugin).IsAssignableFrom(parentRequest.Service))
if (parentRequest == null || typeof(PluginFeature).IsAssignableFrom(parentRequest.Service))
throw new ArtemisPluginException($"SettingsService can not be injected into a plugin. Inject {nameof(PluginSettings)} instead.");
return _instance;

View File

@ -14,10 +14,10 @@ namespace Artemis.Core.DataModelExpansions
private readonly Dictionary<string, DataModel> _dynamicDataModels = new Dictionary<string, DataModel>();
/// <summary>
/// Gets the plugin info this data model belongs to
/// Gets the plugin feature this data model belongs to
/// </summary>
[DataModelIgnore]
public PluginInfo PluginInfo { get; internal set; }
public DataModelPluginFeature Feature { get; internal set; }
/// <summary>
/// Gets the <see cref="DataModelPropertyAttribute" /> describing this data model
@ -43,9 +43,9 @@ namespace Artemis.Core.DataModelExpansions
/// <returns></returns>
public ReadOnlyCollection<PropertyInfo> GetHiddenProperties()
{
if (PluginInfo.Instance is ProfileModule profileModule)
if (Feature is ProfileModule profileModule)
return profileModule.HiddenProperties;
if (PluginInfo.Instance is BaseDataModelExpansion dataModelExpansion)
if (Feature is BaseDataModelExpansion dataModelExpansion)
return dataModelExpansion.HiddenProperties;
return new List<PropertyInfo>().AsReadOnly();
@ -81,7 +81,7 @@ namespace Artemis.Core.DataModelExpansions
throw new ArtemisCoreException($"Cannot add a dynamic data model with key '{key}' " +
"because the key is already in use by a static property on this data model.");
dynamicDataModel.PluginInfo = PluginInfo;
dynamicDataModel.Feature = Feature;
dynamicDataModel.DataModelDescription = new DataModelPropertyAttribute
{
Name = string.IsNullOrWhiteSpace(name) ? key.Humanize() : name,

View File

@ -42,18 +42,18 @@ namespace Artemis.Core.DataModelExpansions
HiddenPropertiesList.RemoveAll(p => p.Equals(propertyInfo));
}
internal override void InternalEnablePlugin()
internal override void InternalEnable()
{
DataModel = Activator.CreateInstance<T>();
DataModel.PluginInfo = PluginInfo;
DataModel.Feature = this;
DataModel.DataModelDescription = GetDataModelDescription();
base.InternalEnablePlugin();
base.InternalEnable();
}
internal override void InternalDisablePlugin()
internal override void InternalDisable()
{
DataModel = null;
base.InternalDisablePlugin();
base.InternalDisable();
}
}
}

View File

@ -8,7 +8,7 @@ namespace Artemis.Core.DataModelExpansions
/// For internal use only, to implement your own layer property type, extend <see cref="DataModelExpansion{T}" />
/// instead.
/// </summary>
public abstract class BaseDataModelExpansion : Plugin
public abstract class BaseDataModelExpansion : DataModelPluginFeature
{
/// <summary>
/// Gets a list of all properties ignored at runtime using <c>IgnoreProperty(x => x.y)</c>
@ -20,7 +20,7 @@ namespace Artemis.Core.DataModelExpansions
/// </summary>
public ReadOnlyCollection<PropertyInfo> HiddenProperties => HiddenPropertiesList.AsReadOnly();
internal DataModel InternalDataModel { get; set; }
internal DataModel? InternalDataModel { get; set; }
/// <summary>
/// Called each frame when the data model should update
@ -28,6 +28,12 @@ namespace Artemis.Core.DataModelExpansions
/// <param name="deltaTime">Time in seconds since the last update</param>
public abstract void Update(double deltaTime);
internal void InternalUpdate(double deltaTime)
{
if (InternalDataModel != null)
Update(deltaTime);
}
/// <summary>
/// Override to provide your own data model description. By default this returns a description matching your plugin
/// name and description
@ -35,7 +41,7 @@ namespace Artemis.Core.DataModelExpansions
/// <returns></returns>
public virtual DataModelPropertyAttribute GetDataModelDescription()
{
return new DataModelPropertyAttribute {Name = PluginInfo.Name, Description = PluginInfo.Description};
return new DataModelPropertyAttribute {Name = Plugin.Info.Name, Description = Plugin.Info.Description};
}
}
}

View File

@ -0,0 +1,47 @@
using System;
using System.Threading.Tasks;
namespace Artemis.Core
{
/// <summary>
/// Represents an feature of a certain type provided by a plugin with support for data models
/// </summary>
public abstract class DataModelPluginFeature : PluginFeature
{
/// <summary>
/// Registers a timed update that whenever the plugin is enabled calls the provided <paramref name="action" /> at the
/// provided
/// <paramref name="interval" />
/// </summary>
/// <param name="interval">The interval at which the update should occur</param>
/// <param name="action">
/// The action to call every time the interval has passed. The delta time parameter represents the
/// time passed since the last update in seconds
/// </param>
/// <returns>The resulting plugin update registration which can be used to stop the update</returns>
public TimedUpdateRegistration AddTimedUpdate(TimeSpan interval, Action<double> action)
{
if (action == null)
throw new ArgumentNullException(nameof(action));
return new TimedUpdateRegistration(this, interval, action);
}
/// <summary>
/// Registers a timed update that whenever the plugin is enabled calls the provided <paramref name="asyncAction" /> at the
/// provided
/// <paramref name="interval" />
/// </summary>
/// <param name="interval">The interval at which the update should occur</param>
/// <param name="asyncAction">
/// The async action to call every time the interval has passed. The delta time parameter
/// represents the time passed since the last update in seconds
/// </param>
/// <returns>The resulting plugin update registration</returns>
public TimedUpdateRegistration AddTimedUpdate(TimeSpan interval, Func<double, Task> asyncAction)
{
if (asyncAction == null)
throw new ArgumentNullException(nameof(asyncAction));
return new TimedUpdateRegistration(this, interval, asyncAction);
}
}
}

View File

@ -10,7 +10,7 @@ namespace Artemis.Core.DeviceProviders
/// <summary>
/// Allows you to implement and register your own device provider
/// </summary>
public abstract class DeviceProvider : Plugin
public abstract class DeviceProvider : PluginFeature
{
/// <summary>
/// Creates a new instance of the <see cref="DeviceProvider" /> class
@ -34,7 +34,7 @@ namespace Artemis.Core.DeviceProviders
public ILogger Logger { get; set; }
/// <inheritdoc />
public override void DisablePlugin()
public override void Disable()
{
// Does not happen with device providers, they require Artemis to restart
}
@ -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))

View File

@ -0,0 +1,20 @@
namespace Artemis.Core
{
/// <summary>
/// An optional entry point for your plugin
/// </summary>
public interface IPluginBootstrapper
{
/// <summary>
/// Called when the plugin is activated
/// </summary>
/// <param name="plugin">The plugin instance of your plugin</param>
void Enable(Plugin plugin);
/// <summary>
/// Called when the plugin is deactivated or when Artemis shuts down
/// </summary>
/// <param name="plugin">The plugin instance of your plugin</param>
void Disable(Plugin plugin);
}
}

View File

@ -0,0 +1,7 @@
namespace Artemis.Core
{
public interface IPluginConfigurationDialog
{
}
}

View File

@ -0,0 +1,10 @@
namespace Artemis.Core
{
/// <summary>
/// Represents a view model for a plugin configuration window
/// </summary>
public interface IPluginConfigurationViewModel
{
}
}

Some files were not shown because too many files have changed in this diff Show More