mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Data bindings - Updated to new paths API
Data bindings - Fixed profile editor behavior
This commit is contained in:
parent
69ae42c039
commit
7610aeae4b
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Artemis.Storage.Entities.Profile.DataBindings;
|
using Artemis.Storage.Entities.Profile.DataBindings;
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
@ -7,8 +6,6 @@ namespace Artemis.Core
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public class DataBinding<TLayerProperty, TProperty> : IDataBinding
|
public class DataBinding<TLayerProperty, TProperty> : IDataBinding
|
||||||
{
|
{
|
||||||
private readonly List<DataBindingModifier<TLayerProperty, TProperty>> _modifiers = new List<DataBindingModifier<TLayerProperty, TProperty>>();
|
|
||||||
|
|
||||||
private TProperty _currentValue;
|
private TProperty _currentValue;
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private TimeSpan _easingProgress;
|
private TimeSpan _easingProgress;
|
||||||
@ -63,51 +60,9 @@ namespace Artemis.Core
|
|||||||
/// Gets ors ets the easing function of the data binding
|
/// Gets ors ets the easing function of the data binding
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Easings.Functions EasingFunction { get; set; }
|
public Easings.Functions EasingFunction { get; set; }
|
||||||
|
|
||||||
|
|
||||||
internal DataBindingEntity Entity { get; }
|
internal DataBindingEntity Entity { get; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the smoothing progress of the data binding
|
|
||||||
/// </summary>
|
|
||||||
/// <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);
|
|
||||||
|
|
||||||
_easingProgress = _easingProgress.Add(TimeSpan.FromSeconds(deltaTime));
|
|
||||||
if (_easingProgress > EasingTime)
|
|
||||||
_easingProgress = EasingTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Apply()
|
|
||||||
{
|
|
||||||
if (_disposed)
|
|
||||||
throw new ObjectDisposedException("DataBinding");
|
|
||||||
|
|
||||||
if (Converter == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
TProperty converterValue = Converter.GetValue();
|
|
||||||
TProperty value = GetValue(converterValue);
|
|
||||||
Converter.ApplyValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
_disposed = true;
|
|
||||||
|
|
||||||
Registration.DataBinding = null;
|
|
||||||
DataBindingMode?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the current value of the data binding
|
/// Gets the current value of the data binding
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -179,6 +134,46 @@ namespace Artemis.Core
|
|||||||
return Converter.Interpolate(_previousValue, _currentValue, Easings.Interpolate(easingAmount, EasingFunction));
|
return Converter.Interpolate(_previousValue, _currentValue, Easings.Interpolate(easingAmount, EasingFunction));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the smoothing progress of the data binding
|
||||||
|
/// </summary>
|
||||||
|
/// <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);
|
||||||
|
|
||||||
|
_easingProgress = _easingProgress.Add(TimeSpan.FromSeconds(deltaTime));
|
||||||
|
if (_easingProgress > EasingTime)
|
||||||
|
_easingProgress = EasingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Apply()
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
throw new ObjectDisposedException("DataBinding");
|
||||||
|
|
||||||
|
if (Converter == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
TProperty converterValue = Converter.GetValue();
|
||||||
|
TProperty value = GetValue(converterValue);
|
||||||
|
Converter.ApplyValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_disposed = true;
|
||||||
|
|
||||||
|
Registration.DataBinding = null;
|
||||||
|
DataBindingMode?.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
#region Mode management
|
#region Mode management
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -82,7 +82,7 @@ namespace Artemis.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts the provided object to a type of <typeparamref name="TProperty" />
|
/// Converts the provided object to a type of <typeparamref name="TProperty" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual TProperty ConvertFromObject(object source)
|
public virtual TProperty ConvertFromObject(object? source)
|
||||||
{
|
{
|
||||||
return (TProperty) Convert.ChangeType(source, typeof(TProperty));
|
return (TProperty) Convert.ChangeType(source, typeof(TProperty));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq.Expressions;
|
|
||||||
using Artemis.Core.DataModelExpansions;
|
|
||||||
using Artemis.Storage.Entities.Profile.DataBindings;
|
using Artemis.Storage.Entities.Profile.DataBindings;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
@ -50,14 +48,9 @@ namespace Artemis.Core
|
|||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the currently used instance of the parameter data model
|
/// Gets the path of the parameter property
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataModel ParameterDataModel { get; private set; }
|
public DataModelPath? ParameterPath { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the path of the parameter property in the <see cref="ParameterDataModel" />
|
|
||||||
/// </summary>
|
|
||||||
public string ParameterPropertyPath { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the parameter static value, only used it <see cref="ParameterType" /> is
|
/// Gets the parameter static value, only used it <see cref="ParameterType" /> is
|
||||||
@ -65,13 +58,144 @@ namespace Artemis.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public object ParameterStaticValue { get; private set; }
|
public object ParameterStaticValue { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A compiled expression tree that when given a matching data model returns the value of the modifiers parameter
|
|
||||||
/// </summary>
|
|
||||||
public Func<DataModel, object> CompiledParameterAccessor { get; set; }
|
|
||||||
|
|
||||||
internal DataBindingModifierEntity Entity { get; set; }
|
internal DataBindingModifierEntity Entity { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Applies the modifier to the provided value
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="currentValue">The value to apply the modifier to, should be of the same type as the data binding target</param>
|
||||||
|
/// <returns>The modified value</returns>
|
||||||
|
public object Apply(object? currentValue)
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
throw new ObjectDisposedException("DataBindingModifier");
|
||||||
|
|
||||||
|
if (ModifierType == null)
|
||||||
|
return currentValue;
|
||||||
|
|
||||||
|
if (!ModifierType.SupportsParameter)
|
||||||
|
return ModifierType.Apply(currentValue, null);
|
||||||
|
|
||||||
|
if (ParameterType == ProfileRightSideType.Dynamic && ParameterPath != null && ParameterPath.IsValid)
|
||||||
|
{
|
||||||
|
object? value = ParameterPath.GetValue();
|
||||||
|
return ModifierType.Apply(currentValue, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ParameterType == ProfileRightSideType.Static)
|
||||||
|
return ModifierType.Apply(currentValue, ParameterStaticValue);
|
||||||
|
|
||||||
|
return currentValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the modifier type of the modifier and re-compiles the expression
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="modifierType"></param>
|
||||||
|
public void UpdateModifierType(DataBindingModifierType modifierType)
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
throw new ObjectDisposedException("DataBindingModifier");
|
||||||
|
|
||||||
|
// Calling CreateExpression will clear compiled expressions
|
||||||
|
if (modifierType == null)
|
||||||
|
{
|
||||||
|
ModifierType = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type targetType = DirectDataBinding.DataBinding.GetTargetType();
|
||||||
|
if (!modifierType.SupportsType(targetType))
|
||||||
|
throw new ArtemisCoreException($"Cannot apply modifier type {modifierType.GetType().Name} to this modifier because " +
|
||||||
|
$"it does not support this data binding's type {targetType.Name}");
|
||||||
|
|
||||||
|
ModifierType = modifierType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the parameter of the modifier and makes the modifier dynamic
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">The path pointing to the parameter</param>
|
||||||
|
public void UpdateParameterDynamic(DataModelPath? path)
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
throw new ObjectDisposedException("DataBindingModifier");
|
||||||
|
|
||||||
|
if (path != null && !path.IsValid)
|
||||||
|
throw new ArtemisCoreException("Cannot update parameter of data binding modifier to an invalid path");
|
||||||
|
|
||||||
|
ParameterPath?.Dispose();
|
||||||
|
ParameterPath = path != null ? new DataModelPath(path) : null;
|
||||||
|
|
||||||
|
ParameterType = ProfileRightSideType.Dynamic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the parameter of the modifier, makes the modifier static and re-compiles the expression
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="staticValue">The static value to use as a parameter</param>
|
||||||
|
public void UpdateParameterStatic(object staticValue)
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
throw new ObjectDisposedException("DataBindingModifier");
|
||||||
|
|
||||||
|
ParameterType = ProfileRightSideType.Static;
|
||||||
|
ParameterPath?.Dispose();
|
||||||
|
ParameterPath = null;
|
||||||
|
|
||||||
|
Type parameterType = ModifierType?.ParameterType ?? DirectDataBinding.DataBinding.GetTargetType();
|
||||||
|
|
||||||
|
// If not null ensure the types match and if not, convert it
|
||||||
|
if (staticValue != null && staticValue.GetType() == parameterType)
|
||||||
|
ParameterStaticValue = staticValue;
|
||||||
|
else if (staticValue != null)
|
||||||
|
ParameterStaticValue = Convert.ChangeType(staticValue, parameterType);
|
||||||
|
// If null create a default instance for value types or simply make it null for reference types
|
||||||
|
else if (parameterType.IsValueType)
|
||||||
|
ParameterStaticValue = Activator.CreateInstance(parameterType);
|
||||||
|
else
|
||||||
|
ParameterStaticValue = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Initialize()
|
||||||
|
{
|
||||||
|
DataBindingModifierTypeStore.DataBindingModifierAdded += DataBindingModifierTypeStoreOnDataBindingModifierAdded;
|
||||||
|
DataBindingModifierTypeStore.DataBindingModifierRemoved += DataBindingModifierTypeStoreOnDataBindingModifierRemoved;
|
||||||
|
|
||||||
|
// Modifier type
|
||||||
|
if (Entity.ModifierTypePluginGuid != null && ModifierType == null)
|
||||||
|
{
|
||||||
|
DataBindingModifierType modifierType = DataBindingModifierTypeStore.Get(Entity.ModifierTypePluginGuid.Value, Entity.ModifierType)?.DataBindingModifierType;
|
||||||
|
if (modifierType != null)
|
||||||
|
UpdateModifierType(modifierType);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dynamic parameter
|
||||||
|
if (ParameterType == ProfileRightSideType.Dynamic && Entity.ParameterPath != null)
|
||||||
|
{
|
||||||
|
ParameterPath = new DataModelPath(null, Entity.ParameterPath);
|
||||||
|
}
|
||||||
|
// Static parameter
|
||||||
|
else if (ParameterType == ProfileRightSideType.Static && Entity.ParameterStaticValue != null && ParameterStaticValue == null)
|
||||||
|
{
|
||||||
|
// Use the target type so JSON.NET has a better idea what to do
|
||||||
|
Type parameterType = ModifierType?.ParameterType ?? DirectDataBinding.DataBinding.GetTargetType();
|
||||||
|
object staticValue;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
staticValue = JsonConvert.DeserializeObject(Entity.ParameterStaticValue, parameterType);
|
||||||
|
}
|
||||||
|
// If deserialization fails, use the type's default
|
||||||
|
catch (JsonSerializationException e)
|
||||||
|
{
|
||||||
|
DeserializationLogger.LogModifierDeserializationFailure(GetType().Name, e);
|
||||||
|
staticValue = Activator.CreateInstance(parameterType);
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateParameterStatic(staticValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Save()
|
public void Save()
|
||||||
@ -79,6 +203,10 @@ namespace Artemis.Core
|
|||||||
if (_disposed)
|
if (_disposed)
|
||||||
throw new ObjectDisposedException("DataBindingModifier");
|
throw new ObjectDisposedException("DataBindingModifier");
|
||||||
|
|
||||||
|
// Don't save an invalid state
|
||||||
|
if (ParameterPath != null && !ParameterPath.IsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!DirectDataBinding.Entity.Modifiers.Contains(Entity))
|
if (!DirectDataBinding.Entity.Modifiers.Contains(Entity))
|
||||||
DirectDataBinding.Entity.Modifiers.Add(Entity);
|
DirectDataBinding.Entity.Modifiers.Add(Entity);
|
||||||
|
|
||||||
@ -94,11 +222,8 @@ namespace Artemis.Core
|
|||||||
Entity.ParameterType = (int) ParameterType;
|
Entity.ParameterType = (int) ParameterType;
|
||||||
|
|
||||||
// Parameter
|
// Parameter
|
||||||
if (ParameterDataModel != null)
|
ParameterPath?.Save();
|
||||||
{
|
Entity.ParameterPath = ParameterPath?.Entity;
|
||||||
Entity.ParameterDataModelGuid = ParameterDataModel.PluginInfo.Guid;
|
|
||||||
Entity.ParameterPropertyPath = ParameterPropertyPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
Entity.ParameterStaticValue = JsonConvert.SerializeObject(ParameterStaticValue);
|
Entity.ParameterStaticValue = JsonConvert.SerializeObject(ParameterStaticValue);
|
||||||
}
|
}
|
||||||
@ -125,186 +250,8 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
DataBindingModifierTypeStore.DataBindingModifierAdded -= DataBindingModifierTypeStoreOnDataBindingModifierAdded;
|
DataBindingModifierTypeStore.DataBindingModifierAdded -= DataBindingModifierTypeStoreOnDataBindingModifierAdded;
|
||||||
DataBindingModifierTypeStore.DataBindingModifierRemoved -= DataBindingModifierTypeStoreOnDataBindingModifierRemoved;
|
DataBindingModifierTypeStore.DataBindingModifierRemoved -= DataBindingModifierTypeStoreOnDataBindingModifierRemoved;
|
||||||
DataModelStore.DataModelAdded -= DataModelStoreOnDataModelAdded;
|
|
||||||
DataModelStore.DataModelRemoved -= DataModelStoreOnDataModelRemoved;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
ParameterPath?.Dispose();
|
||||||
/// Applies the modifier to the provided value
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="currentValue">The value to apply the modifier to, should be of the same type as the data binding target</param>
|
|
||||||
/// <returns>The modified value</returns>
|
|
||||||
public object Apply(object currentValue)
|
|
||||||
{
|
|
||||||
if (_disposed)
|
|
||||||
throw new ObjectDisposedException("DataBindingModifier");
|
|
||||||
|
|
||||||
if (ModifierType == null)
|
|
||||||
return currentValue;
|
|
||||||
|
|
||||||
if (!ModifierType.SupportsParameter)
|
|
||||||
return ModifierType.Apply(currentValue, null);
|
|
||||||
|
|
||||||
if (ParameterType == ProfileRightSideType.Dynamic && CompiledParameterAccessor != null)
|
|
||||||
{
|
|
||||||
object value = CompiledParameterAccessor(ParameterDataModel);
|
|
||||||
return ModifierType.Apply(currentValue, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ParameterType == ProfileRightSideType.Static)
|
|
||||||
return ModifierType.Apply(currentValue, ParameterStaticValue);
|
|
||||||
|
|
||||||
return currentValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the modifier type of the modifier and re-compiles the expression
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="modifierType"></param>
|
|
||||||
public void UpdateModifierType(DataBindingModifierType modifierType)
|
|
||||||
{
|
|
||||||
if (_disposed)
|
|
||||||
throw new ObjectDisposedException("DataBindingModifier");
|
|
||||||
|
|
||||||
// Calling CreateExpression will clear compiled expressions
|
|
||||||
if (modifierType == null)
|
|
||||||
{
|
|
||||||
ModifierType = null;
|
|
||||||
CreateExpression();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Type targetType = DirectDataBinding.DataBinding.GetTargetType();
|
|
||||||
if (!modifierType.SupportsType(targetType))
|
|
||||||
{
|
|
||||||
throw new ArtemisCoreException($"Cannot apply modifier type {modifierType.GetType().Name} to this modifier because " +
|
|
||||||
$"it does not support this data binding's type {targetType.Name}");
|
|
||||||
}
|
|
||||||
|
|
||||||
ModifierType = modifierType;
|
|
||||||
CreateExpression();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the parameter of the modifier, makes the modifier dynamic and re-compiles the expression
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dataModel">The data model of the parameter</param>
|
|
||||||
/// <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)
|
|
||||||
throw new ArtemisCoreException("If path is provided, a data model is also required");
|
|
||||||
|
|
||||||
if (dataModel != null)
|
|
||||||
{
|
|
||||||
if (!dataModel.ContainsPath(path))
|
|
||||||
throw new ArtemisCoreException($"Data model of type {dataModel.GetType().Name} does not contain a property at path '{path}'");
|
|
||||||
}
|
|
||||||
|
|
||||||
ParameterType = ProfileRightSideType.Dynamic;
|
|
||||||
ParameterDataModel = dataModel;
|
|
||||||
ParameterPropertyPath = path;
|
|
||||||
|
|
||||||
CreateExpression();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the parameter of the modifier, makes the modifier static and re-compiles the expression
|
|
||||||
/// </summary>
|
|
||||||
/// <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;
|
|
||||||
|
|
||||||
Type parameterType = ModifierType?.ParameterType ?? DirectDataBinding.DataBinding.GetTargetType();
|
|
||||||
|
|
||||||
// If not null ensure the types match and if not, convert it
|
|
||||||
if (staticValue != null && staticValue.GetType() == parameterType)
|
|
||||||
ParameterStaticValue = staticValue;
|
|
||||||
else if (staticValue != null)
|
|
||||||
ParameterStaticValue = Convert.ChangeType(staticValue, parameterType);
|
|
||||||
// If null create a default instance for value types or simply make it null for reference types
|
|
||||||
else if (parameterType.IsValueType)
|
|
||||||
ParameterStaticValue = Activator.CreateInstance(parameterType);
|
|
||||||
else
|
|
||||||
ParameterStaticValue = null;
|
|
||||||
|
|
||||||
CreateExpression();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Initialize()
|
|
||||||
{
|
|
||||||
DataBindingModifierTypeStore.DataBindingModifierAdded += DataBindingModifierTypeStoreOnDataBindingModifierAdded;
|
|
||||||
DataBindingModifierTypeStore.DataBindingModifierRemoved += DataBindingModifierTypeStoreOnDataBindingModifierRemoved;
|
|
||||||
DataModelStore.DataModelAdded += DataModelStoreOnDataModelAdded;
|
|
||||||
DataModelStore.DataModelRemoved += DataModelStoreOnDataModelRemoved;
|
|
||||||
|
|
||||||
// Modifier type
|
|
||||||
if (Entity.ModifierTypePluginGuid != null && ModifierType == null)
|
|
||||||
{
|
|
||||||
DataBindingModifierType modifierType = DataBindingModifierTypeStore.Get(Entity.ModifierTypePluginGuid.Value, Entity.ModifierType)?.DataBindingModifierType;
|
|
||||||
if (modifierType != null)
|
|
||||||
UpdateModifierType(modifierType);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dynamic parameter
|
|
||||||
if (ParameterType == ProfileRightSideType.Dynamic && Entity.ParameterDataModelGuid != null && ParameterDataModel == null)
|
|
||||||
{
|
|
||||||
DataModel dataModel = DataModelStore.Get(Entity.ParameterDataModelGuid.Value)?.DataModel;
|
|
||||||
if (dataModel != null && dataModel.ContainsPath(Entity.ParameterPropertyPath))
|
|
||||||
UpdateParameter(dataModel, Entity.ParameterPropertyPath);
|
|
||||||
}
|
|
||||||
// Static parameter
|
|
||||||
else if (ParameterType == ProfileRightSideType.Static && Entity.ParameterStaticValue != null && ParameterStaticValue == null)
|
|
||||||
{
|
|
||||||
// Use the target type so JSON.NET has a better idea what to do
|
|
||||||
Type parameterType = ModifierType?.ParameterType ?? DirectDataBinding.DataBinding.GetTargetType();
|
|
||||||
object staticValue;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
staticValue = JsonConvert.DeserializeObject(Entity.ParameterStaticValue, parameterType);
|
|
||||||
}
|
|
||||||
// If deserialization fails, use the type's default
|
|
||||||
catch (JsonSerializationException e)
|
|
||||||
{
|
|
||||||
DeserializationLogger.LogModifierDeserializationFailure(GetType().Name, e);
|
|
||||||
staticValue = Activator.CreateInstance(parameterType);
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateParameter(staticValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateExpression()
|
|
||||||
{
|
|
||||||
CompiledParameterAccessor = null;
|
|
||||||
|
|
||||||
if (ModifierType == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ParameterType == ProfileRightSideType.Dynamic && ModifierType.SupportsParameter)
|
|
||||||
{
|
|
||||||
if (ParameterDataModel == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// If the right side value is null, the constant type cannot be inferred and must be provided based on the data binding target
|
|
||||||
Expression parameterAccessor = ExpressionUtilities.CreateDataModelAccessor(
|
|
||||||
ParameterDataModel, ParameterPropertyPath, "parameter", out ParameterExpression rightSideParameter
|
|
||||||
);
|
|
||||||
Expression<Func<DataModel, object>> lambda = Expression.Lambda<Func<DataModel, object>>(Expression.Convert(parameterAccessor, typeof(object)), rightSideParameter);
|
|
||||||
CompiledParameterAccessor = lambda.Compile();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Event handlers
|
#region Event handlers
|
||||||
@ -325,21 +272,6 @@ namespace Artemis.Core
|
|||||||
UpdateModifierType(null);
|
UpdateModifierType(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DataModelStoreOnDataModelAdded(object sender, DataModelStoreEvent e)
|
|
||||||
{
|
|
||||||
DataModel 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
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,8 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using Artemis.Core.DataModelExpansions;
|
|
||||||
using Artemis.Storage.Entities.Profile.DataBindings;
|
using Artemis.Storage.Entities.Profile.DataBindings;
|
||||||
|
|
||||||
namespace Artemis.Core
|
namespace Artemis.Core
|
||||||
@ -20,31 +17,20 @@ namespace Artemis.Core
|
|||||||
DataBinding = dataBinding;
|
DataBinding = dataBinding;
|
||||||
Entity = entity;
|
Entity = entity;
|
||||||
|
|
||||||
Initialize();
|
|
||||||
Load();
|
Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal DirectDataBindingEntity Entity { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the currently used instance of the data model that contains the source of the data binding
|
/// Gets the path of the source property
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataModel SourceDataModel { get; private set; }
|
public DataModelPath? SourcePath { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the path of the source property in the <see cref="SourceDataModel" />
|
|
||||||
/// </summary>
|
|
||||||
public string SourcePropertyPath { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a list of modifiers applied to this data binding
|
/// Gets a list of modifiers applied to this data binding
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IReadOnlyList<DataBindingModifier<TLayerProperty, TProperty>> Modifiers => _modifiers.AsReadOnly();
|
public IReadOnlyList<DataBindingModifier<TLayerProperty, TProperty>> Modifiers => _modifiers.AsReadOnly();
|
||||||
|
|
||||||
/// <summary>
|
internal DirectDataBindingEntity Entity { get; }
|
||||||
/// Gets the compiled function that gets the current value of the data binding target
|
|
||||||
/// </summary>
|
|
||||||
public Func<DataModel, object> CompiledTargetAccessor { get; private set; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public DataBinding<TLayerProperty, TProperty> DataBinding { get; }
|
public DataBinding<TLayerProperty, TProperty> DataBinding { get; }
|
||||||
@ -55,10 +41,10 @@ namespace Artemis.Core
|
|||||||
if (_disposed)
|
if (_disposed)
|
||||||
throw new ObjectDisposedException("DirectDataBinding");
|
throw new ObjectDisposedException("DirectDataBinding");
|
||||||
|
|
||||||
if (CompiledTargetAccessor == null)
|
if (SourcePath == null || !SourcePath.IsValid)
|
||||||
return baseValue;
|
return baseValue;
|
||||||
|
|
||||||
object dataBindingValue = CompiledTargetAccessor(SourceDataModel);
|
object? dataBindingValue = SourcePath.GetValue();
|
||||||
foreach (DataBindingModifier<TLayerProperty, TProperty> dataBindingModifier in Modifiers)
|
foreach (DataBindingModifier<TLayerProperty, TProperty> dataBindingModifier in Modifiers)
|
||||||
dataBindingValue = dataBindingModifier.Apply(dataBindingValue);
|
dataBindingValue = dataBindingModifier.Apply(dataBindingValue);
|
||||||
|
|
||||||
@ -72,11 +58,10 @@ namespace Artemis.Core
|
|||||||
{
|
{
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
|
|
||||||
DataModelStore.DataModelAdded -= DataModelStoreOnDataModelAdded;
|
|
||||||
DataModelStore.DataModelRemoved -= DataModelStoreOnDataModelRemoved;
|
|
||||||
|
|
||||||
foreach (DataBindingModifier<TLayerProperty, TProperty> dataBindingModifier in Modifiers)
|
foreach (DataBindingModifier<TLayerProperty, TProperty> dataBindingModifier in Modifiers)
|
||||||
dataBindingModifier.Dispose();
|
dataBindingModifier.Dispose();
|
||||||
|
|
||||||
|
SourcePath?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -86,7 +71,9 @@ namespace Artemis.Core
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Load()
|
public void Load()
|
||||||
{
|
{
|
||||||
// Data model is done during Initialize
|
// Source
|
||||||
|
if (Entity.SourcePath != null)
|
||||||
|
SourcePath = new DataModelPath(null, Entity.SourcePath);
|
||||||
|
|
||||||
// Modifiers
|
// Modifiers
|
||||||
foreach (DataBindingModifierEntity dataBindingModifierEntity in Entity.Modifiers)
|
foreach (DataBindingModifierEntity dataBindingModifierEntity in Entity.Modifiers)
|
||||||
@ -98,12 +85,12 @@ namespace Artemis.Core
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
// Data model
|
// Don't save an invalid state
|
||||||
if (SourceDataModel != null)
|
if (SourcePath != null && !SourcePath.IsValid)
|
||||||
{
|
return;
|
||||||
Entity.SourceDataModelGuid = SourceDataModel.PluginInfo.Guid;
|
|
||||||
Entity.SourcePropertyPath = SourcePropertyPath;
|
SourcePath?.Save();
|
||||||
}
|
Entity.SourcePath = SourcePath?.Entity;
|
||||||
|
|
||||||
// Modifiers
|
// Modifiers
|
||||||
Entity.Modifiers.Clear();
|
Entity.Modifiers.Clear();
|
||||||
@ -113,76 +100,30 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Initialization
|
|
||||||
|
|
||||||
private void Initialize()
|
|
||||||
{
|
|
||||||
DataModelStore.DataModelAdded += DataModelStoreOnDataModelAdded;
|
|
||||||
DataModelStore.DataModelRemoved += DataModelStoreOnDataModelRemoved;
|
|
||||||
|
|
||||||
// Source
|
|
||||||
if (Entity.SourceDataModelGuid != null && SourceDataModel == null)
|
|
||||||
{
|
|
||||||
DataModel dataModel = DataModelStore.Get(Entity.SourceDataModelGuid.Value)?.DataModel;
|
|
||||||
if (dataModel != null && dataModel.ContainsPath(Entity.SourcePropertyPath))
|
|
||||||
UpdateSource(dataModel, Entity.SourcePropertyPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateExpression()
|
|
||||||
{
|
|
||||||
Type listType = SourceDataModel.GetListTypeInPath(SourcePropertyPath);
|
|
||||||
if (listType != null)
|
|
||||||
throw new ArtemisCoreException($"Cannot create a regular accessor at path {SourcePropertyPath} because the path contains a list");
|
|
||||||
|
|
||||||
ParameterExpression parameter = Expression.Parameter(typeof(DataModel), "targetDataModel");
|
|
||||||
Expression accessor = SourcePropertyPath.Split('.').Aggregate<string, Expression>(
|
|
||||||
Expression.Convert(parameter, SourceDataModel.GetType()), // Cast to the appropriate type
|
|
||||||
Expression.Property
|
|
||||||
);
|
|
||||||
|
|
||||||
UnaryExpression returnValue = Expression.Convert(accessor, typeof(object));
|
|
||||||
|
|
||||||
Expression<Func<DataModel, object>> lambda = Expression.Lambda<Func<DataModel, object>>(returnValue, parameter);
|
|
||||||
CompiledTargetAccessor = lambda.Compile();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Source
|
#region Source
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the type of the source property of this data binding
|
/// Returns the type of the source property of this data binding
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Type GetSourceType()
|
public Type? GetSourceType()
|
||||||
{
|
{
|
||||||
return SourceDataModel?.GetTypeAtPath(SourcePropertyPath);
|
return SourcePath?.GetPropertyType();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the source of the data binding and re-compiles the expression
|
/// Updates the source of the data binding
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dataModel">The data model of the source</param>
|
/// <param name="path">The path pointing to the source</param>
|
||||||
/// <param name="path">The path pointing to the source inside the data model</param>
|
public void UpdateSource(DataModelPath? path)
|
||||||
public void UpdateSource(DataModel dataModel, string path)
|
|
||||||
{
|
{
|
||||||
if (_disposed)
|
if (_disposed)
|
||||||
throw new ObjectDisposedException("DirectDataBinding");
|
throw new ObjectDisposedException("DirectDataBinding");
|
||||||
|
|
||||||
if (dataModel != null && path == null)
|
if (path != null && !path.IsValid)
|
||||||
throw new ArtemisCoreException("If a data model is provided, a path is also required");
|
throw new ArtemisCoreException("Cannot update source of data binding to an invalid path");
|
||||||
if (dataModel == null && path != null)
|
|
||||||
throw new ArtemisCoreException("If path is provided, a data model is also required");
|
|
||||||
|
|
||||||
if (dataModel != null)
|
SourcePath?.Dispose();
|
||||||
{
|
SourcePath = path != null ? new DataModelPath(path) : null;
|
||||||
if (!dataModel.ContainsPath(path))
|
|
||||||
throw new ArtemisCoreException($"Data model of type {dataModel.GetType().Name} does not contain a property at path '{path}'");
|
|
||||||
}
|
|
||||||
|
|
||||||
SourceDataModel = dataModel;
|
|
||||||
SourcePropertyPath = path;
|
|
||||||
CreateExpression();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@ -239,31 +180,12 @@ namespace Artemis.Core
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Event handlers
|
|
||||||
|
|
||||||
private void DataModelStoreOnDataModelAdded(object sender, DataModelStoreEvent e)
|
|
||||||
{
|
|
||||||
DataModel 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
|
#region Events
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Occurs when a modifier is added or removed
|
/// Occurs when a modifier is added or removed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event EventHandler ModifiersUpdated;
|
public event EventHandler? ModifiersUpdated;
|
||||||
|
|
||||||
protected virtual void OnModifiersUpdated()
|
protected virtual void OnModifiersUpdated()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -10,8 +10,7 @@ namespace Artemis.Storage.Entities.Profile.DataBindings
|
|||||||
public int Order { get; set; }
|
public int Order { get; set; }
|
||||||
public int ParameterType { get; set; }
|
public int ParameterType { get; set; }
|
||||||
|
|
||||||
public Guid? ParameterDataModelGuid { get; set; }
|
public DataModelPathEntity ParameterPath { get; set; }
|
||||||
public string ParameterPropertyPath { get; set; }
|
|
||||||
|
|
||||||
// Stored as a string to be able to control serialization and deserialization ourselves
|
// Stored as a string to be able to control serialization and deserialization ourselves
|
||||||
public string ParameterStaticValue { get; set; }
|
public string ParameterStaticValue { get; set; }
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Artemis.Storage.Entities.Profile.DataBindings
|
namespace Artemis.Storage.Entities.Profile.DataBindings
|
||||||
{
|
{
|
||||||
@ -10,9 +9,7 @@ namespace Artemis.Storage.Entities.Profile.DataBindings
|
|||||||
Modifiers = new List<DataBindingModifierEntity>();
|
Modifiers = new List<DataBindingModifierEntity>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Guid? SourceDataModelGuid { get; set; }
|
public DataModelPathEntity SourcePath { get; set; }
|
||||||
public string SourcePropertyPath { get; set; }
|
|
||||||
|
|
||||||
public List<DataBindingModifierEntity> Modifiers { get; set; }
|
public List<DataBindingModifierEntity> Modifiers { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -20,10 +20,10 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
private bool _isEasingTimeEnabled;
|
private bool _isEasingTimeEnabled;
|
||||||
private DataBindingModeType _selectedDataBindingMode;
|
private DataBindingModeType _selectedDataBindingMode;
|
||||||
private TimelineEasingViewModel _selectedEasingViewModel;
|
private TimelineEasingViewModel _selectedEasingViewModel;
|
||||||
|
|
||||||
private bool _updating;
|
|
||||||
private bool _applyTestResultToLayer;
|
private bool _applyTestResultToLayer;
|
||||||
|
|
||||||
|
private bool _updating;
|
||||||
|
private bool _updatingTestResult;
|
||||||
|
|
||||||
public DataBindingViewModel(DataBindingRegistration<TLayerProperty, TProperty> registration,
|
public DataBindingViewModel(DataBindingRegistration<TLayerProperty, TProperty> registration,
|
||||||
IProfileEditorService profileEditorService,
|
IProfileEditorService profileEditorService,
|
||||||
@ -74,7 +74,11 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
public bool ApplyTestResultToLayer
|
public bool ApplyTestResultToLayer
|
||||||
{
|
{
|
||||||
get => _applyTestResultToLayer;
|
get => _applyTestResultToLayer;
|
||||||
set => SetAndNotify(ref _applyTestResultToLayer, value);
|
set
|
||||||
|
{
|
||||||
|
if (!SetAndNotify(ref _applyTestResultToLayer, value)) return;
|
||||||
|
_profileEditorService.UpdateProfilePreview();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TimelineEasingViewModel SelectedEasingViewModel
|
public TimelineEasingViewModel SelectedEasingViewModel
|
||||||
@ -111,6 +115,8 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
{
|
{
|
||||||
_updateTimer.Dispose();
|
_updateTimer.Dispose();
|
||||||
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
_updateTimer.Elapsed -= OnUpdateTimerOnElapsed;
|
||||||
|
|
||||||
|
Registration.LayerProperty.Updated -= LayerPropertyOnUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Initialize()
|
private void Initialize()
|
||||||
@ -119,6 +125,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
|
|
||||||
_updateTimer.Start();
|
_updateTimer.Start();
|
||||||
_updateTimer.Elapsed += OnUpdateTimerOnElapsed;
|
_updateTimer.Elapsed += OnUpdateTimerOnElapsed;
|
||||||
|
Registration.LayerProperty.Updated += LayerPropertyOnUpdated;
|
||||||
|
|
||||||
CreateDataBindingModeModeViewModel();
|
CreateDataBindingModeModeViewModel();
|
||||||
Update();
|
Update();
|
||||||
@ -216,14 +223,22 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
|
|
||||||
private void UpdateTestResult()
|
private void UpdateTestResult()
|
||||||
{
|
{
|
||||||
|
if (_updating || _updatingTestResult)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_updatingTestResult = true;
|
||||||
|
|
||||||
if (Registration.DataBinding == null || ActiveItem == null)
|
if (Registration.DataBinding == null || ActiveItem == null)
|
||||||
{
|
{
|
||||||
TestInputValue.UpdateValue(default);
|
TestInputValue.UpdateValue(default);
|
||||||
TestResultValue.UpdateValue(default);
|
TestResultValue.UpdateValue(default);
|
||||||
|
_updatingTestResult = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// While playing in preview data bindings aren't updated
|
||||||
Registration.DataBinding.Update(0.04);
|
Registration.DataBinding.Update(0.04);
|
||||||
|
|
||||||
if (ActiveItem.SupportsTestValue)
|
if (ActiveItem.SupportsTestValue)
|
||||||
{
|
{
|
||||||
TProperty currentValue = Registration.Converter.ConvertFromObject(ActiveItem?.GetTestValue() ?? default(TProperty));
|
TProperty currentValue = Registration.Converter.ConvertFromObject(ActiveItem?.GetTestValue() ?? default(TProperty));
|
||||||
@ -235,11 +250,15 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
|
|
||||||
if (ApplyTestResultToLayer)
|
if (ApplyTestResultToLayer)
|
||||||
{
|
{
|
||||||
Registration.DataBinding.Apply();
|
// TODO: A bit crappy, the ProfileEditorService should really be doing this
|
||||||
_profileEditorService.UpdateProfilePreview();
|
bool playing = ((Parent as Screen)?.Parent as LayerPropertiesViewModel)?.Playing ?? true;
|
||||||
|
if (!playing)
|
||||||
|
_profileEditorService.UpdateProfilePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_updatingTestResult = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EnableDataBinding()
|
private void EnableDataBinding()
|
||||||
{
|
{
|
||||||
if (Registration.DataBinding != null)
|
if (Registration.DataBinding != null)
|
||||||
@ -264,6 +283,12 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings
|
|||||||
{
|
{
|
||||||
UpdateTestResult();
|
UpdateTestResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void LayerPropertyOnUpdated(object? sender, LayerPropertyEventArgs<TLayerProperty> e)
|
||||||
|
{
|
||||||
|
if (ApplyTestResultToLayer)
|
||||||
|
Registration.DataBinding?.Apply();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IDataBindingViewModel : IScreen, IDisposable
|
public interface IDataBindingViewModel : IScreen, IDisposable
|
||||||
|
|||||||
@ -94,10 +94,10 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
|
|||||||
if (Modifier.ParameterType == ProfileRightSideType.Dynamic)
|
if (Modifier.ParameterType == ProfileRightSideType.Dynamic)
|
||||||
{
|
{
|
||||||
Type sourceType = Modifier.DirectDataBinding.GetSourceType();
|
Type sourceType = Modifier.DirectDataBinding.GetSourceType();
|
||||||
Modifier.UpdateParameter((Modifier.ModifierType.ParameterType ?? sourceType).GetDefault());
|
Modifier.UpdateParameterStatic((Modifier.ModifierType.ParameterType ?? sourceType).GetDefault());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Modifier.UpdateParameter(null, null);
|
Modifier.UpdateParameterDynamic(null);
|
||||||
|
|
||||||
Update();
|
Update();
|
||||||
_profileEditorService.UpdateSelectedProfileElement();
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
@ -105,13 +105,13 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
|
|||||||
|
|
||||||
private void ParameterSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
|
private void ParameterSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
|
||||||
{
|
{
|
||||||
Modifier.UpdateParameter(e.DataModelPath.Target, e.DataModelPath.Path);
|
Modifier.UpdateParameterDynamic(e.DataModelPath);
|
||||||
_profileEditorService.UpdateSelectedProfileElement();
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StaticInputViewModelOnValueUpdated(object sender, DataModelInputStaticEventArgs e)
|
private void StaticInputViewModelOnValueUpdated(object sender, DataModelInputStaticEventArgs e)
|
||||||
{
|
{
|
||||||
Modifier.UpdateParameter(e.Value);
|
Modifier.UpdateParameterStatic(e.Value);
|
||||||
_profileEditorService.UpdateSelectedProfileElement();
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,11 +166,10 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
|
|||||||
SelectedModifierType = Modifier.ModifierType;
|
SelectedModifierType = Modifier.ModifierType;
|
||||||
|
|
||||||
// Parameter
|
// Parameter
|
||||||
throw new NotImplementedException();
|
if (DynamicSelectionViewModel != null)
|
||||||
// if (DynamicSelectionViewModel != null)
|
DynamicSelectionViewModel.ChangeDataModelPath(Modifier.ParameterPath);
|
||||||
// DynamicSelectionViewModel.PopulateSelectedPropertyViewModel(Modifier.ParameterDataModel, Modifier.ParameterPropertyPath);
|
else if (StaticInputViewModel != null)
|
||||||
// else if (StaticInputViewModel != null)
|
StaticInputViewModel.Value = Modifier.ParameterStaticValue;
|
||||||
// StaticInputViewModel.Value = Modifier.ParameterStaticValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExecuteSelectModifierTypeCommand(object context)
|
private void ExecuteSelectModifierTypeCommand(object context)
|
||||||
|
|||||||
@ -56,18 +56,16 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
|
|||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
TargetSelectionViewModel.ChangeDataModelPath(DirectDataBinding.SourcePath);
|
||||||
// TargetSelectionViewModel.PopulateSelectedPropertyViewModel(DirectDataBinding.SourceDataModel, DirectDataBinding.SourcePropertyPath);
|
|
||||||
TargetSelectionViewModel.FilterTypes = new[] {DirectDataBinding.DataBinding.GetTargetType()};
|
TargetSelectionViewModel.FilterTypes = new[] {DirectDataBinding.DataBinding.GetTargetType()};
|
||||||
|
|
||||||
CanAddModifier = DirectDataBinding.SourceDataModel != null;
|
CanAddModifier = DirectDataBinding.SourcePath != null && DirectDataBinding.SourcePath.IsValid;
|
||||||
UpdateModifierViewModels();
|
UpdateModifierViewModels();
|
||||||
}
|
}
|
||||||
|
|
||||||
public object GetTestValue()
|
public object GetTestValue()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return DirectDataBinding.SourcePath?.GetValue();
|
||||||
// return TargetSelectionViewModel.SelectedPropertyViewModel?.GetCurrentValue();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IDisposable
|
#region IDisposable
|
||||||
@ -114,8 +112,7 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
|
|||||||
|
|
||||||
private void TargetSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
|
private void TargetSelectionViewModelOnPropertySelected(object sender, DataModelInputDynamicEventArgs e)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
DirectDataBinding.UpdateSource(e.DataModelPath);
|
||||||
// DirectDataBinding.UpdateSource(e.DataModelVisualizationViewModel.DataModel, e.DataModelVisualizationViewModel.Path);
|
|
||||||
Update();
|
Update();
|
||||||
|
|
||||||
_profileEditorService.UpdateSelectedProfileElement();
|
_profileEditorService.UpdateSelectedProfileElement();
|
||||||
@ -143,6 +140,10 @@ namespace Artemis.UI.Screens.ProfileEditor.LayerProperties.DataBindings.DirectDa
|
|||||||
modifierViewModel.Dispose();
|
modifierViewModel.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't create children without a source or with an invalid source
|
||||||
|
if (DirectDataBinding.SourcePath == null || !DirectDataBinding.SourcePath.IsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
// Add missing VMs
|
// Add missing VMs
|
||||||
foreach (DataBindingModifier<TLayerProperty, TProperty> modifier in DirectDataBinding.Modifiers)
|
foreach (DataBindingModifier<TLayerProperty, TProperty> modifier in DirectDataBinding.Modifiers)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user