diff --git a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
index acdf15530..54c63292f 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/DataBinding.cs
@@ -177,7 +177,7 @@ namespace Artemis.Core
var easingAmount = _easingProgress.TotalSeconds / EasingTime.TotalSeconds;
return Converter.Interpolate(_previousValue, _currentValue, Easings.Interpolate(easingAmount, EasingFunction));
}
-
+
#region Mode management
///
@@ -218,7 +218,7 @@ namespace Artemis.Core
}
#endregion
-
+
#region Storage
///
@@ -262,7 +262,7 @@ namespace Artemis.Core
public enum DataBindingModeType
{
///
- /// Disables the data binding
+ /// Disables the data binding
///
None,
@@ -272,8 +272,8 @@ namespace Artemis.Core
Direct,
///
- /// Replaces the layer property value with the data binding value
+ /// Replaces the layer property value with the data binding value
///
- Conditional,
+ Conditional
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/DataBindingRegistration.cs b/src/Artemis.Core/Models/Profile/DataBindings/DataBindingRegistration.cs
index e1dea2169..6ef9dd14a 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/DataBindingRegistration.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/DataBindingRegistration.cs
@@ -51,7 +51,7 @@ namespace Artemis.Core
{
return DataBinding;
}
-
+
///
public IDataBinding CreateDataBinding()
{
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/ConditionalDataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/ConditionalDataBinding.cs
index 9d844bd9b..0e3cd309d 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/ConditionalDataBinding.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Modes/ConditionalDataBinding.cs
@@ -1,4 +1,7 @@
-using Artemis.Storage.Entities.Profile.DataBindings;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Artemis.Storage.Entities.Profile.DataBindings;
namespace Artemis.Core
{
@@ -7,42 +10,130 @@ namespace Artemis.Core
///
public class ConditionalDataBinding : IDataBindingMode
{
+ private readonly List> _conditions = new List>();
+ private bool _disposed;
+
internal ConditionalDataBinding(DataBinding dataBinding, ConditionalDataBindingEntity entity)
{
DataBinding = dataBinding;
Entity = entity;
}
+ internal ConditionalDataBindingEntity Entity { get; }
+
+ ///
+ /// Gets a list of conditions applied to this data binding
+ ///
+ public IReadOnlyList> Conditions => _conditions.AsReadOnly();
+
///
public DataBinding DataBinding { get; }
///
public TProperty GetValue(TProperty baseValue)
{
- return default;
+ if (_disposed)
+ throw new ObjectDisposedException("ConditionalDataBinding");
+
+ var condition = Conditions.FirstOrDefault(c => c.Evaluate());
+ return condition == null ? baseValue : condition.Value;
}
- internal ConditionalDataBindingEntity Entity { get; }
-
- #region Storage
-
- ///
- public void Load()
- {
- }
-
- ///
- public void Save()
- {
- }
-
- #endregion
-
#region IDisposable
///
public void Dispose()
{
+ _disposed = true;
+
+ foreach (var dataBindingCondition in Conditions)
+ dataBindingCondition.Dispose();
+ }
+
+ #endregion
+
+ #region Values
+
+ ///
+ /// Adds a condition to the conditional data binding's collection
+ ///
+ /// The newly created
+ public DataBindingCondition AddCondition()
+ {
+ if (_disposed)
+ throw new ObjectDisposedException("ConditionalDataBinding");
+
+ var condition = new DataBindingCondition(this);
+ _conditions.Add(condition);
+
+ ApplyOrder();
+ OnConditionsUpdated();
+
+ return condition;
+ }
+
+ ///
+ /// Removes a condition from the conditional data binding's collection and disposes it
+ ///
+ ///
+ public void RemoveCondition(DataBindingCondition condition)
+ {
+ if (_disposed)
+ throw new ObjectDisposedException("ConditionalDataBinding");
+ if (!_conditions.Contains(condition))
+ return;
+
+ _conditions.Remove(condition);
+ condition.Dispose();
+
+ ApplyOrder();
+ OnConditionsUpdated();
+ }
+
+ internal void ApplyOrder()
+ {
+ _conditions.Sort((a, b) => a.Order.CompareTo(b.Order));
+ for (var index = 0; index < _conditions.Count; index++)
+ {
+ var condition = _conditions[index];
+ condition.Order = index + 1;
+ }
+ }
+
+ #endregion
+
+
+ #region Storage
+
+ ///
+ public void Load()
+ {
+ foreach (var dataBindingConditionEntity in Entity.Values)
+ _conditions.Add(new DataBindingCondition(this, dataBindingConditionEntity));
+
+ ApplyOrder();
+ }
+
+ ///
+ public void Save()
+ {
+ Entity.Values.Clear();
+ foreach (var dataBindingCondition in Conditions)
+ dataBindingCondition.Save();
+ }
+
+ #endregion
+
+ #region Events
+
+ ///
+ /// Occurs when a condition is added or removed
+ ///
+ public event EventHandler ConditionsUpdated;
+
+ protected virtual void OnConditionsUpdated()
+ {
+ ConditionsUpdated?.Invoke(this, EventArgs.Empty);
}
#endregion
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/DataBindingCondition.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/DataBindingCondition.cs
new file mode 100644
index 000000000..49f08ee8c
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Modes/DataBindingCondition.cs
@@ -0,0 +1,107 @@
+using System;
+using Artemis.Storage.Entities.Profile.DataBindings;
+using Newtonsoft.Json;
+
+namespace Artemis.Core
+{
+ ///
+ public class DataBindingCondition : IDataBindingCondition
+ {
+ private bool _disposed;
+
+ ///
+ /// Creates a new instance of the class
+ ///
+ /// The conditional data binding this condition is applied too
+ public DataBindingCondition(ConditionalDataBinding conditionalDataBinding)
+ {
+ ConditionalDataBinding = conditionalDataBinding ?? throw new ArgumentNullException(nameof(conditionalDataBinding));
+ Order = conditionalDataBinding.Conditions.Count + 1;
+ Entity = new DataBindingConditionEntity();
+ Save();
+ }
+
+ internal DataBindingCondition(ConditionalDataBinding conditionalDataBinding, DataBindingConditionEntity entity)
+ {
+ ConditionalDataBinding = conditionalDataBinding ?? throw new ArgumentNullException(nameof(conditionalDataBinding));
+ Entity = entity;
+ Load();
+ }
+
+ ///
+ /// Gets the conditional data binding this condition is applied to
+ ///
+ public ConditionalDataBinding ConditionalDataBinding { get; }
+
+ ///
+ /// Gets the position at which the modifier appears on the data binding
+ ///
+ public int Order { get; internal set; }
+
+ ///
+ /// Gets or sets the value to be applied when the condition is met
+ ///
+ public TProperty Value { get; set; }
+
+ ///
+ /// Gets the root group of the condition that must be met
+ ///
+ public DataModelConditionGroup Condition { get; private set; }
+
+ internal DataBindingConditionEntity Entity { get; set; }
+
+ ///
+ public bool Evaluate()
+ {
+ return Condition.Evaluate();
+ }
+
+ ///
+ public void Save()
+ {
+ if (_disposed)
+ throw new ObjectDisposedException("DataBindingCondition");
+
+ if (!ConditionalDataBinding.Entity.Values.Contains(Entity))
+ ConditionalDataBinding.Entity.Values.Add(Entity);
+
+ Entity.Condition = Condition.Entity;
+ Condition.Save();
+
+ Entity.Value = JsonConvert.SerializeObject(Value);
+ Entity.Order = Order;
+ }
+
+ ///
+ public void Load()
+ {
+ if (_disposed)
+ throw new ObjectDisposedException("DataBindingCondition");
+
+ Condition = Entity.Condition != null
+ ? new DataModelConditionGroup(null, Entity.Condition)
+ : new DataModelConditionGroup(null);
+
+ Value = JsonConvert.DeserializeObject(Entity.Value);
+ Order = Entity.Order;
+ }
+
+ ///
+ public void Dispose()
+ {
+ _disposed = true;
+
+ Condition.Dispose();
+ }
+
+ ///
+ /// Updates the order and resorts the Conditions list in the
+ ///
+ ///
+ public void UpdateOrder(int order)
+ {
+ Order = order;
+ ConditionalDataBinding.ApplyOrder();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/DataBindingModifier.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/DataBindingModifier.cs
similarity index 95%
rename from src/Artemis.Core/Models/Profile/DataBindings/DataBindingModifier.cs
rename to src/Artemis.Core/Models/Profile/DataBindings/Modes/DataBindingModifier.cs
index d8b2c117d..391027097 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/DataBindingModifier.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Modes/DataBindingModifier.cs
@@ -12,14 +12,10 @@ namespace Artemis.Core
{
private bool _disposed;
- ///
- /// Creates a new instance of the class
- ///
- /// The direct data binding the modifier is to be applied to
- /// The type of the parameter, can either be dynamic (based on a data model value) or static
- public DataBindingModifier(DirectDataBinding directDataBinding, ProfileRightSideType parameterType)
+ internal DataBindingModifier(DirectDataBinding directDataBinding, ProfileRightSideType parameterType)
{
DirectDataBinding = directDataBinding ?? throw new ArgumentNullException(nameof(directDataBinding));
+ Order = directDataBinding.Modifiers.Count + 1;
ParameterType = parameterType;
Entity = new DataBindingModifierEntity();
Initialize();
@@ -40,7 +36,7 @@ namespace Artemis.Core
public DataBindingModifierType ModifierType { get; private set; }
///
- /// Gets the direct data binding this modifier is applied to
+ /// Gets the direct data binding this modifier is applied to
///
public DirectDataBinding DirectDataBinding { get; }
@@ -123,6 +119,17 @@ namespace Artemis.Core
// Parameter is done during initialize
}
+ ///
+ public void Dispose()
+ {
+ _disposed = true;
+
+ DataBindingModifierTypeStore.DataBindingModifierAdded -= DataBindingModifierTypeStoreOnDataBindingModifierAdded;
+ DataBindingModifierTypeStore.DataBindingModifierRemoved -= DataBindingModifierTypeStoreOnDataBindingModifierRemoved;
+ DataModelStore.DataModelAdded -= DataModelStoreOnDataModelAdded;
+ DataModelStore.DataModelRemoved -= DataModelStoreOnDataModelRemoved;
+ }
+
///
/// Applies the modifier to the provided value
///
@@ -339,23 +346,12 @@ namespace Artemis.Core
private void DataModelStoreOnDataModelRemoved(object sender, DataModelStoreEvent e)
{
- if (e.Registration.DataModel != ParameterDataModel)
+ if (e.Registration.DataModel != ParameterDataModel)
return;
ParameterDataModel = null;
CompiledParameterAccessor = null;
}
#endregion
-
- ///
- public void Dispose()
- {
- _disposed = true;
-
- DataBindingModifierTypeStore.DataBindingModifierAdded -= DataBindingModifierTypeStoreOnDataBindingModifierAdded;
- DataBindingModifierTypeStore.DataBindingModifierRemoved -= DataBindingModifierTypeStoreOnDataBindingModifierRemoved;
- DataModelStore.DataModelAdded -= DataModelStoreOnDataModelAdded;
- DataModelStore.DataModelRemoved -= DataModelStoreOnDataModelRemoved;
- }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/DataBindingModifierType.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/DataBindingModifierType.cs
similarity index 100%
rename from src/Artemis.Core/Models/Profile/DataBindings/DataBindingModifierType.cs
rename to src/Artemis.Core/Models/Profile/DataBindings/Modes/DataBindingModifierType.cs
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/DirectDataBinding.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/DirectDataBinding.cs
index 4ed07a17c..75e3c8c82 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/DirectDataBinding.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Modes/DirectDataBinding.cs
@@ -24,9 +24,6 @@ namespace Artemis.Core
Load();
}
- ///
- public DataBinding DataBinding { get; }
-
internal DirectDataBindingEntity Entity { get; }
///
@@ -49,11 +46,14 @@ namespace Artemis.Core
///
public Func CompiledTargetAccessor { get; private set; }
+ ///
+ public DataBinding DataBinding { get; }
+
///
public TProperty GetValue(TProperty baseValue)
{
if (_disposed)
- throw new ObjectDisposedException("DataBinding");
+ throw new ObjectDisposedException("DirectDataBinding");
if (CompiledTargetAccessor == null)
return baseValue;
@@ -91,6 +91,8 @@ namespace Artemis.Core
// Modifiers
foreach (var dataBindingModifierEntity in Entity.Modifiers)
_modifiers.Add(new DataBindingModifier(this, dataBindingModifierEntity));
+
+ ApplyOrder();
}
///
@@ -156,7 +158,7 @@ namespace Artemis.Core
{
return SourceDataModel?.GetTypeAtPath(SourcePropertyPath);
}
-
+
///
/// Updates the source of the data binding and re-compiles the expression
///
@@ -165,7 +167,7 @@ namespace Artemis.Core
public void UpdateSource(DataModel dataModel, string path)
{
if (_disposed)
- throw new ObjectDisposedException("DataBinding");
+ throw new ObjectDisposedException("DirectDataBinding");
if (dataModel != null && path == null)
throw new ArtemisCoreException("If a data model is provided, a path is also required");
@@ -188,34 +190,47 @@ namespace Artemis.Core
#region Modifiers
///
- /// Adds a modifier to the data binding's collection
+ /// Adds a modifier to the direct data binding's collection
///
+ /// The type of the parameter, can either be dynamic (based on a data model value) or static
public DataBindingModifier AddModifier(ProfileRightSideType type)
{
if (_disposed)
- throw new ObjectDisposedException("DataBinding");
+ throw new ObjectDisposedException("DirectDataBinding");
var modifier = new DataBindingModifier(this, type);
_modifiers.Add(modifier);
+
+ ApplyOrder();
OnModifiersUpdated();
return modifier;
}
///
- /// Removes a modifier from the data binding's collection and disposes it
+ /// Removes a modifier from the direct data binding's collection and disposes it
///
public void RemoveModifier(DataBindingModifier modifier)
{
if (_disposed)
- throw new ObjectDisposedException("DataBinding");
+ throw new ObjectDisposedException("DirectDataBinding");
+ if (!_modifiers.Contains(modifier))
+ return;
- if (_modifiers.Contains(modifier))
+ _modifiers.Remove(modifier);
+ modifier.Dispose();
+
+ ApplyOrder();
+ OnModifiersUpdated();
+ }
+
+ internal void ApplyOrder()
+ {
+ _modifiers.Sort((a, b) => a.Order.CompareTo(b.Order));
+ for (var index = 0; index < _modifiers.Count; index++)
{
- _modifiers.Remove(modifier);
- modifier.Dispose();
-
- OnModifiersUpdated();
+ var modifier = _modifiers[index];
+ modifier.Order = index + 1;
}
}
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingCondition.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingCondition.cs
new file mode 100644
index 000000000..26ad9a9f2
--- /dev/null
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingCondition.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace Artemis.Core
+{
+ ///
+ /// Represents a condition and a value inside a
+ ///
+ public interface IDataBindingCondition : IStorageModel, IDisposable
+ {
+ ///
+ /// Evaluates the condition
+ ///
+ bool Evaluate();
+ }
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingMode.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingMode.cs
index d9cea1a86..e46a2aee9 100644
--- a/src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingMode.cs
+++ b/src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingMode.cs
@@ -3,7 +3,7 @@
namespace Artemis.Core
{
///
- /// Represents a data binding mode
+ /// Represents a data binding mode
///
public interface IDataBindingMode : IStorageModel, IDisposable
{
@@ -19,4 +19,4 @@ namespace Artemis.Core
///
TProperty GetValue(TProperty baseValue);
}
-}
+}
\ No newline at end of file
diff --git a/src/Artemis.Core/Models/Profile/DataBindings/IDataBindingModifier.cs b/src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingModifier.cs
similarity index 100%
rename from src/Artemis.Core/Models/Profile/DataBindings/IDataBindingModifier.cs
rename to src/Artemis.Core/Models/Profile/DataBindings/Modes/IDataBindingModifier.cs
diff --git a/src/Artemis.Storage/Entities/Profile/DataBindings/ConditionalDataBindingEntity.cs b/src/Artemis.Storage/Entities/Profile/DataBindings/ConditionalDataBindingEntity.cs
index 02a8768e3..c7fffcf19 100644
--- a/src/Artemis.Storage/Entities/Profile/DataBindings/ConditionalDataBindingEntity.cs
+++ b/src/Artemis.Storage/Entities/Profile/DataBindings/ConditionalDataBindingEntity.cs
@@ -6,9 +6,9 @@ namespace Artemis.Storage.Entities.Profile.DataBindings
{
public ConditionalDataBindingEntity()
{
- Values = new List();
+ Values = new List();
}
- public List Values { get; set; }
+ public List Values { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingConditionValueEntity.cs b/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingConditionEntity.cs
similarity index 54%
rename from src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingConditionValueEntity.cs
rename to src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingConditionEntity.cs
index 8f1c9004b..7fb0fc611 100644
--- a/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingConditionValueEntity.cs
+++ b/src/Artemis.Storage/Entities/Profile/DataBindings/DataBindingConditionEntity.cs
@@ -2,9 +2,10 @@
namespace Artemis.Storage.Entities.Profile.DataBindings
{
- public class DataBindingConditionValueEntity
+ public class DataBindingConditionEntity
{
public string Value { get; set; }
- public DataModelConditionGroupEntity RootGroup { get; set; }
+ public DataModelConditionGroupEntity Condition { get; set; }
+ public int Order { get; set; }
}
}
\ No newline at end of file