diff --git a/src/Artemis.Core/Artemis.Core.csproj.DotSettings b/src/Artemis.Core/Artemis.Core.csproj.DotSettings
index 77021d436..7f651acb6 100644
--- a/src/Artemis.Core/Artemis.Core.csproj.DotSettings
+++ b/src/Artemis.Core/Artemis.Core.csproj.DotSettings
@@ -1,5 +1,8 @@
True
+ True
+ True
+ True
True
True
True
@@ -29,6 +32,10 @@
True
True
True
+ True
+ True
True
True
+ True
+ True
True
\ No newline at end of file
diff --git a/src/Artemis.Core/Events/PluginEventArgs.cs b/src/Artemis.Core/Events/Plugins/PluginEventArgs.cs
similarity index 100%
rename from src/Artemis.Core/Events/PluginEventArgs.cs
rename to src/Artemis.Core/Events/Plugins/PluginEventArgs.cs
diff --git a/src/Artemis.Core/Events/DataBindingPropertyUpdatedEvent.cs b/src/Artemis.Core/Events/Profiles/DataBindingPropertyUpdatedEvent.cs
similarity index 100%
rename from src/Artemis.Core/Events/DataBindingPropertyUpdatedEvent.cs
rename to src/Artemis.Core/Events/Profiles/DataBindingPropertyUpdatedEvent.cs
diff --git a/src/Artemis.Core/Events/LayerPropertyEventArgs.cs b/src/Artemis.Core/Events/Profiles/LayerPropertyEventArgs.cs
similarity index 100%
rename from src/Artemis.Core/Events/LayerPropertyEventArgs.cs
rename to src/Artemis.Core/Events/Profiles/LayerPropertyEventArgs.cs
diff --git a/src/Artemis.Core/Events/LayerPropertyGroupUpdatingEventArgs.cs b/src/Artemis.Core/Events/Profiles/LayerPropertyGroupUpdatingEventArgs.cs
similarity index 100%
rename from src/Artemis.Core/Events/LayerPropertyGroupUpdatingEventArgs.cs
rename to src/Artemis.Core/Events/Profiles/LayerPropertyGroupUpdatingEventArgs.cs
diff --git a/src/Artemis.Core/Events/Stores/ConditionOperatorStoreEvent.cs b/src/Artemis.Core/Events/Stores/ConditionOperatorStoreEvent.cs
new file mode 100644
index 000000000..fb81fa23f
--- /dev/null
+++ b/src/Artemis.Core/Events/Stores/ConditionOperatorStoreEvent.cs
@@ -0,0 +1,12 @@
+namespace Artemis.Core
+{
+ internal class ConditionOperatorStoreEvent
+ {
+ public ConditionOperatorStoreEvent(ConditionOperatorRegistration registration)
+ {
+ Registration = registration;
+ }
+
+ public ConditionOperatorRegistration Registration { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Events/Stores/DataBindingModifierTypeStoreEvent.cs b/src/Artemis.Core/Events/Stores/DataBindingModifierTypeStoreEvent.cs
new file mode 100644
index 000000000..c954a7f60
--- /dev/null
+++ b/src/Artemis.Core/Events/Stores/DataBindingModifierTypeStoreEvent.cs
@@ -0,0 +1,12 @@
+namespace Artemis.Core
+{
+ internal class DataBindingModifierTypeStoreEvent
+ {
+ public DataBindingModifierTypeStoreEvent(DataBindingModifierTypeRegistration typeRegistration)
+ {
+ TypeRegistration = typeRegistration;
+ }
+
+ public DataBindingModifierTypeRegistration TypeRegistration { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Events/Stores/DataModelStoreEvent.cs b/src/Artemis.Core/Events/Stores/DataModelStoreEvent.cs
new file mode 100644
index 000000000..eb1132422
--- /dev/null
+++ b/src/Artemis.Core/Events/Stores/DataModelStoreEvent.cs
@@ -0,0 +1,12 @@
+namespace Artemis.Core
+{
+ internal class DataModelStoreEvent
+ {
+ public DataModelStoreEvent(DataModelRegistration registration)
+ {
+ Registration = registration;
+ }
+
+ public DataModelRegistration Registration { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Events/Stores/LayerBrushStoreEvent.cs b/src/Artemis.Core/Events/Stores/LayerBrushStoreEvent.cs
new file mode 100644
index 000000000..6d80a46fb
--- /dev/null
+++ b/src/Artemis.Core/Events/Stores/LayerBrushStoreEvent.cs
@@ -0,0 +1,12 @@
+namespace Artemis.Core
+{
+ internal class LayerBrushStoreEvent
+ {
+ public LayerBrushStoreEvent(LayerBrushRegistration registration)
+ {
+ Registration = registration;
+ }
+
+ public LayerBrushRegistration Registration { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Events/Stores/LayerEffectStoreEvent.cs b/src/Artemis.Core/Events/Stores/LayerEffectStoreEvent.cs
new file mode 100644
index 000000000..8abcecb7f
--- /dev/null
+++ b/src/Artemis.Core/Events/Stores/LayerEffectStoreEvent.cs
@@ -0,0 +1,12 @@
+namespace Artemis.Core
+{
+ internal class LayerEffectStoreEvent
+ {
+ public LayerEffectStoreEvent(LayerEffectRegistration registration)
+ {
+ Registration = registration;
+ }
+
+ public LayerEffectRegistration Registration { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Abstract/DisplayConditionPart.cs b/src/Artemis.Core/Models/Profile/Conditions/Abstract/DisplayConditionPart.cs
index 2ae490f56..2669afc17 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Abstract/DisplayConditionPart.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Abstract/DisplayConditionPart.cs
@@ -60,7 +60,6 @@ namespace Artemis.Core
///
public abstract bool EvaluateObject(object target);
- internal abstract void Initialize(IDataModelService dataModelService);
internal abstract void ApplyToEntity();
internal abstract DisplayConditionPartEntity GetEntity();
}
diff --git a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/ConditionOperator.cs
similarity index 61%
rename from src/Artemis.Core/Models/Profile/Conditions/DisplayConditionOperator.cs
rename to src/Artemis.Core/Models/Profile/Conditions/ConditionOperator.cs
index cb592b5e5..53ca9bd79 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/ConditionOperator.cs
@@ -2,18 +2,14 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
-using Artemis.Core.Services;
namespace Artemis.Core
{
///
- /// A display condition operator is used by the conditions system to perform a specific boolean check
+ /// A condition operator is used by the conditions system to perform a specific boolean check
///
- public abstract class DisplayConditionOperator
+ public abstract class ConditionOperator
{
- private IDataModelService _dataModelService;
- private bool _registered;
-
///
/// Gets the plugin info this condition operator belongs to
/// Note: Not set until after registering
@@ -57,35 +53,5 @@ namespace Artemis.Core
/// The parameter on the right side of the expression
///
public abstract BinaryExpression CreateExpression(Expression leftSide, Expression rightSide);
-
- internal void Register(PluginInfo pluginInfo, IDataModelService dataModelService)
- {
- if (_registered)
- return;
-
- PluginInfo = pluginInfo;
- _dataModelService = dataModelService;
-
- if (PluginInfo != Constants.CorePluginInfo)
- PluginInfo.Instance.PluginDisabled += InstanceOnPluginDisabled;
-
- _registered = true;
- }
-
- internal void Unsubscribe()
- {
- if (!_registered)
- return;
-
- if (PluginInfo != Constants.CorePluginInfo)
- PluginInfo.Instance.PluginDisabled -= InstanceOnPluginDisabled;
- _registered = false;
- }
-
- private void InstanceOnPluginDisabled(object sender, EventArgs e)
- {
- // The service will call Unsubscribe
- _dataModelService.RemoveConditionOperator(this);
- }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionGroup.cs b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionGroup.cs
index c93bb0612..e68dd9e57 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionGroup.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionGroup.cs
@@ -1,6 +1,5 @@
using System;
using System.Linq;
-using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions;
@@ -108,12 +107,6 @@ namespace Artemis.Core
child.ApplyToEntity();
}
- internal override void Initialize(IDataModelService dataModelService)
- {
- foreach (var child in Children)
- child.Initialize(dataModelService);
- }
-
internal override DisplayConditionPartEntity GetEntity()
{
return Entity;
diff --git a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionList.cs b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionList.cs
index 4bb1a587d..bd9c54b76 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionList.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionList.cs
@@ -3,7 +3,6 @@ using System.Collections;
using System.Linq;
using System.Linq.Expressions;
using Artemis.Core.DataModelExpansions;
-using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions;
@@ -15,6 +14,8 @@ namespace Artemis.Core
{
Parent = parent;
Entity = new DisplayConditionListEntity();
+
+ Initialize();
}
public DisplayConditionList(DisplayConditionPart parent, DisplayConditionListEntity entity)
@@ -22,6 +23,8 @@ namespace Artemis.Core
Parent = parent;
Entity = entity;
ListOperator = (ListOperator) entity.ListOperator;
+
+ Initialize();
}
public DisplayConditionListEntity Entity { get; set; }
@@ -120,13 +123,13 @@ namespace Artemis.Core
return Entity;
}
- internal override void Initialize(IDataModelService dataModelService)
+ internal void Initialize()
{
if (Entity.ListDataModelGuid == null)
return;
// Get the data model and ensure the path is valid
- var dataModel = dataModelService.GetPluginDataModelByGuid(Entity.ListDataModelGuid.Value);
+ var dataModel = DataModelStore.Get(Entity.ListDataModelGuid.Value)?.DataModel;
if (dataModel == null || !dataModel.ContainsPath(Entity.ListPropertyPath))
return;
@@ -143,8 +146,6 @@ namespace Artemis.Core
Entity.Children.Clear();
AddChild(new DisplayConditionGroup(this));
}
-
- Children[0].Initialize(dataModelService);
}
}
diff --git a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionListPredicate.cs b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionListPredicate.cs
index 6afee4a2f..41c5890df 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionListPredicate.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionListPredicate.cs
@@ -2,7 +2,6 @@
using System.Linq;
using System.Linq.Expressions;
using Artemis.Core.DataModelExpansions;
-using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions;
using Newtonsoft.Json;
@@ -18,6 +17,7 @@ namespace Artemis.Core
Entity = new DisplayConditionListPredicateEntity();
ApplyParentList();
+ Initialize();
}
public DisplayConditionListPredicate(DisplayConditionPart parent, DisplayConditionListPredicateEntity entity)
@@ -27,12 +27,13 @@ namespace Artemis.Core
PredicateType = (ProfileRightSideType) entity.PredicateType;
ApplyParentList();
+ Initialize();
}
public DisplayConditionListPredicateEntity Entity { get; set; }
public ProfileRightSideType PredicateType { get; set; }
- public DisplayConditionOperator Operator { get; private set; }
+ public ConditionOperator Operator { get; private set; }
public Type ListType { get; private set; }
public DataModel ListDataModel { get; private set; }
@@ -120,9 +121,9 @@ namespace Artemis.Core
CreateExpression();
}
- public void UpdateOperator(DisplayConditionOperator displayConditionOperator)
+ public void UpdateOperator(ConditionOperator conditionOperator)
{
- if (displayConditionOperator == null)
+ if (conditionOperator == null)
{
Operator = null;
return;
@@ -130,13 +131,13 @@ namespace Artemis.Core
if (LeftPropertyPath == null)
{
- Operator = displayConditionOperator;
+ Operator = conditionOperator;
return;
}
var leftType = GetTypeAtInnerPath(LeftPropertyPath);
- if (displayConditionOperator.SupportsType(leftType))
- Operator = displayConditionOperator;
+ if (conditionOperator.SupportsType(leftType))
+ Operator = conditionOperator;
CreateExpression();
}
@@ -203,7 +204,7 @@ namespace Artemis.Core
Entity.OperatorType = Operator?.GetType().Name;
}
- internal override void Initialize(IDataModelService dataModelService)
+ internal void Initialize()
{
// Left side
if (Entity.LeftPropertyPath != null && ListContainsInnerPath(Entity.LeftPropertyPath))
@@ -212,7 +213,7 @@ namespace Artemis.Core
// Operator
if (Entity.OperatorPluginGuid != null)
{
- var conditionOperator = dataModelService.GetConditionOperator(Entity.OperatorPluginGuid.Value, Entity.OperatorType);
+ var conditionOperator = ConditionOperatorStore.Get(Entity.OperatorPluginGuid.Value, Entity.OperatorType)?.ConditionOperator;
if (conditionOperator != null)
UpdateOperator(conditionOperator);
}
@@ -241,7 +242,7 @@ namespace Artemis.Core
// If deserialization fails, use the type's default
catch (JsonSerializationException e)
{
- dataModelService.LogListPredicateDeserializationFailure(this, e);
+ DeserializationLogger.LogListPredicateDeserializationFailure(this, e);
rightSideValue = Activator.CreateInstance(leftSideType);
}
@@ -255,7 +256,7 @@ namespace Artemis.Core
}
catch (JsonException e)
{
- dataModelService.LogListPredicateDeserializationFailure(this, e);
+ DeserializationLogger.LogListPredicateDeserializationFailure(this, e);
}
}
}
diff --git a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionPredicate.cs b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionPredicate.cs
index 617de25f1..70a7a890a 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionPredicate.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/DisplayConditionPredicate.cs
@@ -2,7 +2,6 @@
using System.Linq;
using System.Linq.Expressions;
using Artemis.Core.DataModelExpansions;
-using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile.Abstract;
using Artemis.Storage.Entities.Profile.Conditions;
using Newtonsoft.Json;
@@ -25,6 +24,8 @@ namespace Artemis.Core
Parent = parent;
PredicateType = predicateType;
Entity = new DisplayConditionPredicateEntity();
+
+ Initialize();
}
///
@@ -37,6 +38,8 @@ namespace Artemis.Core
Parent = parent;
Entity = entity;
PredicateType = (ProfileRightSideType) entity.PredicateType;
+
+ Initialize();
}
///
@@ -47,7 +50,7 @@ namespace Artemis.Core
///
/// Gets the operator
///
- public DisplayConditionOperator Operator { get; private set; }
+ public ConditionOperator Operator { get; private set; }
///
/// Gets the currently used instance of the left data model
@@ -175,11 +178,11 @@ namespace Artemis.Core
///
/// Updates the operator of the predicate and re-compiles the expression
///
- ///
- public void UpdateOperator(DisplayConditionOperator displayConditionOperator)
+ ///
+ public void UpdateOperator(ConditionOperator conditionOperator)
{
// Calling CreateExpression will clear compiled expressions
- if (displayConditionOperator == null)
+ if (conditionOperator == null)
{
Operator = null;
CreateExpression();
@@ -189,18 +192,18 @@ namespace Artemis.Core
// No need to clear compiled expressions, without a left data model they are already null
if (LeftDataModel == null)
{
- Operator = displayConditionOperator;
+ Operator = conditionOperator;
return;
}
var leftType = LeftDataModel.GetTypeAtPath(LeftPropertyPath);
- if (!displayConditionOperator.SupportsType(leftType))
+ if (!conditionOperator.SupportsType(leftType))
{
- throw new ArtemisCoreException($"Cannot apply operator {displayConditionOperator.GetType().Name} to this predicate because " +
+ throw new ArtemisCoreException($"Cannot apply operator {conditionOperator.GetType().Name} to this predicate because " +
$"it does not support left side type {leftType.Name}");
}
- Operator = displayConditionOperator;
+ Operator = conditionOperator;
CreateExpression();
}
@@ -243,12 +246,12 @@ namespace Artemis.Core
Entity.OperatorType = Operator?.GetType().Name;
}
- internal override void Initialize(IDataModelService dataModelService)
+ internal void Initialize()
{
// Left side
if (Entity.LeftDataModelGuid != null)
{
- var dataModel = dataModelService.GetPluginDataModelByGuid(Entity.LeftDataModelGuid.Value);
+ var dataModel = DataModelStore.Get(Entity.LeftDataModelGuid.Value)?.DataModel;
if (dataModel != null && dataModel.ContainsPath(Entity.LeftPropertyPath))
UpdateLeftSide(dataModel, Entity.LeftPropertyPath);
}
@@ -256,7 +259,7 @@ namespace Artemis.Core
// Operator
if (Entity.OperatorPluginGuid != null)
{
- var conditionOperator = dataModelService.GetConditionOperator(Entity.OperatorPluginGuid.Value, Entity.OperatorType);
+ var conditionOperator = ConditionOperatorStore.Get(Entity.OperatorPluginGuid.Value, Entity.OperatorType)?.ConditionOperator;
if (conditionOperator != null)
UpdateOperator(conditionOperator);
}
@@ -264,7 +267,7 @@ namespace Artemis.Core
// Right side dynamic
if (PredicateType == ProfileRightSideType.Dynamic && Entity.RightDataModelGuid != null)
{
- var dataModel = dataModelService.GetPluginDataModelByGuid(Entity.RightDataModelGuid.Value);
+ var dataModel = DataModelStore.Get(Entity.RightDataModelGuid.Value)?.DataModel;
if (dataModel != null && dataModel.ContainsPath(Entity.RightPropertyPath))
UpdateRightSide(dataModel, Entity.RightPropertyPath);
}
@@ -286,7 +289,7 @@ namespace Artemis.Core
// If deserialization fails, use the type's default
catch (JsonSerializationException e)
{
- dataModelService.LogPredicateDeserializationFailure(this, e);
+ DeserializationLogger.LogPredicateDeserializationFailure(this, e);
rightSideValue = Activator.CreateInstance(leftSideType);
}
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/EqualsConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/EqualsConditionOperator.cs
index 44388b7c1..87b60d484 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Operators/EqualsConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/EqualsConditionOperator.cs
@@ -4,7 +4,7 @@ using System.Linq.Expressions;
namespace Artemis.Core
{
- internal class EqualsConditionOperator : DisplayConditionOperator
+ internal class EqualsConditionOperator : ConditionOperator
{
public override IReadOnlyCollection CompatibleTypes => new List {typeof(object)};
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanConditionOperator.cs
index 37dbccadb..6fa3287a5 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanConditionOperator.cs
@@ -4,7 +4,7 @@ using System.Linq.Expressions;
namespace Artemis.Core
{
- internal class GreaterThanConditionOperator : DisplayConditionOperator
+ internal class GreaterThanConditionOperator : ConditionOperator
{
public override IReadOnlyCollection CompatibleTypes => Constants.NumberTypes;
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanOrEqualConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanOrEqualConditionOperator.cs
index 578c20aab..5bd914abb 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanOrEqualConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/GreaterThanOrEqualConditionOperator.cs
@@ -4,7 +4,7 @@ using System.Linq.Expressions;
namespace Artemis.Core
{
- internal class GreaterThanOrEqualConditionOperator : DisplayConditionOperator
+ internal class GreaterThanOrEqualConditionOperator : ConditionOperator
{
public override IReadOnlyCollection CompatibleTypes => Constants.NumberTypes;
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/LessThanConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/LessThanConditionOperator.cs
index 244b15c08..72567b9a9 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Operators/LessThanConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/LessThanConditionOperator.cs
@@ -4,7 +4,7 @@ using System.Linq.Expressions;
namespace Artemis.Core
{
- internal class LessThanConditionOperator : DisplayConditionOperator
+ internal class LessThanConditionOperator : ConditionOperator
{
public override IReadOnlyCollection CompatibleTypes => Constants.NumberTypes;
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/LessThanOrEqualConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/LessThanOrEqualConditionOperator.cs
index e47b3f018..fd344dbf3 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Operators/LessThanOrEqualConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/LessThanOrEqualConditionOperator.cs
@@ -4,7 +4,7 @@ using System.Linq.Expressions;
namespace Artemis.Core
{
- internal class LessThanOrEqualConditionOperator : DisplayConditionOperator
+ internal class LessThanOrEqualConditionOperator : ConditionOperator
{
public override IReadOnlyCollection CompatibleTypes => Constants.NumberTypes;
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/NotEqualConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/NotEqualConditionOperator.cs
index a1a9934be..4af94147c 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Operators/NotEqualConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/NotEqualConditionOperator.cs
@@ -4,7 +4,7 @@ using System.Linq.Expressions;
namespace Artemis.Core
{
- internal class NotEqualConditionOperator : DisplayConditionOperator
+ internal class NotEqualConditionOperator : ConditionOperator
{
public override IReadOnlyCollection CompatibleTypes => new List {typeof(object)};
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/StringContainsConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/StringContainsConditionOperator.cs
index 758e0400e..3ef231cfd 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Operators/StringContainsConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/StringContainsConditionOperator.cs
@@ -5,7 +5,7 @@ using System.Reflection;
namespace Artemis.Core
{
- internal class StringContainsConditionOperator : DisplayConditionOperator
+ internal class StringContainsConditionOperator : ConditionOperator
{
private readonly MethodInfo _contains;
private readonly MethodInfo _toLower;
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/StringEndsWithConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/StringEndsWithConditionOperator.cs
index 38ed72633..1903984e9 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Operators/StringEndsWithConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/StringEndsWithConditionOperator.cs
@@ -5,7 +5,7 @@ using System.Reflection;
namespace Artemis.Core
{
- internal class StringEndsWithConditionOperator : DisplayConditionOperator
+ internal class StringEndsWithConditionOperator : ConditionOperator
{
private readonly MethodInfo _endsWith;
private readonly MethodInfo _toLower;
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/StringEqualsConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/StringEqualsConditionOperator.cs
index 91a58ec91..cc0cf432c 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Operators/StringEqualsConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/StringEqualsConditionOperator.cs
@@ -5,7 +5,7 @@ using System.Reflection;
namespace Artemis.Core
{
- internal class StringEqualsConditionOperator : DisplayConditionOperator
+ internal class StringEqualsConditionOperator : ConditionOperator
{
private readonly MethodInfo _toLower;
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/StringNotContainsConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/StringNotContainsConditionOperator.cs
index 671555eb5..97fbac2eb 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Operators/StringNotContainsConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/StringNotContainsConditionOperator.cs
@@ -5,7 +5,7 @@ using System.Reflection;
namespace Artemis.Core
{
- internal class StringNotContainsConditionOperator : DisplayConditionOperator
+ internal class StringNotContainsConditionOperator : ConditionOperator
{
private readonly MethodInfo _contains;
private readonly MethodInfo _toLower;
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/StringNotEqualConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/StringNotEqualConditionOperator.cs
index c98d4bef3..33e14b4e1 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Operators/StringNotEqualConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/StringNotEqualConditionOperator.cs
@@ -5,7 +5,7 @@ using System.Reflection;
namespace Artemis.Core
{
- internal class StringNotEqualConditionOperator : DisplayConditionOperator
+ internal class StringNotEqualConditionOperator : ConditionOperator
{
private readonly MethodInfo _toLower;
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/StringNullConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/StringNullConditionOperator.cs
index bb0b99d42..6c51024ed 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Operators/StringNullConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/StringNullConditionOperator.cs
@@ -4,7 +4,7 @@ using System.Linq.Expressions;
namespace Artemis.Core
{
- internal class StringNullConditionOperator : DisplayConditionOperator
+ internal class StringNullConditionOperator : ConditionOperator
{
public StringNullConditionOperator()
{
diff --git a/src/Artemis.Core/Models/Profile/Conditions/Operators/StringStartsWithConditionOperator.cs b/src/Artemis.Core/Models/Profile/Conditions/Operators/StringStartsWithConditionOperator.cs
index f9f9fbf8e..4b3d9f39b 100644
--- a/src/Artemis.Core/Models/Profile/Conditions/Operators/StringStartsWithConditionOperator.cs
+++ b/src/Artemis.Core/Models/Profile/Conditions/Operators/StringStartsWithConditionOperator.cs
@@ -5,7 +5,7 @@ using System.Reflection;
namespace Artemis.Core
{
- internal class StringStartsWithConditionOperator : DisplayConditionOperator
+ internal class StringStartsWithConditionOperator : ConditionOperator
{
private readonly MethodInfo _startsWith;
private readonly MethodInfo _toLower;
diff --git a/src/Artemis.Core/Models/Profile/Folder.cs b/src/Artemis.Core/Models/Profile/Folder.cs
index 5671181ca..1436f7bcf 100644
--- a/src/Artemis.Core/Models/Profile/Folder.cs
+++ b/src/Artemis.Core/Models/Profile/Folder.cs
@@ -42,21 +42,7 @@ namespace Artemis.Core
_layerEffects = new List();
_expandedPropertyGroups = new List();
- _expandedPropertyGroups.AddRange(folderEntity.ExpandedPropertyGroups);
-
- // Load child folders
- foreach (var childFolder in Profile.ProfileEntity.Folders.Where(f => f.ParentId == EntityId))
- ChildrenList.Add(new Folder(profile, this, childFolder));
- // Load child layers
- foreach (var childLayer in Profile.ProfileEntity.Layers.Where(f => f.ParentId == EntityId))
- ChildrenList.Add(new Layer(profile, this, childLayer));
-
- // Ensure order integrity, should be unnecessary but no one is perfect specially me
- ChildrenList = ChildrenList.OrderBy(c => c.Order).ToList();
- for (var index = 0; index < ChildrenList.Count; index++)
- ChildrenList[index].Order = index + 1;
-
- ApplyRenderElementEntity();
+ Load();
}
internal FolderEntity FolderEntity { get; set; }
@@ -263,23 +249,36 @@ namespace Artemis.Core
if (!disposing)
return;
+ _disposed = true;
+
foreach (var baseLayerEffect in LayerEffects)
baseLayerEffect.Dispose();
- _layerEffects.Clear();
-
foreach (var profileElement in Children)
profileElement.Dispose();
- ChildrenList.Clear();
_folderBitmap?.Dispose();
- _folderBitmap = null;
-
- Profile = null;
- _disposed = true;
}
+ internal override void Load()
+ {
+ _expandedPropertyGroups.AddRange(FolderEntity.ExpandedPropertyGroups);
- internal override void ApplyToEntity()
+ // Load child folders
+ foreach (var childFolder in Profile.ProfileEntity.Folders.Where(f => f.ParentId == EntityId))
+ ChildrenList.Add(new Folder(Profile, this, childFolder));
+ // Load child layers
+ foreach (var childLayer in Profile.ProfileEntity.Layers.Where(f => f.ParentId == EntityId))
+ ChildrenList.Add(new Layer(Profile, this, childLayer));
+
+ // Ensure order integrity, should be unnecessary but no one is perfect specially me
+ ChildrenList = ChildrenList.OrderBy(c => c.Order).ToList();
+ for (var index = 0; index < ChildrenList.Count; index++)
+ ChildrenList[index].Order = index + 1;
+
+ LoadRenderElement();
+ }
+
+ internal override void Save()
{
if (_disposed)
throw new ObjectDisposedException("Folder");
@@ -295,11 +294,11 @@ namespace Artemis.Core
FolderEntity.ExpandedPropertyGroups.Clear();
FolderEntity.ExpandedPropertyGroups.AddRange(_expandedPropertyGroups);
- ApplyRenderElementToEntity();
-
// Conditions
RenderElementEntity.RootDisplayCondition = DisplayConditionGroup?.Entity;
DisplayConditionGroup?.ApplyToEntity();
+
+ SaveRenderElement();
}
#region Events
diff --git a/src/Artemis.Core/Models/Profile/Layer.cs b/src/Artemis.Core/Models/Profile/Layer.cs
index 5470a4c46..b1d411e9c 100644
--- a/src/Artemis.Core/Models/Profile/Layer.cs
+++ b/src/Artemis.Core/Models/Profile/Layer.cs
@@ -4,7 +4,6 @@ using System.Collections.ObjectModel;
using System.Linq;
using Artemis.Core.LayerBrushes;
using Artemis.Core.LayerEffects;
-using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile;
using Artemis.Storage.Entities.Profile.Abstract;
using SkiaSharp;
@@ -41,30 +40,27 @@ namespace Artemis.Core
_leds = new List();
_expandedPropertyGroups = new List();
- General.PropertyGroupInitialized += GeneralOnPropertyGroupInitialized;
+ InitializeDefaultGroups();
+
+ parent.AddChild(this);
ApplyRenderElementDefaults();
}
internal Layer(Profile profile, ProfileElement parent, LayerEntity layerEntity)
{
LayerEntity = layerEntity;
- EntityId = layerEntity.Id;
-
Profile = profile;
Parent = parent;
- Name = layerEntity.Name;
- Enabled = layerEntity.Enabled;
- Order = layerEntity.Order;
General = new LayerGeneralProperties();
Transform = new LayerTransformProperties();
_layerEffects = new List();
_leds = new List();
_expandedPropertyGroups = new List();
- _expandedPropertyGroups.AddRange(layerEntity.ExpandedPropertyGroups);
- General.PropertyGroupInitialized += GeneralOnPropertyGroupInitialized;
- ApplyRenderElementEntity();
+ InitializeDefaultGroups();
+
+ Load();
}
internal LayerEntity LayerEntity { get; set; }
@@ -128,25 +124,41 @@ namespace Artemis.Core
// Brush first in case it depends on any of the other disposables during it's own disposal
_layerBrush?.Dispose();
- _layerBrush = null;
foreach (var baseLayerEffect in LayerEffects)
baseLayerEffect.Dispose();
- _layerEffects.Clear();
_general?.Dispose();
- _general = null;
_layerBitmap?.Dispose();
- _layerBitmap = null;
_transform?.Dispose();
- _transform = null;
+ }
- Profile = null;
+ private void InitializeDefaultGroups()
+ {
+ // Layers have two hardcoded property groups, instantiate them
+ General.Initialize(this, "General.", Constants.CorePluginInfo);
+ Transform.Initialize(this, "Transform.", Constants.CorePluginInfo);
+
+ General.ShapeType.BaseValueChanged += ShapeTypeOnBaseValueChanged;
+ ApplyShapeType();
}
#region Storage
- internal override void ApplyToEntity()
+ internal override void Load()
+ {
+ EntityId = LayerEntity.Id;
+ Name = LayerEntity.Name;
+ Enabled = LayerEntity.Enabled;
+ Order = LayerEntity.Order;
+
+ _expandedPropertyGroups.AddRange(LayerEntity.ExpandedPropertyGroups);
+ ActivateLayerBrush();
+
+ LoadRenderElement();
+ }
+
+ internal override void Save()
{
if (_disposed)
throw new ObjectDisposedException("Layer");
@@ -181,20 +193,13 @@ namespace Artemis.Core
RenderElementEntity.RootDisplayCondition = DisplayConditionGroup?.Entity;
DisplayConditionGroup?.ApplyToEntity();
- ApplyRenderElementToEntity();
+ SaveRenderElement();
}
#endregion
#region Shape management
- private void GeneralOnPropertyGroupInitialized(object sender, EventArgs e)
- {
- ApplyShapeType();
- General.ShapeType.BaseValueChanged -= ShapeTypeOnBaseValueChanged;
- General.ShapeType.BaseValueChanged += ShapeTypeOnBaseValueChanged;
- }
-
private void ShapeTypeOnBaseValueChanged(object sender, EventArgs e)
{
ApplyShapeType();
@@ -290,7 +295,7 @@ namespace Artemis.Core
baseLayerEffect.Update(delta);
}
}
-
+
///
public override void Render(double deltaTime, SKCanvas canvas, SKImageInfo canvasInfo)
{
@@ -646,7 +651,51 @@ namespace Artemis.Core
#endregion
- #region Activation
+ #region Brush management
+
+ ///
+ /// Changes the current layer brush to the brush described in the provided
+ ///
+ public void ChangeLayerBrush(LayerBrushDescriptor descriptor)
+ {
+ if (descriptor == null)
+ throw new ArgumentNullException(nameof(descriptor));
+
+ // Ensure the brush reference matches the brush
+ var current = General.BrushReference.CurrentValue;
+ if (current.BrushPluginGuid != descriptor.LayerBrushProvider.PluginInfo.Guid || current.BrushType != descriptor.LayerBrushType.Name)
+ {
+ General.BrushReference.CurrentValue = new LayerBrushReference
+ {
+ BrushPluginGuid = descriptor.LayerBrushProvider.PluginInfo.Guid,
+ BrushType = descriptor.LayerBrushType.Name
+ };
+ }
+
+ ActivateLayerBrush();
+ }
+
+ ///
+ /// Removes the current layer brush from the layer
+ ///
+ public void RemoveLayerBrush()
+ {
+ if (LayerBrush == null)
+ return;
+
+ var brush = LayerBrush;
+ DeactivateLayerBrush();
+ LayerEntity.PropertyEntities.RemoveAll(p => p.PluginGuid == brush.PluginInfo.Guid && p.Path.StartsWith("LayerBrush."));
+ }
+
+ internal void ActivateLayerBrush()
+ {
+ var current = General.BrushReference.CurrentValue;
+ var descriptor = LayerBrushStore.Get(current.BrushPluginGuid, current.BrushType)?.LayerBrushDescriptor;
+ descriptor?.CreateInstance(this);
+
+ OnLayerBrushUpdated();
+ }
internal void DeactivateLayerBrush()
{
@@ -656,16 +705,8 @@ namespace Artemis.Core
var brush = LayerBrush;
LayerBrush = null;
brush.Dispose();
- }
- internal void RemoveLayerBrush()
- {
- if (LayerBrush == null)
- return;
-
- var brush = LayerBrush;
- DeactivateLayerBrush();
- LayerEntity.PropertyEntities.RemoveAll(p => p.PluginGuid == brush.PluginInfo.Guid && p.Path.StartsWith("LayerBrush."));
+ OnLayerBrushUpdated();
}
#endregion
diff --git a/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs b/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs
index e753cd3d7..b6720b92f 100644
--- a/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs
+++ b/src/Artemis.Core/Models/Profile/LayerPropertyGroup.cs
@@ -171,14 +171,6 @@ namespace Artemis.Core
OnPropertyGroupInitialized();
}
- internal void InitializeDataBindings(IDataModelService dataModelService, IDataModelService dataModelService1)
- {
- foreach (var layerProperty in LayerProperties)
- {
- layerProperty.InitializeDataBindings(dataModelService);
- }
- }
-
internal void ApplyToEntity()
{
if (!PropertiesInitialized)
diff --git a/src/Artemis.Core/Models/Profile/Profile.cs b/src/Artemis.Core/Models/Profile/Profile.cs
index 030cf786f..e23874cfe 100644
--- a/src/Artemis.Core/Models/Profile/Profile.cs
+++ b/src/Artemis.Core/Models/Profile/Profile.cs
@@ -22,7 +22,7 @@ namespace Artemis.Core
RedoStack = new Stack();
AddChild(new Folder(this, this, "Root folder"));
- ApplyToEntity();
+ Save();
}
internal Profile(ProfileModule module, ProfileEntity profileEntity)
@@ -129,7 +129,7 @@ namespace Artemis.Core
_disposed = true;
}
- internal override void ApplyToEntity()
+ internal override void Save()
{
if (_disposed)
throw new ObjectDisposedException("Profile");
@@ -140,7 +140,7 @@ namespace Artemis.Core
ProfileEntity.IsActive = IsActivated;
foreach (var profileElement in Children)
- profileElement.ApplyToEntity();
+ profileElement.Save();
ProfileEntity.Folders.Clear();
ProfileEntity.Folders.AddRange(GetAllFolders().Select(f => f.FolderEntity));
diff --git a/src/Artemis.Core/Models/Profile/ProfileElement.cs b/src/Artemis.Core/Models/Profile/ProfileElement.cs
index efa5bdb52..0a2ee39aa 100644
--- a/src/Artemis.Core/Models/Profile/ProfileElement.cs
+++ b/src/Artemis.Core/Models/Profile/ProfileElement.cs
@@ -23,18 +23,27 @@ namespace Artemis.Core
ChildrenList = new List();
}
+ ///
+ /// Gets the unique ID of this profile element
+ ///
public Guid EntityId
{
get => _entityId;
internal set => SetAndNotify(ref _entityId, value);
}
+ ///
+ /// Gets the profile this element belongs to
+ ///
public Profile Profile
{
get => _profile;
internal set => SetAndNotify(ref _profile, value);
}
+ ///
+ /// Gets the parent of this element
+ ///
public ProfileElement Parent
{
get => _parent;
@@ -73,12 +82,6 @@ namespace Artemis.Core
set => SetAndNotify(ref _enabled, value);
}
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
///
/// Updates the element
///
@@ -90,39 +93,13 @@ namespace Artemis.Core
///
public abstract void Render(double deltaTime, SKCanvas canvas, SKImageInfo canvasInfo);
- public List GetAllFolders()
+ ///
+ public override string ToString()
{
- if (_disposed)
- throw new ObjectDisposedException(GetType().Name);
-
- var folders = new List();
- foreach (var childFolder in Children.Where(c => c is Folder).Cast())
- {
- // Add all folders in this element
- folders.Add(childFolder);
- // Add all folders in folders inside this element
- folders.AddRange(childFolder.GetAllFolders());
- }
-
- return folders;
+ return $"{nameof(EntityId)}: {EntityId}, {nameof(Order)}: {Order}, {nameof(Name)}: {Name}";
}
- public List GetAllLayers()
- {
- if (_disposed)
- throw new ObjectDisposedException(GetType().Name);
-
- var layers = new List();
-
- // Add all layers in this element
- layers.AddRange(Children.Where(c => c is Layer).Cast());
-
- // Add all layers in folders inside this element
- foreach (var childFolder in Children.Where(c => c is Folder).Cast())
- layers.AddRange(childFolder.GetAllLayers());
-
- return layers;
- }
+ #region Hierarchy
///
/// Adds a profile element to the collection, optionally at the given position (1-based)
@@ -189,9 +166,64 @@ namespace Artemis.Core
OnChildRemoved();
}
- public override string ToString()
+ ///
+ /// Returns a flattened list of all child folders
+ ///
+ ///
+ public List GetAllFolders()
{
- return $"{nameof(EntityId)}: {EntityId}, {nameof(Order)}: {Order}, {nameof(Name)}: {Name}";
+ if (_disposed)
+ throw new ObjectDisposedException(GetType().Name);
+
+ var folders = new List();
+ foreach (var childFolder in Children.Where(c => c is Folder).Cast())
+ {
+ // Add all folders in this element
+ folders.Add(childFolder);
+ // Add all folders in folders inside this element
+ folders.AddRange(childFolder.GetAllFolders());
+ }
+
+ return folders;
+ }
+
+ ///
+ /// Returns a flattened list of all child layers
+ ///
+ ///
+ public List GetAllLayers()
+ {
+ if (_disposed)
+ throw new ObjectDisposedException(GetType().Name);
+
+ var layers = new List();
+
+ // Add all layers in this element
+ layers.AddRange(Children.Where(c => c is Layer).Cast());
+
+ // Add all layers in folders inside this element
+ foreach (var childFolder in Children.Where(c => c is Folder).Cast())
+ layers.AddRange(childFolder.GetAllLayers());
+
+ return layers;
+ }
+
+ #endregion
+
+ #region Storage
+
+ internal abstract void Load();
+ internal abstract void Save();
+
+ #endregion
+
+ #region IDisposable
+
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
@@ -201,10 +233,7 @@ namespace Artemis.Core
}
}
- ///
- /// Applies the profile element's properties to the underlying storage entity
- ///
- internal abstract void ApplyToEntity();
+ #endregion
#region Events
diff --git a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
index a75ed2b56..bc3d86cb6 100644
--- a/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
+++ b/src/Artemis.Core/Models/Profile/RenderProfileElement.cs
@@ -12,21 +12,23 @@ namespace Artemis.Core
{
public abstract class RenderProfileElement : ProfileElement
{
- protected void ApplyRenderElementDefaults()
+ internal void ApplyRenderElementDefaults()
{
MainSegmentLength = TimeSpan.FromSeconds(5);
}
- protected void ApplyRenderElementEntity()
+ internal void LoadRenderElement()
{
StartSegmentLength = RenderElementEntity.StartSegmentLength;
MainSegmentLength = RenderElementEntity.MainSegmentLength;
EndSegmentLength = RenderElementEntity.EndSegmentLength;
DisplayContinuously = RenderElementEntity.DisplayContinuously;
AlwaysFinishTimeline = RenderElementEntity.AlwaysFinishTimeline;
+
+ ActivateEffects();
}
- protected void ApplyRenderElementToEntity()
+ internal void SaveRenderElement()
{
RenderElementEntity.StartSegmentLength = StartSegmentLength;
RenderElementEntity.MainSegmentLength = MainSegmentLength;
@@ -206,7 +208,7 @@ namespace Artemis.Core
#endregion
- #region Effects
+ #region Effect management
protected List _layerEffects;
@@ -215,11 +217,35 @@ namespace Artemis.Core
///
public ReadOnlyCollection LayerEffects => _layerEffects.AsReadOnly();
- internal void RemoveLayerEffect([NotNull] BaseLayerEffect effect)
+ ///
+ /// Adds a the layer effect described inthe provided
+ ///
+ public void AddLayerEffect(LayerEffectDescriptor descriptor)
+ {
+ if (descriptor == null)
+ throw new ArgumentNullException(nameof(descriptor));
+
+ var entity = new LayerEffectEntity
+ {
+ Id = Guid.NewGuid(),
+ Enabled = true,
+ Order = LayerEffects.Count + 1
+ };
+ descriptor.CreateInstance(this, entity);
+ OnLayerEffectsUpdated();
+ }
+
+ ///
+ /// Removes the provided layer
+ ///
+ ///
+ public void RemoveLayerEffect([NotNull] BaseLayerEffect effect)
{
if (effect == null) throw new ArgumentNullException(nameof(effect));
- DeactivateLayerEffect(effect);
+ // Remove the effect from the layer and dispose it
+ _layerEffects.Remove(effect);
+ effect.Dispose();
// Update the order on the remaining effects
var index = 0;
@@ -232,20 +258,31 @@ namespace Artemis.Core
OnLayerEffectsUpdated();
}
- internal void AddLayerEffect([NotNull] BaseLayerEffect effect)
+ internal void ActivateEffects()
{
- if (effect == null) throw new ArgumentNullException(nameof(effect));
- _layerEffects.Add(effect);
- OnLayerEffectsUpdated();
+ foreach (var layerEffectEntity in RenderElementEntity.LayerEffects)
+ {
+ if (_layerEffects.Any(e => e.EntityId == layerEffectEntity.Id))
+ continue;
+
+ var descriptor = LayerEffectStore.Get(layerEffectEntity.PluginGuid, layerEffectEntity.EffectType)?.LayerEffectDescriptor;
+ descriptor?.CreateInstance(this, layerEffectEntity);
+ }
}
- internal void DeactivateLayerEffect([NotNull] BaseLayerEffect effect)
+ internal void ActivateLayerEffect(BaseLayerEffect layerEffect)
{
- if (effect == null) throw new ArgumentNullException(nameof(effect));
+ _layerEffects.Add(layerEffect);
- // Remove the effect from the layer and dispose it
- _layerEffects.Remove(effect);
- effect.Dispose();
+ // Update the order on the effects
+ var index = 0;
+ foreach (var baseLayerEffect in LayerEffects.OrderBy(e => e.Order))
+ {
+ baseLayerEffect.Order = Order = index + 1;
+ index++;
+ }
+
+ OnLayerEffectsUpdated();
}
#endregion
@@ -296,6 +333,5 @@ namespace Artemis.Core
}
#endregion
-
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs b/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs
index 9edd2a6cc..e0fbc4f35 100644
--- a/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs
+++ b/src/Artemis.Core/Plugins/DataModelExpansions/DataModel.cs
@@ -22,6 +22,12 @@ namespace Artemis.Core.DataModelExpansions
[DataModelIgnore]
public DataModelPropertyAttribute DataModelDescription { get; internal set; }
+ ///
+ /// Gets the is expansion status indicating whether this data model expands the main data model
+ ///
+ [DataModelIgnore]
+ public bool IsExpansion { get; internal set; }
+
public bool ContainsPath(string path)
{
var parts = path.Split('.');
diff --git a/src/Artemis.Core/Plugins/DataModelExpansions/DataModelExpansion.cs b/src/Artemis.Core/Plugins/DataModelExpansions/DataModelExpansion.cs
index 8230e08f8..28946a89b 100644
--- a/src/Artemis.Core/Plugins/DataModelExpansions/DataModelExpansion.cs
+++ b/src/Artemis.Core/Plugins/DataModelExpansions/DataModelExpansion.cs
@@ -10,7 +10,8 @@ namespace Artemis.Core.DataModelExpansions
public abstract class DataModelExpansion : BaseDataModelExpansion where T : DataModel
{
///
- /// The data model driving this module
+ /// The main data model of this data model expansion
+ /// Note: This default data model is automatically registered upon plugin enable
///
public T DataModel
{
diff --git a/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushDescriptor.cs b/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushDescriptor.cs
index 685435646..a4173e75c 100644
--- a/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushDescriptor.cs
+++ b/src/Artemis.Core/Plugins/LayerBrushes/LayerBrushDescriptor.cs
@@ -1,4 +1,5 @@
using System;
+using Ninject;
namespace Artemis.Core.LayerBrushes
{
@@ -41,5 +42,28 @@ namespace Artemis.Core.LayerBrushes
/// The plugin that provided this
///
public LayerBrushProvider LayerBrushProvider { get; }
+
+ ///
+ /// Gets or sets the kernel used to instantiate the described layer brush
+ ///
+ internal IKernel Kernel { get; set; }
+
+ ///
+ /// Creates an instance of the described brush and applies it to the layer
+ ///
+ internal void CreateInstance(Layer layer)
+ {
+ if (layer.LayerBrush != null)
+ throw new ArtemisCoreException("Layer already has an instantiated layer brush");
+
+ var brush = (BaseLayerBrush) Kernel.Get(LayerBrushType);
+ brush.Layer = layer;
+ brush.Descriptor = this;
+ brush.Initialize();
+ brush.Update(0);
+
+ layer.LayerBrush = brush;
+ layer.OnLayerBrushUpdated();
+ }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs b/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs
index b3c1db3b5..47d95d396 100644
--- a/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs
+++ b/src/Artemis.Core/Plugins/LayerEffects/LayerEffectDescriptor.cs
@@ -1,4 +1,8 @@
using System;
+using System.Linq;
+using Artemis.Core.LayerBrushes;
+using Artemis.Storage.Entities.Profile;
+using Ninject;
namespace Artemis.Core.LayerEffects
{
@@ -41,5 +45,33 @@ namespace Artemis.Core.LayerEffects
/// The plugin that provided this
///
public LayerEffectProvider LayerEffectProvider { get; }
+
+ ///
+ /// Gets or sets the kernel used to instantiate the described layer effect
+ ///
+ internal IKernel Kernel { get; set; }
+
+ ///
+ /// Creates an instance of the described effect and applies it to the render element
+ ///
+ internal void CreateInstance(RenderProfileElement renderElement, LayerEffectEntity entity)
+ {
+ // Skip effects already on the element
+ if (renderElement.LayerEffects.Any(e => e.EntityId == entity.Id))
+ return;
+
+ var effect = (BaseLayerEffect) Kernel.Get(LayerEffectType);
+ effect.ProfileElement = renderElement;
+ effect.EntityId = entity.Id;
+ effect.Order = entity.Order;
+ effect.Name = entity.Name;
+ effect.Enabled = entity.Enabled;
+ effect.Descriptor = this;
+
+ effect.Initialize();
+ effect.Update(0);
+
+ renderElement.ActivateLayerEffect(effect);
+ }
}
}
\ 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 31efee688..e67eb1174 100644
--- a/src/Artemis.Core/Plugins/Modules/Module.cs
+++ b/src/Artemis.Core/Plugins/Modules/Module.cs
@@ -14,6 +14,7 @@ namespace Artemis.Core.Modules
{
///
/// The data model driving this module
+ /// Note: This default data model is automatically registered upon plugin enable
///
public T DataModel
{
diff --git a/src/Artemis.Core/Plugins/Modules/ProfileModule.cs b/src/Artemis.Core/Plugins/Modules/ProfileModule.cs
index 9b7c303ff..86afbcc0a 100644
--- a/src/Artemis.Core/Plugins/Modules/ProfileModule.cs
+++ b/src/Artemis.Core/Plugins/Modules/ProfileModule.cs
@@ -18,6 +18,7 @@ namespace Artemis.Core.Modules
{
///
/// The data model driving this module
+ /// Note: This default data model is automatically registered upon plugin enable
///
public T DataModel
{
@@ -118,7 +119,7 @@ namespace Artemis.Core.Modules
/// Indicates whether or not a profile change is being animated
///
public bool AnimatingProfileChange { get; private set; }
-
+
///
/// Called after the profile has updated
///
diff --git a/src/Artemis.Core/Services/CoreService.cs b/src/Artemis.Core/Services/CoreService.cs
index 1c739c425..eaf195c28 100644
--- a/src/Artemis.Core/Services/CoreService.cs
+++ b/src/Artemis.Core/Services/CoreService.cs
@@ -9,6 +9,7 @@ using Artemis.Core.JsonConverters;
using Artemis.Core.Ninject;
using Artemis.Storage;
using Newtonsoft.Json;
+using Ninject;
using RGB.NET.Core;
using Serilog;
using Serilog.Events;
@@ -23,6 +24,7 @@ namespace Artemis.Core.Services
internal class CoreService : ICoreService
{
private readonly Stopwatch _frameStopWatch;
+ private readonly IKernel _kernel;
private readonly ILogger _logger;
private readonly PluginSetting _loggingLevel;
private readonly IPluginService _pluginService;
@@ -34,9 +36,10 @@ namespace Artemis.Core.Services
private List _modules;
// ReSharper disable once UnusedParameter.Local - Storage migration service is injected early to ensure it runs before anything else
- public CoreService(ILogger logger, StorageMigrationService _, ISettingsService settingsService, IPluginService pluginService,
- IRgbService rgbService, ISurfaceService surfaceService, IProfileService profileService, IModuleService moduleService)
+ public CoreService(IKernel kernel, ILogger logger, StorageMigrationService _, ISettingsService settingsService, IPluginService pluginService,
+ IRgbService rgbService, ISurfaceService surfaceService, IProfileService profileService)
{
+ _kernel = kernel;
_logger = logger;
_pluginService = pluginService;
_rgbService = rgbService;
@@ -77,6 +80,8 @@ namespace Artemis.Core.Services
_logger.Information("Initializing Artemis Core version {version}", versionAttribute?.InformationalVersion);
ApplyLoggingLevel();
+ DeserializationLogger.Initialize(_kernel);
+
// Initialize the services
_pluginService.CopyBuiltInPlugins();
_pluginService.LoadPlugins(StartupArguments.Contains("--ignore-plugin-lock"));
diff --git a/src/Artemis.Core/Services/DataBindingService.cs b/src/Artemis.Core/Services/DataBindingService.cs
deleted file mode 100644
index 3af46569f..000000000
--- a/src/Artemis.Core/Services/DataBindingService.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Newtonsoft.Json;
-using Serilog;
-
-namespace Artemis.Core.Services
-{
- internal class DataBindingService : IDataBindingService
- {
- private readonly ILogger _logger;
- private readonly List _registeredDataBindingModifierTypes;
-
- public DataBindingService(ILogger logger)
- {
- _logger = logger;
- _registeredDataBindingModifierTypes = new List();
-
- RegisterBuiltInModifiers();
- }
-
- public IReadOnlyCollection RegisteredDataBindingModifierTypes
- {
- get
- {
- lock (_registeredDataBindingModifierTypes)
- {
- return _registeredDataBindingModifierTypes.AsReadOnly();
- }
- }
- }
-
- public void RegisterModifierType(PluginInfo pluginInfo, DataBindingModifierType dataBindingModifierType)
- {
- if (pluginInfo == null)
- throw new ArgumentNullException(nameof(pluginInfo));
- if (dataBindingModifierType == null)
- throw new ArgumentNullException(nameof(dataBindingModifierType));
-
- lock (_registeredDataBindingModifierTypes)
- {
- if (_registeredDataBindingModifierTypes.Contains(dataBindingModifierType))
- return;
-
- dataBindingModifierType.Register(pluginInfo, this);
- _registeredDataBindingModifierTypes.Add(dataBindingModifierType);
- }
- }
-
- public void RemoveModifierType(DataBindingModifierType dataBindingModifierType)
- {
- if (dataBindingModifierType == null)
- throw new ArgumentNullException(nameof(dataBindingModifierType));
-
- lock (_registeredDataBindingModifierTypes)
- {
- if (!_registeredDataBindingModifierTypes.Contains(dataBindingModifierType))
- return;
-
- dataBindingModifierType.Unsubscribe();
- _registeredDataBindingModifierTypes.Remove(dataBindingModifierType);
- }
- }
-
- public List GetCompatibleModifierTypes(Type type)
- {
- lock (_registeredDataBindingModifierTypes)
- {
- if (type == null)
- return new List(_registeredDataBindingModifierTypes);
-
- var candidates = _registeredDataBindingModifierTypes.Where(c => c.CompatibleTypes.Any(t => t.IsCastableFrom(type))).ToList();
-
- // If there are multiple modifier types with the same description, use the closest match
- foreach (var dataBindingModifierTypes in candidates.GroupBy(c => c.Description).Where(g => g.Count() > 1).ToList())
- {
- var bestCandidate = dataBindingModifierTypes.OrderByDescending(c => c.CompatibleTypes.Contains(type)).FirstOrDefault();
- foreach (var dataBindingModifierType in dataBindingModifierTypes)
- {
- if (dataBindingModifierType != bestCandidate)
- candidates.Remove(dataBindingModifierType);
- }
- }
-
- return candidates;
- }
- }
-
- public DataBindingModifierType GetModifierType(Guid modifierTypePluginGuid, string modifierType)
- {
- return RegisteredDataBindingModifierTypes.FirstOrDefault(o => o.PluginInfo.Guid == modifierTypePluginGuid && o.GetType().Name == modifierType);
- }
-
- public void LogModifierDeserializationFailure(string modifierName, JsonSerializationException exception)
- {
- _logger.Warning(exception, "Failed to deserialize static parameter for modifier {modifierName}", modifierName);
- }
-
- private void RegisterBuiltInModifiers()
- {
- RegisterModifierType(Constants.CorePluginInfo, new MultiplicationModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new DivideModifierType());
- RegisterModifierType(Constants.CorePluginInfo, new FloorModifierType());
- }
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/DataModelService.cs b/src/Artemis.Core/Services/DataModelService.cs
deleted file mode 100644
index 8d5d8956d..000000000
--- a/src/Artemis.Core/Services/DataModelService.cs
+++ /dev/null
@@ -1,252 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Artemis.Core.DataModelExpansions;
-using Artemis.Core.Modules;
-using Newtonsoft.Json;
-using Serilog;
-
-namespace Artemis.Core.Services
-{
- ///
- /// Provides access to the main data model
- ///
- internal class DataModelService : IDataModelService
- {
- private readonly List _dataModelExpansions;
- private readonly ILogger _logger;
- private readonly IPluginService _pluginService;
- private readonly List _registeredConditionOperators;
-
- public DataModelService(IPluginService pluginService, ILogger logger)
- {
- _pluginService = pluginService;
- _logger = logger;
- _dataModelExpansions = new List();
- _registeredConditionOperators = new List();
-
- _pluginService.PluginEnabled += PluginServiceOnPluginEnabled;
- _pluginService.PluginDisabled += PluginServiceOnPluginDisabled;
-
- RegisterBuiltInConditionOperators();
-
- foreach (var module in _pluginService.GetPluginsOfType().Where(m => m.InternalExpandsMainDataModel))
- AddModuleDataModel(module);
- foreach (var dataModelExpansion in _pluginService.GetPluginsOfType())
- AddDataModelExpansionDataModel(dataModelExpansion);
- }
-
- public IReadOnlyCollection RegisteredConditionOperators
- {
- get
- {
- lock (_registeredConditionOperators)
- {
- return _registeredConditionOperators.AsReadOnly();
- }
- }
- }
-
- public IReadOnlyCollection DataModelExpansions
- {
- get
- {
- lock (_dataModelExpansions)
- {
- return new List(_dataModelExpansions).AsReadOnly();
- }
- }
- }
-
- public void AddExpansion(DataModel dataModelExpansion)
- {
- lock (_dataModelExpansions)
- {
- _dataModelExpansions.Add(dataModelExpansion);
- // TODO SpoinkyNL 3-3-2018: Initialize the expansion and fire an event
- }
- }
-
- public void RemoveExpansion(DataModel dataModelExpansion)
- {
- lock (_dataModelExpansions)
- {
- if (!_dataModelExpansions.Contains(dataModelExpansion))
- throw new ArtemisCoreException("Cannot remove a data model expansion that wasn't previously added.");
-
- // TODO SpoinkyNL 3-3-2018: Dispose the expansion and fire an event
- _dataModelExpansions.Remove(dataModelExpansion);
- }
- }
-
- public DataModel GetPluginDataModel(Plugin plugin)
- {
- if (plugin is Module module)
- return module.InternalDataModel;
- if (plugin is BaseDataModelExpansion dataModelExpansion)
- return dataModelExpansion.InternalDataModel;
- return null;
- }
-
- public DataModel GetPluginDataModelByGuid(Guid pluginGuid)
- {
- var pluginInfo = _pluginService.GetAllPluginInfo().FirstOrDefault(i => i.Guid == pluginGuid);
- if (pluginInfo == null || !pluginInfo.Enabled)
- return null;
-
- return GetPluginDataModel(pluginInfo.Instance);
- }
-
- public bool GetPluginExtendsDataModel(Plugin plugin)
- {
- if (plugin is Module module)
- return module.InternalExpandsMainDataModel;
- if (plugin is BaseDataModelExpansion)
- return true;
-
- return false;
- }
-
-
- public void RegisterConditionOperator(PluginInfo pluginInfo, DisplayConditionOperator displayConditionOperator)
- {
- if (pluginInfo == null)
- throw new ArgumentNullException(nameof(pluginInfo));
- if (displayConditionOperator == null)
- throw new ArgumentNullException(nameof(displayConditionOperator));
-
- lock (_registeredConditionOperators)
- {
- if (_registeredConditionOperators.Contains(displayConditionOperator))
- return;
-
- displayConditionOperator.Register(pluginInfo, this);
- _registeredConditionOperators.Add(displayConditionOperator);
- }
- }
-
- public void RemoveConditionOperator(DisplayConditionOperator displayConditionOperator)
- {
- if (displayConditionOperator == null)
- throw new ArgumentNullException(nameof(displayConditionOperator));
-
- lock (_registeredConditionOperators)
- {
- if (!_registeredConditionOperators.Contains(displayConditionOperator))
- return;
-
- displayConditionOperator.Unsubscribe();
- _registeredConditionOperators.Remove(displayConditionOperator);
- }
- }
-
- public List GetCompatibleConditionOperators(Type type)
- {
- lock (_registeredConditionOperators)
- {
- if (type == null)
- return new List(_registeredConditionOperators);
-
- var candidates = _registeredConditionOperators.Where(c => c.CompatibleTypes.Any(t => t.IsCastableFrom(type))).ToList();
-
- // If there are multiple operators with the same description, use the closest match
- foreach (var displayConditionOperators in candidates.GroupBy(c => c.Description).Where(g => g.Count() > 1).ToList())
- {
- var bestCandidate = displayConditionOperators.OrderByDescending(c => c.CompatibleTypes.Contains(type)).FirstOrDefault();
- foreach (var displayConditionOperator in displayConditionOperators)
- {
- if (displayConditionOperator != bestCandidate)
- candidates.Remove(displayConditionOperator);
- }
- }
-
- return candidates;
- }
- }
-
- public DisplayConditionOperator GetConditionOperator(Guid operatorPluginGuid, string operatorType)
- {
- return RegisteredConditionOperators.FirstOrDefault(o => o.PluginInfo.Guid == operatorPluginGuid && o.GetType().Name == operatorType);
- }
-
- public void LogPredicateDeserializationFailure(DisplayConditionPredicate displayConditionPredicate, JsonException exception)
- {
- _logger.Warning(
- exception,
- "Failed to deserialize display condition predicate {left} {operator} {right}",
- displayConditionPredicate.Entity.LeftPropertyPath,
- displayConditionPredicate.Entity.OperatorType,
- displayConditionPredicate.Entity.RightPropertyPath
- );
- }
-
- public void LogListPredicateDeserializationFailure(DisplayConditionListPredicate displayConditionPredicate, JsonException exception)
- {
- _logger.Warning(
- exception,
- "Failed to deserialize display condition list predicate {list} => {left} {operator} {right}",
- displayConditionPredicate.Entity.ListPropertyPath,
- displayConditionPredicate.Entity.LeftPropertyPath,
- displayConditionPredicate.Entity.OperatorType,
- displayConditionPredicate.Entity.RightPropertyPath
- );
- }
-
- private void RegisterBuiltInConditionOperators()
- {
- // General usage for any type
- RegisterConditionOperator(Constants.CorePluginInfo, new EqualsConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new NotEqualConditionOperator());
-
- // Numeric operators
- RegisterConditionOperator(Constants.CorePluginInfo, new LessThanConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new GreaterThanConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, new LessThanOrEqualConditionOperator());
- RegisterConditionOperator(Constants.CorePluginInfo, 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 StringNullConditionOperator());
- }
-
- private void PluginServiceOnPluginEnabled(object sender, PluginEventArgs e)
- {
- if (e.PluginInfo.Instance is Module module && module.InternalExpandsMainDataModel)
- AddModuleDataModel(module);
- else if (e.PluginInfo.Instance is BaseDataModelExpansion dataModelExpansion)
- AddDataModelExpansionDataModel(dataModelExpansion);
- }
-
- private void AddDataModelExpansionDataModel(BaseDataModelExpansion dataModelExpansion)
- {
- if (dataModelExpansion.InternalDataModel.DataModelDescription == null)
- throw new ArtemisPluginException(dataModelExpansion.PluginInfo, "Data model expansion overrides GetDataModelDescription but returned null");
-
- AddExpansion(dataModelExpansion.InternalDataModel);
- }
-
- private void AddModuleDataModel(Module module)
- {
- if (module.InternalDataModel.DataModelDescription == null)
- throw new ArtemisPluginException(module.PluginInfo, "Module overrides GetDataModelDescription but returned null");
-
- AddExpansion(module.InternalDataModel);
- }
-
- private void PluginServiceOnPluginDisabled(object sender, PluginEventArgs e)
- {
- // Remove all data models related to the plugin
- lock (_dataModelExpansions)
- {
- var toRemove = _dataModelExpansions.Where(d => d.PluginInfo == e.PluginInfo).ToList();
- foreach (var dataModel in toRemove)
- _dataModelExpansions.Remove(dataModel);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Interfaces/ICoreService.cs b/src/Artemis.Core/Services/Interfaces/ICoreService.cs
index 674db94ef..b506f18ac 100644
--- a/src/Artemis.Core/Services/Interfaces/ICoreService.cs
+++ b/src/Artemis.Core/Services/Interfaces/ICoreService.cs
@@ -3,6 +3,9 @@ using System.Collections.Generic;
namespace Artemis.Core.Services
{
+ ///
+ /// A service that initializes the Core and manages the render loop
+ ///
public interface ICoreService : IArtemisService, IDisposable
{
///
diff --git a/src/Artemis.Core/Services/Interfaces/IDataModelService.cs b/src/Artemis.Core/Services/Interfaces/IDataModelService.cs
deleted file mode 100644
index 7b2cb5582..000000000
--- a/src/Artemis.Core/Services/Interfaces/IDataModelService.cs
+++ /dev/null
@@ -1,91 +0,0 @@
-using System;
-using System.Collections.Generic;
-using Artemis.Core.DataModelExpansions;
-using Artemis.Core.Properties;
-using Newtonsoft.Json;
-
-namespace Artemis.Core.Services
-{
- public interface IDataModelService : IArtemisService
- {
- ///
- /// Gets a read-only collection of all registered condition operators
- ///
- IReadOnlyCollection RegisteredConditionOperators { get; }
-
- ///
- /// Gets a read-only collection of all registered data model expansions
- ///
- IReadOnlyCollection DataModelExpansions { get; }
-
- ///
- /// Add an expansion to the datamodel to be available for use after the next update
- ///
- ///
- void AddExpansion(DataModel baseDataModelExpansion);
-
- ///
- /// Remove a previously added expansion so that it is no longer available and updated
- ///
- ///
- void RemoveExpansion(DataModel baseDataModelExpansion);
-
- ///
- /// If found, returns the data model of the provided plugin
- ///
- /// Should be a module with a data model or a data model expansion
- DataModel GetPluginDataModel(Plugin plugin);
-
- ///
- /// If found, returns the data model of the provided plugin
- ///
- /// Should be a module with a data model or a data model expansion
- DataModel GetPluginDataModelByGuid(Guid pluginGuid);
-
- ///
- /// Determines whether the given plugin expands the main data model
- ///
- ///
- ///
- bool GetPluginExtendsDataModel(Plugin plugin);
-
- ///
- /// Registers a new condition operator for use in layer conditions
- ///
- /// The PluginInfo of the plugin this condition operator belongs to
- /// The condition operator to register
- void RegisterConditionOperator([NotNull] PluginInfo pluginInfo, [NotNull] DisplayConditionOperator displayConditionOperator);
-
- ///
- /// Removes a condition operator so it is no longer available for use in layer conditions
- ///
- /// The layer condition operator to remove
- void RemoveConditionOperator([NotNull] DisplayConditionOperator displayConditionOperator);
-
- ///
- /// Returns all the display condition operators compatible with the provided type
- ///
- List GetCompatibleConditionOperators(Type type);
-
- ///
- /// Gets a condition operator by its plugin GUID and type name
- ///
- /// The operator's plugin GUID
- /// The type name of the operator
- DisplayConditionOperator GetConditionOperator(Guid operatorPluginGuid, string operatorType);
-
- ///
- /// Logs a predicate deserialization failure
- ///
- /// The predicate that failed to deserialize
- /// The JSON exception that occurred
- void LogPredicateDeserializationFailure(DisplayConditionPredicate displayConditionPredicate, JsonException exception);
-
- ///
- /// Logs a list predicate deserialization failure
- ///
- /// The list predicate that failed to deserialize
- /// The JSON exception that occurred
- void LogListPredicateDeserializationFailure(DisplayConditionListPredicate displayConditionListPredicate, JsonException exception);
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Interfaces/IDeviceService.cs b/src/Artemis.Core/Services/Interfaces/IDeviceService.cs
index cb09e83e7..154ad5466 100644
--- a/src/Artemis.Core/Services/Interfaces/IDeviceService.cs
+++ b/src/Artemis.Core/Services/Interfaces/IDeviceService.cs
@@ -1,5 +1,8 @@
namespace Artemis.Core.Services
{
+ ///
+ /// A service that allows you manage an
+ ///
public interface IDeviceService : IArtemisService
{
///
diff --git a/src/Artemis.Core/Services/Interfaces/IRenderElementService.cs b/src/Artemis.Core/Services/Interfaces/IRenderElementService.cs
deleted file mode 100644
index 79319f578..000000000
--- a/src/Artemis.Core/Services/Interfaces/IRenderElementService.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using Artemis.Core.LayerBrushes;
-using Artemis.Core.LayerEffects;
-
-namespace Artemis.Core.Services
-{
- public interface IRenderElementService : IArtemisService
- {
- ///
- /// Creates a new layer
- ///
- ///
- ///
- ///
- ///
- Layer CreateLayer(Profile profile, ProfileElement parent, string name);
-
- ///
- /// Removes the currently active layer brush from the and deletes any settings
- ///
- /// The layer to remove the active brush from
- void RemoveLayerBrush(Layer layer);
-
- ///
- /// Deactivates the currently active layer brush from the but keeps all settings
- ///
- /// The layer to deactivate the active brush on
- void DeactivateLayerBrush(Layer layer);
-
- ///
- /// Instantiates and adds the described by the provided
- ///
- /// to the .
- ///
- /// The layer to instantiate the brush for
- ///
- BaseLayerBrush InstantiateLayerBrush(Layer layer);
-
- ///
- /// Instantiates and adds the described by the provided
- /// to the .
- ///
- /// The layer/folder to instantiate the effect for
- void InstantiateLayerEffects(RenderProfileElement renderProfileElement);
-
- ///
- /// Adds the described by the provided to the
- /// .
- ///
- /// The layer/folder to instantiate the effect for
- ///
- ///
- BaseLayerEffect AddLayerEffect(RenderProfileElement renderProfileElement, LayerEffectDescriptor layerEffectDescriptor);
-
- void RemoveLayerEffect(BaseLayerEffect layerEffect);
-
- void InstantiateDisplayConditions(RenderProfileElement renderElement);
- void InstantiateDataBindings(RenderProfileElement renderElement);
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Interfaces/IRgbService.cs b/src/Artemis.Core/Services/Interfaces/IRgbService.cs
index 5b78f6bfb..e5cd0c213 100644
--- a/src/Artemis.Core/Services/Interfaces/IRgbService.cs
+++ b/src/Artemis.Core/Services/Interfaces/IRgbService.cs
@@ -4,7 +4,10 @@ using RGB.NET.Core;
namespace Artemis.Core.Services
{
- public interface IRgbService : IArtemisService
+ ///
+ /// A service that allows you to manage the and its contents
+ ///
+ public interface IRgbService : IArtemisService, IDisposable
{
///
/// Gets or sets the RGB surface rendering is performed on
@@ -26,7 +29,14 @@ namespace Artemis.Core.Services
///
IReadOnlyCollection LoadedDevices { get; }
+ ///
+ /// Gets the update trigger that drives the render loop
+ ///
TimerUpdateTrigger UpdateTrigger { get; }
+
+ ///
+ /// Gets or sets whether rendering should be paused
+ ///
bool IsRenderPaused { get; set; }
///
@@ -35,8 +45,6 @@ namespace Artemis.Core.Services
///
void AddDeviceProvider(IRGBDeviceProvider deviceProvider);
- void Dispose();
-
///
/// Occurs when a single device has loaded
///
@@ -47,6 +55,9 @@ namespace Artemis.Core.Services
///
event EventHandler DeviceReloaded;
+ ///
+ /// Recalculates the LED group used by the
+ ///
void UpdateSurfaceLedGroup();
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Registration/ConditionOperatorService.cs b/src/Artemis.Core/Services/Registration/ConditionOperatorService.cs
new file mode 100644
index 000000000..9ea6fab80
--- /dev/null
+++ b/src/Artemis.Core/Services/Registration/ConditionOperatorService.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Artemis.Core.Services
+{
+ internal class ConditionOperatorService : IConditionOperatorService
+ {
+ public ConditionOperatorService()
+ {
+ RegisterBuiltInConditionOperators();
+ }
+
+ public ConditionOperatorRegistration RegisterConditionOperator(PluginInfo pluginInfo, ConditionOperator conditionOperator)
+ {
+ if (pluginInfo == null)
+ throw new ArgumentNullException(nameof(pluginInfo));
+ if (conditionOperator == null)
+ throw new ArgumentNullException(nameof(conditionOperator));
+
+ conditionOperator.PluginInfo = pluginInfo;
+ return ConditionOperatorStore.Add(conditionOperator);
+ }
+
+ public void RemoveConditionOperator(ConditionOperatorRegistration registration)
+ {
+ if (registration == null)
+ throw new ArgumentNullException(nameof(registration));
+ ConditionOperatorStore.Remove(registration);
+ }
+
+ public List GetConditionOperatorsForType(Type type)
+ {
+ return ConditionOperatorStore.GetForType(type).Select(r => r.ConditionOperator).ToList();
+ }
+
+ public ConditionOperator GetConditionOperator(Guid operatorPluginGuid, string operatorType)
+ {
+ return ConditionOperatorStore.Get(operatorPluginGuid, operatorType)?.ConditionOperator;
+ }
+
+ private void RegisterBuiltInConditionOperators()
+ {
+ // General usage for any type
+ RegisterConditionOperator(Constants.CorePluginInfo, new EqualsConditionOperator());
+ RegisterConditionOperator(Constants.CorePluginInfo, new NotEqualConditionOperator());
+
+ // Numeric operators
+ RegisterConditionOperator(Constants.CorePluginInfo, new LessThanConditionOperator());
+ RegisterConditionOperator(Constants.CorePluginInfo, new GreaterThanConditionOperator());
+ RegisterConditionOperator(Constants.CorePluginInfo, new LessThanOrEqualConditionOperator());
+ RegisterConditionOperator(Constants.CorePluginInfo, 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 StringNullConditionOperator());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Registration/DataBindingService.cs b/src/Artemis.Core/Services/Registration/DataBindingService.cs
new file mode 100644
index 000000000..8deed0c63
--- /dev/null
+++ b/src/Artemis.Core/Services/Registration/DataBindingService.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Artemis.Core.Services
+{
+ internal class DataBindingService : IDataBindingService
+ {
+ public DataBindingService()
+ {
+ RegisterBuiltInModifiers();
+ }
+
+ public DataBindingModifierTypeRegistration RegisterModifierType(PluginInfo pluginInfo, DataBindingModifierType dataBindingModifierType)
+ {
+ if (pluginInfo == null)
+ throw new ArgumentNullException(nameof(pluginInfo));
+ if (dataBindingModifierType == null)
+ throw new ArgumentNullException(nameof(dataBindingModifierType));
+
+ dataBindingModifierType.PluginInfo = pluginInfo;
+ return DataBindingModifierTypeStore.Add(dataBindingModifierType);
+ }
+
+ public void RemoveModifierType(DataBindingModifierTypeRegistration registration)
+ {
+ if (registration == null)
+ throw new ArgumentNullException(nameof(registration));
+ DataBindingModifierTypeStore.Remove(registration);
+ }
+
+ public List GetCompatibleModifierTypes(Type type)
+ {
+ return DataBindingModifierTypeStore.GetForType(type).Select(r => r.DataBindingModifierType).ToList();
+ }
+
+ public DataBindingModifierType GetModifierType(Guid modifierTypePluginGuid, string modifierType)
+ {
+ return DataBindingModifierTypeStore.Get(modifierTypePluginGuid, modifierType)?.DataBindingModifierType;
+ }
+
+ private void RegisterBuiltInModifiers()
+ {
+ RegisterModifierType(Constants.CorePluginInfo, new MultiplicationModifierType());
+ RegisterModifierType(Constants.CorePluginInfo, new DivideModifierType());
+ RegisterModifierType(Constants.CorePluginInfo, new FloorModifierType());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Registration/DataModelService.cs b/src/Artemis.Core/Services/Registration/DataModelService.cs
new file mode 100644
index 000000000..f3dcfaeb9
--- /dev/null
+++ b/src/Artemis.Core/Services/Registration/DataModelService.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Artemis.Core.DataModelExpansions;
+using Artemis.Core.Modules;
+
+namespace Artemis.Core.Services
+{
+ internal class DataModelService : IDataModelService
+ {
+ public DataModelService(IPluginService pluginService)
+ {
+ // Add data models of already loaded plugins
+ foreach (var module in pluginService.GetPluginsOfType())
+ AddModuleDataModel(module);
+ foreach (var dataModelExpansion in pluginService.GetPluginsOfType())
+ AddDataModelExpansionDataModel(dataModelExpansion);
+
+ // Add data models of new plugins when they get enabled
+ pluginService.PluginEnabled += PluginServiceOnPluginEnabled;
+ }
+
+ public DataModelRegistration RegisterDataModel(DataModel dataModel)
+ {
+ if (dataModel == null)
+ throw new ArgumentNullException(nameof(dataModel));
+ return DataModelStore.Add(dataModel);
+ }
+
+ public void RemoveDataModel(DataModelRegistration registration)
+ {
+ if (registration == null)
+ throw new ArgumentNullException(nameof(registration));
+ DataModelStore.Remove(registration);
+ }
+
+ public List GetDataModels()
+ {
+ return DataModelStore.GetAll().Select(d => d.DataModel).ToList();
+ }
+
+ public T GetDataModel() where T : DataModel
+ {
+ return (T) DataModelStore.GetAll().FirstOrDefault(d => d.DataModel is T)?.DataModel;
+ }
+
+ public DataModel GetPluginDataModel(Plugin plugin)
+ {
+ return DataModelStore.Get(plugin.PluginInfo.Guid)?.DataModel;
+ }
+
+ public DataModel GetPluginDataModel(Guid pluginGuid)
+ {
+ return DataModelStore.Get(pluginGuid)?.DataModel;
+ }
+
+ private void PluginServiceOnPluginEnabled(object sender, PluginEventArgs e)
+ {
+ if (e.PluginInfo.Instance is Module module)
+ AddModuleDataModel(module);
+ else if (e.PluginInfo.Instance is BaseDataModelExpansion dataModelExpansion)
+ AddDataModelExpansionDataModel(dataModelExpansion);
+ }
+
+ private void AddModuleDataModel(Module module)
+ {
+ if (module.InternalDataModel == null)
+ return;
+
+ if (module.InternalDataModel.DataModelDescription == null)
+ throw new ArtemisPluginException(module.PluginInfo, "Module overrides GetDataModelDescription but returned null");
+
+ module.InternalDataModel.IsExpansion = module.InternalExpandsMainDataModel;
+ RegisterDataModel(module.InternalDataModel);
+ }
+
+ private void AddDataModelExpansionDataModel(BaseDataModelExpansion dataModelExpansion)
+ {
+ if (dataModelExpansion.InternalDataModel.DataModelDescription == null)
+ throw new ArtemisPluginException(dataModelExpansion.PluginInfo, "Data model expansion overrides GetDataModelDescription but returned null");
+
+ dataModelExpansion.InternalDataModel.IsExpansion = true;
+ RegisterDataModel(dataModelExpansion.InternalDataModel);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Registration/Interfaces/IConditionOperatorService.cs b/src/Artemis.Core/Services/Registration/Interfaces/IConditionOperatorService.cs
new file mode 100644
index 000000000..f59eb587d
--- /dev/null
+++ b/src/Artemis.Core/Services/Registration/Interfaces/IConditionOperatorService.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using Artemis.Core.Properties;
+
+namespace Artemis.Core.Services
+{
+ ///
+ /// A service that allows you to register and retrieve conditions operators used by display conditions
+ ///
+ public interface IConditionOperatorService : IArtemisService
+ {
+ ///
+ /// Registers a new condition operator for use in layer conditions
+ ///
+ /// The PluginInfo of the plugin this condition operator belongs to
+ /// The condition operator to register
+ ConditionOperatorRegistration RegisterConditionOperator([NotNull] PluginInfo pluginInfo, [NotNull] ConditionOperator conditionOperator);
+
+ ///
+ /// Removes a condition operator so it is no longer available for use in layer conditions
+ ///
+ /// The registration of the condition operator to remove
+ void RemoveConditionOperator([NotNull] ConditionOperatorRegistration registration);
+
+ ///
+ /// Returns all the condition operators compatible with the provided type
+ ///
+ List GetConditionOperatorsForType(Type type);
+
+ ///
+ /// Gets a condition operator by its plugin GUID and type name
+ ///
+ /// The operator's plugin GUID
+ /// The type name of the operator
+ ConditionOperator GetConditionOperator(Guid operatorPluginGuid, string operatorType);
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Interfaces/IDataBindingService.cs b/src/Artemis.Core/Services/Registration/Interfaces/IDataBindingService.cs
similarity index 60%
rename from src/Artemis.Core/Services/Interfaces/IDataBindingService.cs
rename to src/Artemis.Core/Services/Registration/Interfaces/IDataBindingService.cs
index 1ed4bbeb2..b40248b37 100644
--- a/src/Artemis.Core/Services/Interfaces/IDataBindingService.cs
+++ b/src/Artemis.Core/Services/Registration/Interfaces/IDataBindingService.cs
@@ -1,29 +1,26 @@
using System;
using System.Collections.Generic;
using Artemis.Core.Properties;
-using Newtonsoft.Json;
namespace Artemis.Core.Services
{
+ ///
+ /// A service that allows you to register and retrieve data binding modifiers used by the data bindings system
+ ///
public interface IDataBindingService : IArtemisService
{
- ///
- /// Gets a read-only collection of all registered modifier types
- ///
- IReadOnlyCollection RegisteredDataBindingModifierTypes { get; }
-
///
/// Registers a new modifier type for use in data bindings
///
/// The PluginInfo of the plugin this modifier type belongs to
/// The modifier type to register
- void RegisterModifierType([NotNull] PluginInfo pluginInfo, [NotNull] DataBindingModifierType dataBindingModifierType);
+ DataBindingModifierTypeRegistration RegisterModifierType([NotNull] PluginInfo pluginInfo, [NotNull] DataBindingModifierType dataBindingModifierType);
///
/// Removes a modifier type so it is no longer available for use in data bindings
///
- /// The modifier type to remove
- void RemoveModifierType([NotNull] DataBindingModifierType dataBindingModifierType);
+ /// The registration of the modifier type to remove
+ void RemoveModifierType([NotNull] DataBindingModifierTypeRegistration dataBindingModifierType);
///
/// Returns all the data binding modifier types compatible with the provided type
@@ -37,12 +34,5 @@ namespace Artemis.Core.Services
/// The type name of the modifier type
///
DataBindingModifierType GetModifierType(Guid modifierTypePluginGuid, string modifierType);
-
- ///
- /// Logs a modifier deserialization failure
- ///
- /// The modifier that failed to deserialize
- /// The JSON exception that occurred
- void LogModifierDeserializationFailure(string modifierName, JsonSerializationException exception);
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Registration/Interfaces/IDataModelService.cs b/src/Artemis.Core/Services/Registration/Interfaces/IDataModelService.cs
new file mode 100644
index 000000000..c9ab8a279
--- /dev/null
+++ b/src/Artemis.Core/Services/Registration/Interfaces/IDataModelService.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using Artemis.Core.DataModelExpansions;
+
+namespace Artemis.Core.Services
+{
+ ///
+ /// A service that allows you to register and retrieve data models
+ ///
+ public interface IDataModelService : IArtemisService
+ {
+ ///
+ /// Add a data model to so that it is available to conditions and data bindings
+ ///
+ ///
+ DataModelRegistration RegisterDataModel(DataModel dataModel);
+
+ ///
+ /// Remove a previously added data model so that it is no longer available
+ ///
+ void RemoveDataModel(DataModelRegistration registration);
+
+ ///
+ /// Returns a list of all registered data models
+ ///
+ List GetDataModels();
+
+ ///
+ /// If found, returns the registered data model of type
+ ///
+ /// The type of the data model to find
+ T GetDataModel() where T : DataModel;
+
+ ///
+ /// If found, returns the data model of the provided plugin
+ ///
+ /// The plugin to find the data model of
+ DataModel GetPluginDataModel(Plugin plugin);
+
+ ///
+ /// 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);
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Registration/Interfaces/ILayerBrushService.cs b/src/Artemis.Core/Services/Registration/Interfaces/ILayerBrushService.cs
new file mode 100644
index 000000000..8bc6a62e0
--- /dev/null
+++ b/src/Artemis.Core/Services/Registration/Interfaces/ILayerBrushService.cs
@@ -0,0 +1,26 @@
+using System.Collections.Generic;
+using Artemis.Core.LayerBrushes;
+
+namespace Artemis.Core.Services
+{
+ ///
+ /// A service that allows you to register and retrieve layer brushes
+ ///
+ public interface ILayerBrushService : IArtemisService
+ {
+ ///
+ /// Add a layer brush descriptor so that it is available to layers
+ ///
+ LayerBrushRegistration RegisterLayerBrush(LayerBrushDescriptor descriptor);
+
+ ///
+ /// Remove a previously added layer brush descriptor so that it is no longer available
+ ///
+ void RemoveLayerBrush(LayerBrushRegistration registration);
+
+ ///
+ /// Returns a list of all registered layer brush descriptors
+ ///
+ List GetLayerBrushes();
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Registration/Interfaces/ILayerEffectService.cs b/src/Artemis.Core/Services/Registration/Interfaces/ILayerEffectService.cs
new file mode 100644
index 000000000..1bb093200
--- /dev/null
+++ b/src/Artemis.Core/Services/Registration/Interfaces/ILayerEffectService.cs
@@ -0,0 +1,27 @@
+using System.Collections.Generic;
+using Artemis.Core.LayerBrushes;
+using Artemis.Core.LayerEffects;
+
+namespace Artemis.Core.Services
+{
+ ///
+ /// A service that allows you to register and retrieve layer brushes
+ ///
+ public interface ILayerEffectService : IArtemisService
+ {
+ ///
+ /// Add an effect descriptor so that it is available to profile elements
+ ///
+ LayerEffectRegistration RegisterLayerEffect(LayerEffectDescriptor descriptor);
+
+ ///
+ /// Remove a previously added layer effect descriptor so that it is no longer available
+ ///
+ void RemoveLayerEffect(LayerEffectRegistration registration);
+
+ ///
+ /// Returns a list of all registered layer effect descriptors
+ ///
+ List GetLayerEffects();
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/Registration/LayerBrushService.cs b/src/Artemis.Core/Services/Registration/LayerBrushService.cs
new file mode 100644
index 000000000..582a988ff
--- /dev/null
+++ b/src/Artemis.Core/Services/Registration/LayerBrushService.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Artemis.Core.LayerBrushes;
+using Ninject;
+
+namespace Artemis.Core.Services
+{
+ internal class LayerBrushService : ILayerBrushService
+ {
+ private readonly IKernel _kernel;
+
+ public LayerBrushService(IKernel kernel)
+ {
+ _kernel = kernel;
+ }
+ public LayerBrushRegistration RegisterLayerBrush(LayerBrushDescriptor descriptor)
+ {
+ if (descriptor == null)
+ throw new ArgumentNullException(nameof(descriptor));
+
+ descriptor.Kernel = _kernel;
+ return LayerBrushStore.Add(descriptor);
+ }
+
+ public void RemoveLayerBrush(LayerBrushRegistration registration)
+ {
+ if (registration == null)
+ throw new ArgumentNullException(nameof(registration));
+ LayerBrushStore.Remove(registration);
+ }
+
+ public List GetLayerBrushes()
+ {
+ return LayerBrushStore.GetAll().Select(r => r.LayerBrushDescriptor).ToList();
+ }
+ }
+}
diff --git a/src/Artemis.Core/Services/Registration/LayerEffectService.cs b/src/Artemis.Core/Services/Registration/LayerEffectService.cs
new file mode 100644
index 000000000..160c712df
--- /dev/null
+++ b/src/Artemis.Core/Services/Registration/LayerEffectService.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Artemis.Core.LayerEffects;
+using Ninject;
+
+namespace Artemis.Core.Services
+{
+ internal class LayerEffectService : ILayerEffectService
+ {
+ private readonly IKernel _kernel;
+
+ public LayerEffectService(IKernel kernel)
+ {
+ _kernel = kernel;
+ }
+
+ public LayerEffectRegistration RegisterLayerEffect(LayerEffectDescriptor descriptor)
+ {
+ if (descriptor == null)
+ throw new ArgumentNullException(nameof(descriptor));
+
+ descriptor.Kernel = _kernel;
+ return LayerEffectStore.Add(descriptor);
+ }
+
+ public void RemoveLayerEffect(LayerEffectRegistration registration)
+ {
+ if (registration == null)
+ throw new ArgumentNullException(nameof(registration));
+ LayerEffectStore.Remove(registration);
+ }
+
+ public List GetLayerEffects()
+ {
+ return LayerEffectStore.GetAll().Select(r => r.LayerEffectDescriptor).ToList();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/RenderElementService.cs b/src/Artemis.Core/Services/RenderElementService.cs
deleted file mode 100644
index fed3caf7a..000000000
--- a/src/Artemis.Core/Services/RenderElementService.cs
+++ /dev/null
@@ -1,168 +0,0 @@
-using System;
-using System.Linq;
-using Artemis.Core.LayerBrushes;
-using Artemis.Core.LayerEffects;
-using Ninject;
-using Serilog;
-
-namespace Artemis.Core.Services
-{
- internal class RenderElementService : IRenderElementService
- {
- private readonly IDataModelService _dataModelService;
- private readonly IDataBindingService _dataBindingService;
- private readonly IKernel _kernel;
- private readonly ILogger _logger;
- private readonly IPluginService _pluginService;
-
- public RenderElementService(IKernel kernel, ILogger logger, IPluginService pluginService, IDataModelService dataModelService, IDataBindingService dataBindingService)
- {
- _kernel = kernel;
- _logger = logger;
- _pluginService = pluginService;
- _dataModelService = dataModelService;
- _dataBindingService = dataBindingService;
- }
-
- public Layer CreateLayer(Profile profile, ProfileElement parent, string name)
- {
- var layer = new Layer(profile, parent, name);
- parent.AddChild(layer);
-
- // Layers have two hardcoded property groups, instantiate them
- layer.General.Initialize(layer, "General.", Constants.CorePluginInfo);
- layer.Transform.Initialize(layer, "Transform.", Constants.CorePluginInfo);
-
- // With the properties loaded, the layer brush and effect can be instantiated
- InstantiateLayerBrush(layer);
- InstantiateLayerEffects(layer);
- InstantiateDisplayConditions(layer);
- InstantiateDataBindings(layer);
- return layer;
- }
-
- public void RemoveLayerBrush(Layer layer)
- {
- layer.RemoveLayerBrush();
- layer.OnLayerBrushUpdated();
- }
-
- public void DeactivateLayerBrush(Layer layer)
- {
- layer.DeactivateLayerBrush();
- layer.OnLayerBrushUpdated();
- }
-
- public BaseLayerBrush InstantiateLayerBrush(Layer layer)
- {
- if (layer.LayerBrush != null)
- throw new ArtemisCoreException("Layer already has an instantiated layer brush");
-
- var descriptorReference = layer.General.BrushReference?.CurrentValue;
- if (descriptorReference == null)
- return null;
-
- // Get a matching descriptor
- var layerBrushProviders = _pluginService.GetPluginsOfType();
- var descriptors = layerBrushProviders.SelectMany(l => l.LayerBrushDescriptors).ToList();
- var descriptor = descriptors.FirstOrDefault(d => d.LayerBrushProvider.PluginInfo.Guid == descriptorReference.BrushPluginGuid &&
- d.LayerBrushType.Name == descriptorReference.BrushType);
-
- if (descriptor == null)
- return null;
-
- var brush = (BaseLayerBrush) _kernel.Get(descriptor.LayerBrushType);
- brush.Layer = layer;
- brush.Descriptor = descriptor;
- brush.Initialize();
- brush.Update(0);
-
- layer.LayerBrush = brush;
- layer.OnLayerBrushUpdated();
-
- return brush;
- }
-
- public BaseLayerEffect AddLayerEffect(RenderProfileElement renderElement, LayerEffectDescriptor layerEffectDescriptor)
- {
- // Create the effect with dependency injection
- var effect = (BaseLayerEffect) _kernel.Get(layerEffectDescriptor.LayerEffectType);
-
- effect.ProfileElement = renderElement;
- effect.EntityId = Guid.NewGuid();
- effect.Enabled = true;
- effect.Order = renderElement.LayerEffects.Count + 1;
- effect.Descriptor = layerEffectDescriptor;
-
- effect.Initialize();
- effect.Update(0);
-
- renderElement.AddLayerEffect(effect);
- _logger.Debug("Added layer effect with root path {rootPath}", effect.PropertyRootPath);
- return effect;
- }
-
- public void RemoveLayerEffect(BaseLayerEffect layerEffect)
- {
- layerEffect.ProfileElement.RemoveLayerEffect(layerEffect);
- }
-
- public void InstantiateLayerEffects(RenderProfileElement renderElement)
- {
- var layerEffectProviders = _pluginService.GetPluginsOfType();
- var descriptors = layerEffectProviders.SelectMany(l => l.LayerEffectDescriptors).ToList();
- var entities = renderElement.RenderElementEntity.LayerEffects.OrderByDescending(e => e.Order).ToList();
-
- foreach (var layerEffectEntity in entities)
- {
- // Skip effects already on the element
- if (renderElement.LayerEffects.Any(e => e.EntityId == layerEffectEntity.Id))
- continue;
-
- // Get a matching descriptor
- var descriptor = descriptors.FirstOrDefault(d => d.LayerEffectProvider.PluginInfo.Guid == layerEffectEntity.PluginGuid &&
- d.LayerEffectType.Name == layerEffectEntity.EffectType);
- if (descriptor == null)
- continue;
-
- // Create the effect with dependency injection
- var effect = (BaseLayerEffect) _kernel.Get(descriptor.LayerEffectType);
-
- effect.ProfileElement = renderElement;
- effect.EntityId = layerEffectEntity.Id;
- effect.Order = layerEffectEntity.Order;
- effect.Name = layerEffectEntity.Name;
- effect.Enabled = layerEffectEntity.Enabled;
- effect.Descriptor = descriptor;
-
- effect.Initialize();
- effect.Update(0);
-
- renderElement.AddLayerEffect(effect);
- _logger.Debug("Instantiated layer effect with root path {rootPath}", effect.PropertyRootPath);
- }
- }
-
- public void InstantiateDisplayConditions(RenderProfileElement renderElement)
- {
- var displayCondition = renderElement.RenderElementEntity.RootDisplayCondition != null
- ? new DisplayConditionGroup(null, renderElement.RenderElementEntity.RootDisplayCondition)
- : new DisplayConditionGroup(null);
-
- try
- {
- displayCondition.Initialize(_dataModelService);
- renderElement.DisplayConditionGroup = displayCondition;
- }
- catch (Exception e)
- {
- _logger.Warning(e, $"Failed to init display conditions for {renderElement}");
- }
- }
-
- public void InstantiateDataBindings(RenderProfileElement renderElement)
- {
- renderElement.InitializeDataBindings(_dataBindingService, _dataModelService);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Artemis.Core/Services/RgbService.cs b/src/Artemis.Core/Services/RgbService.cs
index df10d1a78..c80e36736 100644
--- a/src/Artemis.Core/Services/RgbService.cs
+++ b/src/Artemis.Core/Services/RgbService.cs
@@ -10,7 +10,7 @@ namespace Artemis.Core.Services
///
/// Provides wrapped access the RGB.NET
///
- internal class RgbService : IRgbService, IDisposable
+ internal class RgbService : IRgbService
{
private readonly List _loadedDevices;
private readonly ILogger _logger;
diff --git a/src/Artemis.Core/Services/Storage/ProfileService.cs b/src/Artemis.Core/Services/Storage/ProfileService.cs
index 6b50447c4..49c575d8e 100644
--- a/src/Artemis.Core/Services/Storage/ProfileService.cs
+++ b/src/Artemis.Core/Services/Storage/ProfileService.cs
@@ -158,13 +158,13 @@ namespace Artemis.Core.Services
profile.RedoStack.Clear();
profile.UndoStack.Push(memento);
- profile.ApplyToEntity();
+ profile.Save();
if (includeChildren)
{
foreach (var folder in profile.GetAllFolders())
- folder.ApplyToEntity();
+ folder.Save();
foreach (var layer in profile.GetAllLayers())
- layer.ApplyToEntity();
+ layer.Save();
}
_profileRepository.Save(profile.ProfileEntity);
diff --git a/src/Artemis.Core/Stores/ConditionOperatorStore.cs b/src/Artemis.Core/Stores/ConditionOperatorStore.cs
new file mode 100644
index 000000000..194188084
--- /dev/null
+++ b/src/Artemis.Core/Stores/ConditionOperatorStore.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Artemis.Core
+{
+ internal class ConditionOperatorStore
+ {
+ private static readonly List Registrations = new List();
+
+ public static ConditionOperatorRegistration Add(ConditionOperator conditionOperator)
+ {
+ ConditionOperatorRegistration registration;
+ lock (Registrations)
+ {
+ 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.Instance) {IsInStore = true};
+ Registrations.Add(registration);
+ }
+
+ OnConditionOperatorAdded(new ConditionOperatorStoreEvent(registration));
+ return registration;
+ }
+
+ public static void Remove(ConditionOperatorRegistration registration)
+ {
+ lock (Registrations)
+ {
+ if (!Registrations.Contains(registration))
+ throw new ArtemisCoreException($"Condition operator store does not contain operator '{registration.ConditionOperator.Description}'");
+
+ Registrations.Remove(registration);
+ registration.IsInStore = false;
+ }
+
+ OnConditionOperatorRemoved(new ConditionOperatorStoreEvent(registration));
+ }
+
+ public static ConditionOperatorRegistration Get(Guid pluginGuid, string type)
+ {
+ lock (Registrations)
+ {
+ return Registrations.FirstOrDefault(r => r.Plugin.PluginInfo.Guid == pluginGuid && r.ConditionOperator.GetType().Name == type);
+ }
+ }
+
+ public static List GetForType(Type type)
+ {
+ lock (Registrations)
+ {
+ if (type == null)
+ return new List(Registrations);
+
+ var candidates = Registrations.Where(r => r.ConditionOperator.CompatibleTypes.Any(t => t.IsCastableFrom(type))).ToList();
+
+ // If there are multiple operators with the same description, use the closest match
+ foreach (var displayConditionOperators in candidates.GroupBy(r => r.ConditionOperator.Description).Where(g => g.Count() > 1).ToList())
+ {
+ var closest = displayConditionOperators.OrderByDescending(r => r.ConditionOperator.CompatibleTypes.Contains(type)).FirstOrDefault();
+ foreach (var displayConditionOperator in displayConditionOperators)
+ {
+ if (displayConditionOperator != closest)
+ candidates.Remove(displayConditionOperator);
+ }
+ }
+
+ return candidates;
+ }
+ }
+
+ #region Events
+
+ public static event EventHandler ConditionOperatorAdded;
+ public static event EventHandler ConditionOperatorRemoved;
+
+ private static void OnConditionOperatorAdded(ConditionOperatorStoreEvent e)
+ {
+ ConditionOperatorAdded?.Invoke(null, e);
+ }
+
+ private static void OnConditionOperatorRemoved(ConditionOperatorStoreEvent e)
+ {
+ ConditionOperatorRemoved?.Invoke(null, e);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Stores/DataBindingModifierTypeStore.cs b/src/Artemis.Core/Stores/DataBindingModifierTypeStore.cs
new file mode 100644
index 000000000..b398ed925
--- /dev/null
+++ b/src/Artemis.Core/Stores/DataBindingModifierTypeStore.cs
@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Artemis.Core
+{
+ internal class DataBindingModifierTypeStore
+ {
+ private static readonly List Registrations = new List();
+
+ public static DataBindingModifierTypeRegistration Add(DataBindingModifierType modifierType)
+ {
+ DataBindingModifierTypeRegistration typeRegistration;
+ lock (Registrations)
+ {
+ if (Registrations.Any(r => r.DataBindingModifierType == modifierType))
+ throw new ArtemisCoreException($"Data binding modifier type store already contains modifier '{modifierType.Description}'");
+
+ typeRegistration = new DataBindingModifierTypeRegistration(modifierType, modifierType.PluginInfo.Instance) { IsInStore = true };
+ Registrations.Add(typeRegistration);
+ }
+
+ OnDataBindingModifierAdded(new DataBindingModifierTypeStoreEvent(typeRegistration));
+ return typeRegistration;
+ }
+
+ public static void Remove(DataBindingModifierTypeRegistration typeRegistration)
+ {
+ lock (Registrations)
+ {
+ if (!Registrations.Contains(typeRegistration))
+ throw new ArtemisCoreException($"Data binding modifier type store does not contain modifier type '{typeRegistration.DataBindingModifierType.Description}'");
+
+ Registrations.Remove(typeRegistration);
+ typeRegistration.IsInStore = false;
+ }
+
+ OnDataBindingModifierRemoved(new DataBindingModifierTypeStoreEvent(typeRegistration));
+ }
+
+ public static DataBindingModifierTypeRegistration Get(Guid pluginGuid, string type)
+ {
+ lock (Registrations)
+ {
+ return Registrations.FirstOrDefault(r => r.Plugin.PluginInfo.Guid == pluginGuid && r.DataBindingModifierType.GetType().Name == type);
+ }
+ }
+
+ public static List GetForType(Type type)
+ {
+ lock (Registrations)
+ {
+ if (type == null)
+ return new List(Registrations);
+
+ var candidates = Registrations.Where(r => r.DataBindingModifierType.CompatibleTypes.Any(t => t.IsCastableFrom(type))).ToList();
+
+ // If there are multiple operators with the same description, use the closest match
+ foreach (var displayDataBindingModifiers in candidates.GroupBy(r => r.DataBindingModifierType.Description).Where(g => g.Count() > 1).ToList())
+ {
+ var closest = displayDataBindingModifiers.OrderByDescending(r => r.DataBindingModifierType.CompatibleTypes.Contains(type)).FirstOrDefault();
+ foreach (var displayDataBindingModifier in displayDataBindingModifiers)
+ {
+ if (displayDataBindingModifier != closest)
+ candidates.Remove(displayDataBindingModifier);
+ }
+ }
+
+ return candidates;
+ }
+ }
+
+ #region Events
+
+ public static event EventHandler DataBindingModifierAdded;
+ public static event EventHandler DataBindingModifierRemoved;
+
+ private static void OnDataBindingModifierAdded(DataBindingModifierTypeStoreEvent e)
+ {
+ DataBindingModifierAdded?.Invoke(null, e);
+ }
+
+ private static void OnDataBindingModifierRemoved(DataBindingModifierTypeStoreEvent e)
+ {
+ DataBindingModifierRemoved?.Invoke(null, e);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Stores/DataModelStore.cs b/src/Artemis.Core/Stores/DataModelStore.cs
new file mode 100644
index 000000000..2617e91f7
--- /dev/null
+++ b/src/Artemis.Core/Stores/DataModelStore.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Artemis.Core.DataModelExpansions;
+
+namespace Artemis.Core
+{
+ internal class DataModelStore
+ {
+ private static readonly List Registrations = new List();
+
+ public static DataModelRegistration Add(DataModel dataModel)
+ {
+ DataModelRegistration registration;
+ lock (Registrations)
+ {
+ if (Registrations.Any(r => r.DataModel == dataModel))
+ throw new ArtemisCoreException($"Data model store already contains data model '{dataModel.DataModelDescription}'");
+
+ registration = new DataModelRegistration(dataModel, dataModel.PluginInfo.Instance) {IsInStore = true};
+ Registrations.Add(registration);
+ }
+
+ OnDataModelAdded(new DataModelStoreEvent(registration));
+ return registration;
+ }
+
+ public static void Remove(DataModelRegistration registration)
+ {
+ lock (Registrations)
+ {
+ if (!Registrations.Contains(registration))
+ throw new ArtemisCoreException($"Data model store does not contain data model '{registration.DataModel.DataModelDescription}'");
+
+ Registrations.Remove(registration);
+ registration.IsInStore = false;
+ }
+
+ OnDataModelRemoved(new DataModelStoreEvent(registration));
+ }
+
+ public static List GetAll()
+ {
+ lock (Registrations)
+ {
+ return new List(Registrations);
+ }
+ }
+
+ public static DataModelRegistration Get(Guid pluginGuid)
+ {
+ lock (Registrations)
+ {
+ return Registrations.FirstOrDefault(d => d.Plugin.PluginInfo.Guid == pluginGuid);
+ }
+ }
+
+ #region Events
+
+ public static event EventHandler DataModelAdded;
+ public static event EventHandler DataModelRemoved;
+
+ private static void OnDataModelAdded(DataModelStoreEvent e)
+ {
+ DataModelAdded?.Invoke(null, e);
+ }
+
+ private static void OnDataModelRemoved(DataModelStoreEvent e)
+ {
+ DataModelRemoved?.Invoke(null, e);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Stores/LayerBrushStore.cs b/src/Artemis.Core/Stores/LayerBrushStore.cs
new file mode 100644
index 000000000..75af208b0
--- /dev/null
+++ b/src/Artemis.Core/Stores/LayerBrushStore.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Artemis.Core.LayerBrushes;
+
+namespace Artemis.Core
+{
+ internal class LayerBrushStore
+ {
+ private static readonly List Registrations = new List();
+
+ public static LayerBrushRegistration Add(LayerBrushDescriptor descriptor)
+ {
+ LayerBrushRegistration registration;
+ lock (Registrations)
+ {
+ if (Registrations.Any(r => r.LayerBrushDescriptor == descriptor))
+ throw new ArtemisCoreException($"Store already contains layer brush '{descriptor.DisplayName}'");
+
+ registration = new LayerBrushRegistration(descriptor, descriptor.LayerBrushProvider.PluginInfo.Instance) {IsInStore = true};
+ Registrations.Add(registration);
+ }
+
+ OnLayerBrushAdded(new LayerBrushStoreEvent(registration));
+ return registration;
+ }
+
+ public static void Remove(LayerBrushRegistration registration)
+ {
+ lock (Registrations)
+ {
+ if (!Registrations.Contains(registration))
+ throw new ArtemisCoreException($"Store does not contain layer brush '{registration.LayerBrushDescriptor.DisplayName}'");
+
+ Registrations.Remove(registration);
+ registration.IsInStore = false;
+ }
+
+ OnLayerBrushRemoved(new LayerBrushStoreEvent(registration));
+ }
+
+ public static List GetAll()
+ {
+ lock (Registrations)
+ {
+ return new List(Registrations);
+ }
+ }
+
+ public static LayerBrushRegistration Get(Guid pluginGuid, string typeName)
+ {
+ lock (Registrations)
+ {
+ return Registrations.FirstOrDefault(d => d.Plugin.PluginInfo.Guid == pluginGuid && d.LayerBrushDescriptor.LayerBrushType.Name == typeName);
+ }
+ }
+
+ #region Events
+
+ public static event EventHandler LayerBrushAdded;
+ public static event EventHandler LayerBrushRemoved;
+
+ private static void OnLayerBrushAdded(LayerBrushStoreEvent e)
+ {
+ LayerBrushAdded?.Invoke(null, e);
+ }
+
+ private static void OnLayerBrushRemoved(LayerBrushStoreEvent e)
+ {
+ LayerBrushRemoved?.Invoke(null, e);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Stores/LayerEffectStore.cs b/src/Artemis.Core/Stores/LayerEffectStore.cs
new file mode 100644
index 000000000..7e78e22bc
--- /dev/null
+++ b/src/Artemis.Core/Stores/LayerEffectStore.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Artemis.Core.LayerEffects;
+
+namespace Artemis.Core
+{
+ internal class LayerEffectStore
+ {
+ private static readonly List Registrations = new List();
+
+ public static LayerEffectRegistration Add(LayerEffectDescriptor descriptor)
+ {
+ LayerEffectRegistration registration;
+ lock (Registrations)
+ {
+ if (Registrations.Any(r => r.LayerEffectDescriptor == descriptor))
+ throw new ArtemisCoreException($"Store already contains layer brush '{descriptor.DisplayName}'");
+
+ registration = new LayerEffectRegistration(descriptor, descriptor.LayerEffectProvider.PluginInfo.Instance) { IsInStore = true };
+ Registrations.Add(registration);
+ }
+
+ OnLayerEffectAdded(new LayerEffectStoreEvent(registration));
+ return registration;
+ }
+
+ public static void Remove(LayerEffectRegistration registration)
+ {
+ lock (Registrations)
+ {
+ if (!Registrations.Contains(registration))
+ throw new ArtemisCoreException($"Store does not contain layer brush '{registration.LayerEffectDescriptor.DisplayName}'");
+
+ Registrations.Remove(registration);
+ registration.IsInStore = false;
+ }
+
+ OnLayerEffectRemoved(new LayerEffectStoreEvent(registration));
+ }
+
+ public static List GetAll()
+ {
+ lock (Registrations)
+ {
+ return new List(Registrations);
+ }
+ }
+
+ public static LayerEffectRegistration Get(Guid pluginGuid, string typeName)
+ {
+ lock (Registrations)
+ {
+ return Registrations.FirstOrDefault(d => d.Plugin.PluginInfo.Guid == pluginGuid && d.LayerEffectDescriptor.LayerEffectType.Name == typeName);
+ }
+ }
+
+ #region Events
+
+ public static event EventHandler LayerEffectAdded;
+ public static event EventHandler LayerEffectRemoved;
+
+ private static void OnLayerEffectAdded(LayerEffectStoreEvent e)
+ {
+ LayerEffectAdded?.Invoke(null, e);
+ }
+
+ private static void OnLayerEffectRemoved(LayerEffectStoreEvent e)
+ {
+ LayerEffectRemoved?.Invoke(null, e);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Stores/Registrations/ConditionOperatorRegistration.cs b/src/Artemis.Core/Stores/Registrations/ConditionOperatorRegistration.cs
new file mode 100644
index 000000000..babd6da7e
--- /dev/null
+++ b/src/Artemis.Core/Stores/Registrations/ConditionOperatorRegistration.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Artemis.Core
+{
+ ///
+ /// Represents a data model registration
+ ///
+ public class ConditionOperatorRegistration
+ {
+ internal ConditionOperatorRegistration(ConditionOperator conditionOperator, Plugin plugin)
+ {
+ ConditionOperator = conditionOperator;
+ Plugin = plugin;
+
+ Plugin.PluginDisabled += PluginOnPluginDisabled;
+ }
+
+ ///
+ /// Gets the condition operator that has been registered
+ ///
+ public ConditionOperator ConditionOperator { get; }
+
+ ///
+ /// Gets the plugin the condition operator is associated with
+ ///
+ public Plugin Plugin { get; }
+
+ ///
+ /// Gets a boolean indicating whether the registration is in the internal Core store
+ ///
+ public bool IsInStore { get; internal set; }
+
+ private void PluginOnPluginDisabled(object sender, EventArgs e)
+ {
+ Plugin.PluginDisabled -= PluginOnPluginDisabled;
+ if (IsInStore)
+ ConditionOperatorStore.Remove(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Stores/Registrations/DataBindingModifierTypeRegistration.cs b/src/Artemis.Core/Stores/Registrations/DataBindingModifierTypeRegistration.cs
new file mode 100644
index 000000000..d00e19444
--- /dev/null
+++ b/src/Artemis.Core/Stores/Registrations/DataBindingModifierTypeRegistration.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace Artemis.Core
+{
+ ///
+ /// Represents a data model registration
+ ///
+ public class DataBindingModifierTypeRegistration
+ {
+ internal DataBindingModifierTypeRegistration(DataBindingModifierType dataBindingModifierType, Plugin plugin)
+ {
+ DataBindingModifierType = dataBindingModifierType;
+ Plugin = plugin;
+
+ Plugin.PluginDisabled += PluginOnPluginDisabled;
+ }
+
+ ///
+ /// Gets the data binding modifier that has been registered
+ ///
+ public DataBindingModifierType DataBindingModifierType { get; }
+
+ ///
+ /// Gets the plugin the data binding modifier is associated with
+ ///
+ public Plugin Plugin { get; }
+
+ ///
+ /// Gets a boolean indicating whether the registration is in the internal Core store
+ ///
+ public bool IsInStore { get; internal set; }
+
+ private void PluginOnPluginDisabled(object sender, EventArgs e)
+ {
+ Plugin.PluginDisabled -= PluginOnPluginDisabled;
+ if (IsInStore)
+ DataBindingModifierTypeStore.Remove(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Stores/Registrations/DataModelRegistration.cs b/src/Artemis.Core/Stores/Registrations/DataModelRegistration.cs
new file mode 100644
index 000000000..336a64c96
--- /dev/null
+++ b/src/Artemis.Core/Stores/Registrations/DataModelRegistration.cs
@@ -0,0 +1,41 @@
+using System;
+using Artemis.Core.DataModelExpansions;
+
+namespace Artemis.Core
+{
+ ///
+ /// Represents a data model registration
+ ///
+ public class DataModelRegistration
+ {
+ internal DataModelRegistration(DataModel dataModel, Plugin plugin)
+ {
+ DataModel = dataModel;
+ Plugin = plugin;
+
+ Plugin.PluginDisabled += PluginOnPluginDisabled;
+ }
+
+ ///
+ /// Gets the data model that has been registered
+ ///
+ public DataModel DataModel { get; }
+
+ ///
+ /// Gets the plugin the data model is associated with
+ ///
+ public Plugin Plugin { get; }
+
+ ///
+ /// Gets a boolean indicating whether the registration is in the internal Core store
+ ///
+ public bool IsInStore { get; internal set; }
+
+ private void PluginOnPluginDisabled(object sender, EventArgs e)
+ {
+ Plugin.PluginDisabled -= PluginOnPluginDisabled;
+ if (IsInStore)
+ DataModelStore.Remove(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Stores/Registrations/LayerBrushRegistration.cs b/src/Artemis.Core/Stores/Registrations/LayerBrushRegistration.cs
new file mode 100644
index 000000000..eeda91812
--- /dev/null
+++ b/src/Artemis.Core/Stores/Registrations/LayerBrushRegistration.cs
@@ -0,0 +1,41 @@
+using System;
+using Artemis.Core.LayerBrushes;
+
+namespace Artemis.Core
+{
+ ///
+ /// Represents a layer brush registration
+ ///
+ public class LayerBrushRegistration
+ {
+ internal LayerBrushRegistration(LayerBrushDescriptor descriptor, Plugin plugin)
+ {
+ LayerBrushDescriptor = descriptor;
+ Plugin = plugin;
+
+ Plugin.PluginDisabled += PluginOnPluginDisabled;
+ }
+
+ ///
+ /// Gets the layer brush descriptor that has been registered
+ ///
+ public LayerBrushDescriptor LayerBrushDescriptor { get; }
+
+ ///
+ /// Gets the plugin the layer brush is associated with
+ ///
+ public Plugin Plugin { get; }
+
+ ///
+ /// Gets a boolean indicating whether the registration is in the internal Core store
+ ///
+ public bool IsInStore { get; internal set; }
+
+ private void PluginOnPluginDisabled(object sender, EventArgs e)
+ {
+ Plugin.PluginDisabled -= PluginOnPluginDisabled;
+ if (IsInStore)
+ LayerBrushStore.Remove(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Stores/Registrations/LayerEffectRegistration.cs b/src/Artemis.Core/Stores/Registrations/LayerEffectRegistration.cs
new file mode 100644
index 000000000..992acf616
--- /dev/null
+++ b/src/Artemis.Core/Stores/Registrations/LayerEffectRegistration.cs
@@ -0,0 +1,41 @@
+using System;
+using Artemis.Core.LayerEffects;
+
+namespace Artemis.Core
+{
+ ///
+ /// Represents a layer effect registration
+ ///
+ public class LayerEffectRegistration
+ {
+ internal LayerEffectRegistration(LayerEffectDescriptor descriptor, Plugin plugin)
+ {
+ LayerEffectDescriptor = descriptor;
+ Plugin = plugin;
+
+ Plugin.PluginDisabled += PluginOnPluginDisabled;
+ }
+
+ ///
+ /// Gets the layer effect descriptor that has been registered
+ ///
+ public LayerEffectDescriptor LayerEffectDescriptor { get; }
+
+ ///
+ /// Gets the plugin the layer effect is associated with
+ ///
+ public Plugin Plugin { get; }
+
+ ///
+ /// Gets a boolean indicating whether the registration is in the internal Core store
+ ///
+ public bool IsInStore { get; internal set; }
+
+ private void PluginOnPluginDisabled(object sender, EventArgs e)
+ {
+ Plugin.PluginDisabled -= PluginOnPluginDisabled;
+ if (IsInStore)
+ LayerEffectStore.Remove(this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Utilities/DeserializationLogger.cs b/src/Artemis.Core/Utilities/DeserializationLogger.cs
new file mode 100644
index 000000000..1be7ad7fb
--- /dev/null
+++ b/src/Artemis.Core/Utilities/DeserializationLogger.cs
@@ -0,0 +1,44 @@
+using Newtonsoft.Json;
+using Ninject;
+using Serilog;
+
+namespace Artemis.Core
+{
+ internal static class DeserializationLogger
+ {
+ private static ILogger _logger;
+
+ public static void Initialize(IKernel kernel)
+ {
+ _logger = kernel.Get();
+ }
+
+ public static void LogPredicateDeserializationFailure(DisplayConditionPredicate displayConditionPredicate, JsonException exception)
+ {
+ _logger.Warning(
+ exception,
+ "Failed to deserialize display condition predicate {left} {operator} {right}",
+ displayConditionPredicate.Entity.LeftPropertyPath,
+ displayConditionPredicate.Entity.OperatorType,
+ displayConditionPredicate.Entity.RightPropertyPath
+ );
+ }
+
+ public static void LogListPredicateDeserializationFailure(DisplayConditionListPredicate displayConditionPredicate, JsonException exception)
+ {
+ _logger.Warning(
+ exception,
+ "Failed to deserialize display condition list predicate {list} => {left} {operator} {right}",
+ displayConditionPredicate.Entity.ListPropertyPath,
+ displayConditionPredicate.Entity.LeftPropertyPath,
+ displayConditionPredicate.Entity.OperatorType,
+ displayConditionPredicate.Entity.RightPropertyPath
+ );
+ }
+
+ public static void LogModifierDeserializationFailure(string modifierName, JsonSerializationException exception)
+ {
+ _logger.Warning(exception, "Failed to deserialize static parameter for modifier {modifierName}", modifierName);
+ }
+ }
+}
diff --git a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListPredicateViewModel.cs
index e02fadd81..08e7165ec 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListPredicateViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionListPredicateViewModel.cs
@@ -26,13 +26,13 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
private readonly Timer _updateTimer;
private bool _isInitialized;
private DataModelVisualizationViewModel _leftSideDataModel;
- private BindableCollection _operators;
+ private BindableCollection _operators;
private DataModelVisualizationViewModel _rightSideDataModel;
private DataModelInputViewModel _rightSideInputViewModel;
private int _rightSideTransitionIndex;
private object _rightStaticValue;
private DataModelVisualizationViewModel _selectedLeftSideProperty;
- private DisplayConditionOperator _selectedOperator;
+ private ConditionOperator _selectedOperator;
private DataModelVisualizationViewModel _selectedRightSideProperty;
private List _supportedInputTypes;
@@ -56,7 +56,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
SelectLeftPropertyCommand = new DelegateCommand(ExecuteSelectLeftProperty);
SelectRightPropertyCommand = new DelegateCommand(ExecuteSelectRightProperty);
SelectOperatorCommand = new DelegateCommand(ExecuteSelectOperatorCommand);
- Operators = new BindableCollection();
+ Operators = new BindableCollection();
ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues");
@@ -125,13 +125,13 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
set => SetAndNotify(ref _rightSideInputViewModel, value);
}
- public BindableCollection Operators
+ public BindableCollection Operators
{
get => _operators;
set => SetAndNotify(ref _operators, value);
}
- public DisplayConditionOperator SelectedOperator
+ public ConditionOperator SelectedOperator
{
get => _selectedOperator;
set => SetAndNotify(ref _selectedOperator, value);
@@ -206,7 +206,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
// Get the supported operators
Operators.Clear();
- Operators.AddRange(_dataModelService.GetCompatibleConditionOperators(leftSideType));
+ Operators.AddRange(_dataModelService.GetConditionOperatorsForType(leftSideType));
if (DisplayConditionListPredicate.Operator == null)
DisplayConditionListPredicate.UpdateOperator(Operators.FirstOrDefault(o => o.SupportsType(leftSideType)));
SelectedOperator = DisplayConditionListPredicate.Operator;
@@ -347,7 +347,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
private void ExecuteSelectOperatorCommand(object context)
{
- if (!(context is DisplayConditionOperator displayConditionOperator))
+ if (!(context is ConditionOperator displayConditionOperator))
return;
SelectedOperator = displayConditionOperator;
diff --git a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionPredicateViewModel.cs b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionPredicateViewModel.cs
index 2b38b9c51..a7750ee91 100644
--- a/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionPredicateViewModel.cs
+++ b/src/Artemis.UI/Screens/ProfileEditor/DisplayConditions/DisplayConditionPredicateViewModel.cs
@@ -25,13 +25,13 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
private readonly Timer _updateTimer;
private bool _isInitialized;
private DataModelPropertiesViewModel _leftSideDataModel;
- private BindableCollection _operators;
+ private BindableCollection _operators;
private DataModelPropertiesViewModel _rightSideDataModel;
private DataModelInputViewModel _rightSideInputViewModel;
private int _rightSideTransitionIndex;
private object _rightStaticValue;
private DataModelVisualizationViewModel _selectedLeftSideProperty;
- private DisplayConditionOperator _selectedOperator;
+ private ConditionOperator _selectedOperator;
private DataModelVisualizationViewModel _selectedRightSideProperty;
private List _supportedInputTypes;
@@ -55,7 +55,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
SelectLeftPropertyCommand = new DelegateCommand(ExecuteSelectLeftProperty);
SelectRightPropertyCommand = new DelegateCommand(ExecuteSelectRightProperty);
SelectOperatorCommand = new DelegateCommand(ExecuteSelectOperatorCommand);
- Operators = new BindableCollection();
+ Operators = new BindableCollection();
ShowDataModelValues = settingsService.GetSetting("ProfileEditor.ShowDataModelValues");
@@ -124,13 +124,13 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
set => SetAndNotify(ref _rightSideInputViewModel, value);
}
- public BindableCollection Operators
+ public BindableCollection Operators
{
get => _operators;
set => SetAndNotify(ref _operators, value);
}
- public DisplayConditionOperator SelectedOperator
+ public ConditionOperator SelectedOperator
{
get => _selectedOperator;
set => SetAndNotify(ref _selectedOperator, value);
@@ -208,7 +208,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
// Get the supported operators
Operators.Clear();
- Operators.AddRange(_dataModelService.GetCompatibleConditionOperators(leftSideType));
+ Operators.AddRange(_dataModelService.GetConditionOperatorsForType(leftSideType));
if (DisplayConditionPredicate.Operator == null)
DisplayConditionPredicate.UpdateOperator(Operators.FirstOrDefault(o => o.SupportsType(leftSideType)));
SelectedOperator = DisplayConditionPredicate.Operator;
@@ -329,7 +329,7 @@ namespace Artemis.UI.Screens.ProfileEditor.DisplayConditions
private void ExecuteSelectOperatorCommand(object context)
{
- if (!(context is DisplayConditionOperator displayConditionOperator))
+ if (!(context is ConditionOperator displayConditionOperator))
return;
SelectedOperator = displayConditionOperator;