Data bindings - Fixed internal easing state

Data bindings - Some UI improvements :)
Data bindings - Added floor modifier
Layer properties - Fixed new base values not applying
This commit is contained in:
SpoinkyNL committed 2020-09-07 21:41:39 +02:00
1 parent 6b309cb1f3
commit 5d540530af
12 files changed
+148 -115

No files matched your search

@@ -17,7 +17,6 @@ namespace Artemis.Core
private readonly List<DataBindingModifier> _modifiers = new List<DataBindingModifier>();
private object _currentValue;
private bool _isInitialized;
private object _previousValue;
private TimeSpan _easingProgress;
@@ -200,6 +199,9 @@ namespace Artemis.Core
/// <param name="deltaTime">The time in seconds that passed since the last update</param>
public void Update(double deltaTime)
{
// 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;
@@ -256,11 +258,8 @@ namespace Artemis.Core
internal void Initialize(IDataModelService dataModelService, IDataBindingService dataBindingService)
{
if (_isInitialized)
throw new ArtemisCoreException("Data binding is already initialized");
// Source
if (Entity.SourceDataModelGuid != null)
if (Entity.SourceDataModelGuid != null && SourceDataModel == null)
{
var dataModel = dataModelService.GetPluginDataModelByGuid(Entity.SourceDataModelGuid.Value);
if (dataModel != null && dataModel.ContainsPath(Entity.SourcePropertyPath))
@@ -270,8 +269,6 @@ namespace Artemis.Core
// Modifiers
foreach (var dataBindingModifier in Modifiers)
dataBindingModifier.Initialize(dataModelService, dataBindingService);
_isInitialized = true;
}
private void ApplyRegistration(DataBindingRegistration dataBindingRegistration)
@@ -4,8 +4,6 @@ using System.Linq.Expressions;
using Artemis.Core.DataModelExpansions;
using Artemis.Core.Services;
using Artemis.Storage.Entities.Profile.DataBindings;
using LiteDB.Engine;
using Microsoft.VisualBasic;
using Newtonsoft.Json;
namespace Artemis.Core
@@ -16,10 +14,9 @@ namespace Artemis.Core
public class DataBindingModifier
{
private DataBinding _dataBinding;
private bool _isInitialized;
/// <summary>
/// Creates a new instance of the <see cref="DataBindingModifier"/> class
/// Creates a new instance of the <see cref="DataBindingModifier" /> class
/// </summary>
/// <param name="parameterType">The type of the parameter, can either be dynamic (based on a data model value) or static</param>
public DataBindingModifier(ProfileRightSideType parameterType)
@@ -83,7 +80,7 @@ namespace Artemis.Core
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
/// 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; }
@@ -96,13 +93,19 @@ namespace Artemis.Core
/// <returns>The modified value</returns>
public object Apply(object currentValue)
{
if (ModifierType == null)
return currentValue;
if (!ModifierType.SupportsParameter)
return ModifierType.Apply(currentValue, null);
if (ParameterType == ProfileRightSideType.Dynamic && CompiledParameterAccessor != null)
{
var value = CompiledParameterAccessor(ParameterDataModel);
return ModifierType.Apply(currentValue, value);
}
if (ParameterType == ProfileRightSideType.Static && ModifierType != null)
if (ParameterType == ProfileRightSideType.Static)
return ModifierType.Apply(currentValue, ParameterStaticValue);
return currentValue;
@@ -186,11 +189,8 @@ namespace Artemis.Core
internal void Initialize(IDataModelService dataModelService, IDataBindingService dataBindingService)
{
if (_isInitialized)
throw new ArtemisCoreException("Data binding modifier is already initialized");
// Modifier type
if (Entity.ModifierTypePluginGuid != null)
if (Entity.ModifierTypePluginGuid != null && ModifierType == null)
{
var modifierType = dataBindingService.GetModifierType(Entity.ModifierTypePluginGuid.Value, Entity.ModifierType);
if (modifierType != null)
@@ -198,14 +198,14 @@ namespace Artemis.Core
}
// Dynamic parameter
if (ParameterType == ProfileRightSideType.Dynamic && Entity.ParameterDataModelGuid != null)
if (ParameterType == ProfileRightSideType.Dynamic && Entity.ParameterDataModelGuid != null && ParameterDataModel == null)
{
var dataModel = dataModelService.GetPluginDataModelByGuid(Entity.ParameterDataModelGuid.Value);
if (dataModel != null && dataModel.ContainsPath(Entity.ParameterPropertyPath))
UpdateParameter(dataModel, Entity.ParameterPropertyPath);
}
// Static parameter
else if (ParameterType == ProfileRightSideType.Static && Entity.ParameterStaticValue != null)
else if (ParameterType == ProfileRightSideType.Static && Entity.ParameterStaticValue != null && ParameterStaticValue == null)
{
// Use the target type so JSON.NET has a better idea what to do
var targetType = DataBinding.TargetProperty.PropertyType;
@@ -224,41 +224,6 @@ namespace Artemis.Core
UpdateParameter(staticValue);
}
_isInitialized = true;
}
private void CreateExpression()
{
CompiledParameterAccessor = null;
if (ModifierType == null || DataBinding == 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
var parameterAccessor = CreateAccessor(ParameterDataModel, ParameterPropertyPath, "parameter", out var rightSideParameter);
var lambda = Expression.Lambda<Func<DataModel, object>>(Expression.Convert(parameterAccessor, typeof(object)), rightSideParameter);
CompiledParameterAccessor = lambda.Compile();
}
}
private Expression CreateAccessor(DataModel dataModel, string path, string parameterName, out ParameterExpression parameter)
{
var listType = dataModel.GetListTypeInPath(path);
if (listType != null)
throw new ArtemisCoreException($"Cannot create a regular accessor at path {path} because the path contains a list");
parameter = Expression.Parameter(typeof(object), parameterName + "DataModel");
return path.Split('.').Aggregate<string, Expression>(
Expression.Convert(parameter, dataModel.GetType()), // Cast to the appropriate type
Expression.Property
);
}
internal void ApplyToEntity()
@@ -287,5 +252,38 @@ namespace Artemis.Core
// Parameter is done during initialize
}
private void CreateExpression()
{
CompiledParameterAccessor = null;
if (ModifierType == null || DataBinding == 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
var parameterAccessor = CreateAccessor(ParameterDataModel, ParameterPropertyPath, "parameter", out var rightSideParameter);
var lambda = Expression.Lambda<Func<DataModel, object>>(Expression.Convert(parameterAccessor, typeof(object)), rightSideParameter);
CompiledParameterAccessor = lambda.Compile();
}
}
private Expression CreateAccessor(DataModel dataModel, string path, string parameterName, out ParameterExpression parameter)
{
var listType = dataModel.GetListTypeInPath(path);
if (listType != null)
throw new ArtemisCoreException($"Cannot create a regular accessor at path {path} because the path contains a list");
parameter = Expression.Parameter(typeof(object), parameterName + "DataModel");
return path.Split('.').Aggregate<string, Expression>(
Expression.Convert(parameter, dataModel.GetType()), // Cast to the appropriate type
Expression.Property
);
}
}
}
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
namespace Artemis.Core
{
internal class FloorModifierType : DataBindingModifierType
{
public FloorModifierType()
{
SupportsParameter = false;
}
public override IReadOnlyCollection<Type> CompatibleTypes => Constants.NumberTypes;
public override string Description => "Floor";
public override string Icon => "ArrowDownDropCircleOutline";
public override object Apply(object currentValue, object parameterValue)
{
var floatValue = Convert.ToSingle(currentValue);
return Math.Floor(floatValue);
}
}
}
@@ -39,6 +39,7 @@ namespace Artemis.Core
return;
base.BaseValue = value;
Update();
OnBaseValueChanged();
}
}
@@ -104,7 +105,7 @@ namespace Artemis.Core
// Force an update so that the base value is applied to the current value and
// keyframes/data bindings are applied using the new base value
Update(0);
Update();
}
/// <summary>
@@ -195,7 +196,7 @@ namespace Artemis.Core
/// <summary>
/// Updates the property, applying keyframes and data bindings to the current value
/// </summary>
internal void Update(double deltaTime)
internal void Update(double deltaTime = 0)
{
CurrentValue = BaseValue;