Display conditions - Implemented IDisposable

Display conditions - Listen to registration add/remove WIP
Data bindings - Implemented IDisposable
Data bindings - Listen to registration add/remove
This commit is contained in:
SpoinkyNL committed 2020-09-12 10:39:44 +02:00
1 parent 11de30318e
commit 1de6fefc2a
17 files changed
+461 -227

No files matched your search

@@ -4,7 +4,6 @@ using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Artemis.Core.DataModelExpansions;
using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile.DataBindings;
namespace Artemis.Core
@@ -17,6 +16,7 @@ namespace Artemis.Core
private TProperty _currentValue;
private TimeSpan _easingProgress;
private TProperty _previousValue;
private bool _disposed;
internal DataBinding(DataBindingRegistration<TLayerProperty, TProperty> dataBindingRegistration)
{
@@ -25,6 +25,7 @@ namespace Artemis.Core
ApplyRegistration(dataBindingRegistration);
Save();
Initialize();
}
internal DataBinding(LayerProperty<TLayerProperty> layerProperty, DataBindingEntity entity)
@@ -32,6 +33,8 @@ namespace Artemis.Core
LayerProperty = layerProperty;
Entity = entity;
// Load will add children so be initialized before that
Initialize();
Load();
}
@@ -95,6 +98,9 @@ namespace Artemis.Core
/// <param name="deltaTime">The time in seconds that passed since the last update</param>
public void Update(double deltaTime)
{
if (_disposed)
throw new ObjectDisposedException("DataBinding");
// Data bindings cannot go back in time like brushes
deltaTime = Math.Max(0, deltaTime);
@@ -103,11 +109,27 @@ namespace Artemis.Core
_easingProgress = EasingTime;
}
/// <inheritdoc />
public void Apply()
{
if (_disposed)
throw new ObjectDisposedException("DataBinding");
if (Converter == null)
return;
var value = GetValue(Converter.GetValue());
Converter.ApplyValue(GetValue(value));
}
/// <summary>
/// Adds a modifier to the data binding's <see cref="Modifiers" /> collection
/// </summary>
public void AddModifier(DataBindingModifier<TLayerProperty, TProperty> modifier)
{
if (_disposed)
throw new ObjectDisposedException("DataBinding");
if (!_modifiers.Contains(modifier))
{
modifier.DataBinding = this;
@@ -122,6 +144,9 @@ namespace Artemis.Core
/// </summary>
public void RemoveModifier(DataBindingModifier<TLayerProperty, TProperty> modifier)
{
if (_disposed)
throw new ObjectDisposedException("DataBinding");
if (_modifiers.Contains(modifier))
{
modifier.DataBinding = null;
@@ -138,6 +163,9 @@ namespace Artemis.Core
/// <param name="path">The path pointing to the source inside the data model</param>
public void UpdateSource(DataModel dataModel, string path)
{
if (_disposed)
throw new ObjectDisposedException("DataBinding");
if (dataModel != null && path == null)
throw new ArtemisCoreException("If a data model is provided, a path is also required");
if (dataModel == null && path != null)
@@ -161,6 +189,9 @@ namespace Artemis.Core
/// <returns></returns>
public TProperty GetValue(TProperty baseValue)
{
if (_disposed)
throw new ObjectDisposedException("DataBinding");
if (CompiledTargetAccessor == null || Converter == null)
return baseValue;
@@ -198,30 +229,18 @@ namespace Artemis.Core
return SourceDataModel?.GetTypeAtPath(SourcePropertyPath);
}
/// <inheritdoc />
public void Apply()
private void Initialize()
{
if (Converter == null)
return;
DataModelStore.DataModelAdded += DataModelStoreOnDataModelAdded;
DataModelStore.DataModelRemoved += DataModelStoreOnDataModelRemoved;
var value = GetValue(Converter.GetValue());
Converter.ApplyValue(GetValue(value));
}
/// <inheritdoc />
public void Initialize(IDataModelService dataModelService, IDataBindingService dataBindingService)
{
// Source
if (Entity.SourceDataModelGuid != null && SourceDataModel == null)
{
var dataModel = dataModelService.GetPluginDataModelByGuid(Entity.SourceDataModelGuid.Value);
var dataModel = DataModelStore.Get(Entity.SourceDataModelGuid.Value)?.DataModel;
if (dataModel != null && dataModel.ContainsPath(Entity.SourcePropertyPath))
UpdateSource(dataModel, Entity.SourcePropertyPath);
}
// Modifiers
foreach (var dataBindingModifier in Modifiers)
dataBindingModifier.Initialize(dataModelService, dataBindingService);
}
private void ResetEasing(TProperty value)
@@ -283,6 +302,8 @@ namespace Artemis.Core
/// <inheritdoc />
public void Load()
{
if (_disposed)
throw new ObjectDisposedException("DataBinding");
// General
var registration = LayerProperty.GetDataBindingRegistration<TProperty>(Entity.TargetProperty);
ApplyRegistration(registration);
@@ -301,6 +322,9 @@ namespace Artemis.Core
/// <inheritdoc />
public void Save()
{
if (_disposed)
throw new ObjectDisposedException("DataBinding");
if (!LayerProperty.Entity.DataBindingEntities.Contains(Entity))
LayerProperty.Entity.DataBindingEntities.Add(Entity);
@@ -311,9 +335,12 @@ namespace Artemis.Core
Entity.EasingFunction = (int) EasingFunction;
// Data model
Entity.SourceDataModelGuid = SourceDataModel?.PluginInfo?.Guid;
Entity.SourcePropertyPath = SourcePropertyPath;
if (SourceDataModel != null)
{
Entity.SourceDataModelGuid = SourceDataModel.PluginInfo.Guid;
Entity.SourcePropertyPath = SourcePropertyPath;
}
// Modifiers
Entity.Modifiers.Clear();
foreach (var dataBindingModifier in Modifiers)
@@ -322,6 +349,25 @@ namespace Artemis.Core
#endregion
#region Event handlers
private void DataModelStoreOnDataModelAdded(object sender, DataModelStoreEvent e)
{
var dataModel = e.Registration.DataModel;
if (dataModel.PluginInfo.Guid == Entity.SourceDataModelGuid && dataModel.ContainsPath(Entity.SourcePropertyPath))
UpdateSource(dataModel, Entity.SourcePropertyPath);
}
private void DataModelStoreOnDataModelRemoved(object sender, DataModelStoreEvent e)
{
if (SourceDataModel != e.Registration.DataModel)
return;
SourceDataModel = null;
CompiledTargetAccessor = null;
}
#endregion
#region Events
/// <summary>
@@ -335,6 +381,18 @@ namespace Artemis.Core
}
#endregion
/// <inheritdoc />
public void Dispose()
{
_disposed = true;
DataModelStore.DataModelAdded -= DataModelStoreOnDataModelAdded;
DataModelStore.DataModelRemoved -= DataModelStoreOnDataModelRemoved;
foreach (var dataBindingModifier in Modifiers)
dataBindingModifier.Dispose();
}
}
/// <summary>
@@ -2,7 +2,6 @@
using System.Linq;
using System.Linq.Expressions;
using Artemis.Core.DataModelExpansions;
using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile.DataBindings;
using Newtonsoft.Json;
@@ -12,6 +11,7 @@ namespace Artemis.Core
public class DataBindingModifier<TLayerProperty, TProperty> : IDataBindingModifier
{
private DataBinding<TLayerProperty, TProperty> _dataBinding;
private bool _disposed;
/// <summary>
/// Creates a new instance of the <see cref="DataBindingModifier{TLayerProperty,TProperty}" /> class
@@ -22,6 +22,7 @@ namespace Artemis.Core
ParameterType = parameterType;
Entity = new DataBindingModifierEntity();
Save();
Initialize();
}
internal DataBindingModifier(DataBinding<TLayerProperty, TProperty> dataBinding, DataBindingModifierEntity entity)
@@ -29,6 +30,7 @@ namespace Artemis.Core
DataBinding = dataBinding;
Entity = entity;
Load();
Initialize();
}
/// <summary>
@@ -82,6 +84,52 @@ namespace Artemis.Core
internal DataBindingModifierEntity Entity { get; set; }
/// <inheritdoc />
public void Save()
{
if (_disposed)
throw new ObjectDisposedException("DataBindingModifier");
if (!DataBinding.Entity.Modifiers.Contains(Entity))
DataBinding.Entity.Modifiers.Add(Entity);
// Modifier
if (ModifierType != null)
{
Entity.ModifierType = ModifierType.GetType().Name;
Entity.ModifierTypePluginGuid = ModifierType.PluginInfo.Guid;
}
// General
Entity.Order = Order;
Entity.ParameterType = (int) ParameterType;
// Parameter
if (ParameterDataModel != null)
{
Entity.ParameterDataModelGuid = ParameterDataModel.PluginInfo.Guid;
Entity.ParameterPropertyPath = ParameterPropertyPath;
}
Entity.ParameterStaticValue = JsonConvert.SerializeObject(ParameterStaticValue);
}
/// <inheritdoc />
public void Load()
{
if (_disposed)
throw new ObjectDisposedException("DataBindingModifier");
// Modifier type is done during Initialize
// General
Order = Entity.Order;
ParameterType = (ProfileRightSideType) Entity.ParameterType;
// Parameter is done during initialize
}
/// <summary>
/// Applies the modifier to the provided value
/// </summary>
@@ -89,6 +137,9 @@ namespace Artemis.Core
/// <returns>The modified value</returns>
public object Apply(object currentValue)
{
if (_disposed)
throw new ObjectDisposedException("DataBindingModifier");
if (ModifierType == null)
return currentValue;
@@ -113,6 +164,9 @@ namespace Artemis.Core
/// <param name="modifierType"></param>
public void UpdateModifierType(DataBindingModifierType modifierType)
{
if (_disposed)
throw new ObjectDisposedException("DataBindingModifier");
// Calling CreateExpression will clear compiled expressions
if (modifierType == null)
{
@@ -139,6 +193,9 @@ namespace Artemis.Core
/// <param name="path">The path pointing to the parameter inside the data model</param>
public void UpdateParameter(DataModel dataModel, string path)
{
if (_disposed)
throw new ObjectDisposedException("DataBindingModifier");
if (dataModel != null && path == null)
throw new ArtemisCoreException("If a data model is provided, a path is also required");
if (dataModel == null && path != null)
@@ -163,6 +220,9 @@ namespace Artemis.Core
/// <param name="staticValue">The static value to use as a parameter</param>
public void UpdateParameter(object staticValue)
{
if (_disposed)
throw new ObjectDisposedException("DataBindingModifier");
ParameterType = ProfileRightSideType.Static;
ParameterDataModel = null;
ParameterPropertyPath = null;
@@ -183,12 +243,17 @@ namespace Artemis.Core
CreateExpression();
}
internal void Initialize(IDataModelService dataModelService, IDataBindingService dataBindingService)
private void Initialize()
{
DataBindingModifierTypeStore.DataBindingModifierAdded += DataBindingModifierTypeStoreOnDataBindingModifierAdded;
DataBindingModifierTypeStore.DataBindingModifierRemoved += DataBindingModifierTypeStoreOnDataBindingModifierRemoved;
DataModelStore.DataModelAdded += DataModelStoreOnDataModelAdded;
DataModelStore.DataModelRemoved += DataModelStoreOnDataModelRemoved;
// Modifier type
if (Entity.ModifierTypePluginGuid != null && ModifierType == null)
{
var modifierType = dataBindingService.GetModifierType(Entity.ModifierTypePluginGuid.Value, Entity.ModifierType);
var modifierType = DataBindingModifierTypeStore.Get(Entity.ModifierTypePluginGuid.Value, Entity.ModifierType)?.DataBindingModifierType;
if (modifierType != null)
UpdateModifierType(modifierType);
}
@@ -196,7 +261,7 @@ namespace Artemis.Core
// Dynamic parameter
if (ParameterType == ProfileRightSideType.Dynamic && Entity.ParameterDataModelGuid != null && ParameterDataModel == null)
{
var dataModel = dataModelService.GetPluginDataModelByGuid(Entity.ParameterDataModelGuid.Value);
var dataModel = DataModelStore.Get(Entity.ParameterDataModelGuid.Value)?.DataModel;
if (dataModel != null && dataModel.ContainsPath(Entity.ParameterPropertyPath))
UpdateParameter(dataModel, Entity.ParameterPropertyPath);
}
@@ -214,7 +279,7 @@ namespace Artemis.Core
// If deserialization fails, use the type's default
catch (JsonSerializationException e)
{
dataBindingService.LogModifierDeserializationFailure(GetType().Name, e);
DeserializationLogger.LogModifierDeserializationFailure(GetType().Name, e);
staticValue = Activator.CreateInstance(targetType);
}
@@ -222,39 +287,6 @@ namespace Artemis.Core
}
}
/// <inheritdoc />
public void Save()
{
if (!DataBinding.Entity.Modifiers.Contains(Entity))
DataBinding.Entity.Modifiers.Add(Entity);
// Modifier
Entity.ModifierType = ModifierType?.GetType().Name;
Entity.ModifierTypePluginGuid = ModifierType?.PluginInfo.Guid;
// General
Entity.Order = Order;
Entity.ParameterType = (int) ParameterType;
// Parameter
Entity.ParameterDataModelGuid = ParameterDataModel?.PluginInfo.Guid;
Entity.ParameterPropertyPath = ParameterPropertyPath;
Entity.ParameterStaticValue = JsonConvert.SerializeObject(ParameterStaticValue);
}
/// <inheritdoc />
public void Load()
{
// Modifier type is done during Initialize
// General
Order = Entity.Order;
ParameterType = (ProfileRightSideType) Entity.ParameterType;
// Parameter is done during initialize
}
private void CreateExpression()
{
CompiledParameterAccessor = null;
@@ -286,5 +318,51 @@ namespace Artemis.Core
Expression.Property
);
}
#region Event handlers
private void DataBindingModifierTypeStoreOnDataBindingModifierAdded(object sender, DataBindingModifierTypeStoreEvent e)
{
if (ModifierType != null)
return;
var modifierType = e.TypeRegistration.DataBindingModifierType;
if (modifierType.PluginInfo.Guid == Entity.ModifierTypePluginGuid && modifierType.GetType().Name == Entity.ModifierType)
UpdateModifierType(modifierType);
}
private void DataBindingModifierTypeStoreOnDataBindingModifierRemoved(object sender, DataBindingModifierTypeStoreEvent e)
{
if (e.TypeRegistration.DataBindingModifierType == ModifierType)
UpdateModifierType(null);
}
private void DataModelStoreOnDataModelAdded(object sender, DataModelStoreEvent e)
{
var dataModel = e.Registration.DataModel;
if (dataModel.PluginInfo.Guid == Entity.ParameterDataModelGuid && dataModel.ContainsPath(Entity.ParameterPropertyPath))
UpdateParameter(dataModel, Entity.ParameterPropertyPath);
}
private void DataModelStoreOnDataModelRemoved(object sender, DataModelStoreEvent e)
{
if (e.Registration.DataModel != ParameterDataModel)
return;
ParameterDataModel = null;
CompiledParameterAccessor = null;
}
#endregion
/// <inheritdoc />
public void Dispose()
{
_disposed = true;
DataBindingModifierTypeStore.DataBindingModifierAdded -= DataBindingModifierTypeStoreOnDataBindingModifierAdded;
DataBindingModifierTypeStore.DataBindingModifierRemoved -= DataBindingModifierTypeStoreOnDataBindingModifierRemoved;
DataModelStore.DataModelAdded -= DataModelStoreOnDataModelAdded;
DataModelStore.DataModelRemoved -= DataModelStoreOnDataModelRemoved;
}
}
}
@@ -1,20 +1,14 @@
using Artemis.Core.DataModelExpansions;
using Artemis.Core.Services;
using System;
using Artemis.Core.DataModelExpansions;
namespace Artemis.Core
{
/// <summary>
/// Represents a data binding that binds a certain <see cref="LayerProperty{T}" /> to a value inside a <see cref="DataModel" />
/// Represents a data binding that binds a certain <see cref="LayerProperty{T}" /> to a value inside a
/// <see cref="DataModel" />
/// </summary>
public interface IDataBinding : IStorageModel, IUpdateModel
public interface IDataBinding : IStorageModel, IUpdateModel, IDisposable
{
/// <summary>
/// (Re)initializes the data binding
/// </summary>
/// <param name="dataModelService"></param>
/// <param name="dataBindingService"></param>
void Initialize(IDataModelService dataModelService, IDataBindingService dataBindingService);
/// <summary>
/// Applies the data binding to the layer property
/// </summary>
@@ -1,9 +1,11 @@
namespace Artemis.Core
using System;
namespace Artemis.Core
{
/// <summary>
/// Modifies a data model value in a way defined by the modifier type
/// </summary>
public interface IDataBindingModifier : IStorageModel
public interface IDataBindingModifier : IStorageModel, IDisposable
{
}
}
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Artemis.Core.Services;
namespace Artemis.Core
{
@@ -10,9 +9,6 @@ namespace Artemis.Core
/// </summary>
public abstract class DataBindingModifierType
{
private IDataBindingService _dataBindingService;
private bool _registered;
/// <summary>
/// Gets the plugin info this data binding modifier belongs to
/// <para>Note: Not set until after registering</para>
@@ -63,35 +59,5 @@ namespace Artemis.Core
/// </param>
/// <returns>The modified value, must be a value of a type contained in <see cref="CompatibleTypes" /></returns>
public abstract object Apply(object currentValue, object parameterValue);
internal void Register(PluginInfo pluginInfo, IDataBindingService dataBindingService)
{
if (_registered)
return;
PluginInfo = pluginInfo;
_dataBindingService = dataBindingService;
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
_dataBindingService.RemoveModifierType(this);
}
}
}