mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-11 19:36:28 +00:00
Data bindings - Rewrote data binding system to fully leverage nodes
This commit is contained in:
1 parent
7933bf7ee9
commit
0bb93f2ebd
63 files changed
+654
-1533
No files matched your search
@@ -1,25 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Artemis.Storage.Entities.Profile.DataBindings;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class DataBinding<TLayerProperty, TProperty> : IDataBinding
|
||||
public class DataBinding<TLayerProperty> : IDataBinding
|
||||
{
|
||||
private TProperty _currentValue = default!;
|
||||
private readonly List<IDataBindingProperty> _properties = new();
|
||||
private bool _disposed;
|
||||
private TimeSpan _easingProgress;
|
||||
private TProperty _lastAppliedValue = default!;
|
||||
private TProperty _previousValue = default!;
|
||||
private bool _reapplyValue;
|
||||
private bool _isEnabled;
|
||||
|
||||
internal DataBinding(DataBindingRegistration<TLayerProperty, TProperty> dataBindingRegistration)
|
||||
internal DataBinding(LayerProperty<TLayerProperty> layerProperty)
|
||||
{
|
||||
LayerProperty = dataBindingRegistration.LayerProperty;
|
||||
Entity = new DataBindingEntity();
|
||||
LayerProperty = layerProperty;
|
||||
|
||||
ApplyRegistration(dataBindingRegistration);
|
||||
Script = new NodeScript<TProperty>(GetScriptName(), "The value to put into the data binding", LayerProperty.ProfileElement.Profile);
|
||||
Entity = new DataBindingEntity();
|
||||
Script = new DataBindingNodeScript<TLayerProperty>(GetScriptName(), "The value to put into the data binding", this, LayerProperty.ProfileElement.Profile);
|
||||
|
||||
Save();
|
||||
}
|
||||
@@ -27,39 +26,23 @@ namespace Artemis.Core
|
||||
internal DataBinding(LayerProperty<TLayerProperty> layerProperty, DataBindingEntity entity)
|
||||
{
|
||||
LayerProperty = layerProperty;
|
||||
|
||||
Entity = entity;
|
||||
Script = new NodeScript<TProperty>(GetScriptName(), "The value to put into the data binding", LayerProperty.ProfileElement.Profile);
|
||||
Script = new DataBindingNodeScript<TLayerProperty>(GetScriptName(), "The value to put into the data binding", this, LayerProperty.ProfileElement.Profile);
|
||||
|
||||
// Load will add children so be initialized before that
|
||||
Load();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data binding registration this data binding is based upon
|
||||
/// </summary>
|
||||
public DataBindingRegistration<TLayerProperty, TProperty>? Registration { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the layer property this data binding targets
|
||||
/// </summary>
|
||||
public LayerProperty<TLayerProperty> LayerProperty { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the converter used to apply this data binding to the <see cref="LayerProperty" />
|
||||
/// Gets the script used to populate the data binding
|
||||
/// </summary>
|
||||
public DataBindingConverter<TLayerProperty, TProperty>? Converter { get; private set; }
|
||||
|
||||
public NodeScript<TProperty> Script { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the easing time of the data binding
|
||||
/// </summary>
|
||||
public TimeSpan EasingTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets ors ets the easing function of the data binding
|
||||
/// </summary>
|
||||
public Easings.Functions EasingFunction { get; set; }
|
||||
public DataBindingNodeScript<TLayerProperty> Script { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data binding entity this data binding uses for persistent storage
|
||||
@@ -67,38 +50,52 @@ namespace Artemis.Core
|
||||
public DataBindingEntity Entity { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current value of the data binding
|
||||
/// Updates the pending values of this data binding
|
||||
/// </summary>
|
||||
/// <param name="baseValue">The base value of the property the data binding is applied to</param>
|
||||
/// <returns></returns>
|
||||
public TProperty GetValue(TProperty baseValue)
|
||||
public void Update()
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("DataBinding");
|
||||
|
||||
if (Converter == null)
|
||||
return baseValue;
|
||||
if (!IsEnabled)
|
||||
return;
|
||||
|
||||
// TODO: Update the base node
|
||||
|
||||
Script.Run();
|
||||
|
||||
// If no easing is to be applied simple return whatever the current value is
|
||||
if (EasingTime == TimeSpan.Zero || !Converter.SupportsInterpolate)
|
||||
return Script.Result;
|
||||
|
||||
// If the value changed, update the current and previous values used for easing
|
||||
if (!Equals(Script.Result, _currentValue))
|
||||
ResetEasing(Script.Result);
|
||||
|
||||
// Apply interpolation between the previous and current value
|
||||
return GetInterpolatedValue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the type of the target property of this data binding
|
||||
/// Registers a data binding property so that is available to the data binding system
|
||||
/// </summary>
|
||||
public Type? GetTargetType()
|
||||
/// <typeparam name="TProperty">The type of the layer property</typeparam>
|
||||
/// <param name="getter">The function to call to get the value of the property</param>
|
||||
/// <param name="setter">The action to call to set the value of the property</param>
|
||||
/// <param name="displayName">The display name of the data binding property</param>
|
||||
public DataBindingProperty<TProperty> RegisterDataBindingProperty<TProperty>(Func<TProperty> getter, Action<TProperty?> setter, string displayName)
|
||||
{
|
||||
return Registration?.Getter.Method.ReturnType;
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("DataBinding");
|
||||
if (Properties.Any(d => d.DisplayName == displayName))
|
||||
throw new ArtemisCoreException($"A databinding property named '{displayName}' is already registered.");
|
||||
|
||||
DataBindingProperty<TProperty> property = new(getter, setter, displayName);
|
||||
_properties.Add(property);
|
||||
|
||||
OnDataBindingPropertyRegistered();
|
||||
return property;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all data binding properties so they are no longer available to the data binding system
|
||||
/// </summary>
|
||||
public void ClearDataBindingProperties()
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("LayerProperty");
|
||||
|
||||
_properties.Clear();
|
||||
OnDataBindingPropertiesCleared();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -113,111 +110,78 @@ namespace Artemis.Core
|
||||
if (disposing)
|
||||
{
|
||||
_disposed = true;
|
||||
|
||||
if (Registration != null)
|
||||
Registration.DataBinding = null;
|
||||
|
||||
Script.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetEasing(TProperty value)
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DataBindingPropertyRegistered" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDataBindingPropertyRegistered()
|
||||
{
|
||||
_previousValue = GetInterpolatedValue();
|
||||
_currentValue = value;
|
||||
_easingProgress = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
private void ApplyRegistration(DataBindingRegistration<TLayerProperty, TProperty> dataBindingRegistration)
|
||||
{
|
||||
if (dataBindingRegistration == null)
|
||||
throw new ArgumentNullException(nameof(dataBindingRegistration));
|
||||
|
||||
dataBindingRegistration.DataBinding = this;
|
||||
Converter = dataBindingRegistration.Converter;
|
||||
Registration = dataBindingRegistration;
|
||||
|
||||
if (GetTargetType()!.IsValueType)
|
||||
{
|
||||
if (_currentValue == null)
|
||||
_currentValue = default!;
|
||||
if (_previousValue == null)
|
||||
_previousValue = default!;
|
||||
}
|
||||
|
||||
Converter?.Initialize(this);
|
||||
}
|
||||
|
||||
private TProperty GetInterpolatedValue()
|
||||
{
|
||||
if (_easingProgress == EasingTime || Converter == null || !Converter.SupportsInterpolate)
|
||||
return _currentValue;
|
||||
|
||||
double easingAmount = _easingProgress.TotalSeconds / EasingTime.TotalSeconds;
|
||||
return Converter.Interpolate(_previousValue, _currentValue, Easings.Interpolate(easingAmount, EasingFunction));
|
||||
DataBindingPropertyRegistered?.Invoke(this, new DataBindingEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the smoothing progress of the data binding
|
||||
/// Invokes the <see cref="DataBindingDisabled" /> event
|
||||
/// </summary>
|
||||
/// <param name="timeline">The timeline to apply during update</param>
|
||||
public void Update(Timeline timeline)
|
||||
protected virtual void OnDataBindingPropertiesCleared()
|
||||
{
|
||||
// Don't update data bindings if there is no delta, otherwise this creates an inconsistency between
|
||||
// data bindings with easing and data bindings without easing (the ones with easing will seemingly not update)
|
||||
if (timeline.Delta == TimeSpan.Zero || timeline.IsOverridden)
|
||||
return;
|
||||
DataBindingPropertiesCleared?.Invoke(this, new DataBindingEventArgs(this));
|
||||
}
|
||||
|
||||
UpdateWithDelta(timeline.Delta);
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DataBindingEnabled" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDataBindingEnabled(DataBindingEventArgs e)
|
||||
{
|
||||
DataBindingEnabled?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DataBindingDisabled" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDataBindingDisabled(DataBindingEventArgs e)
|
||||
{
|
||||
DataBindingDisabled?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private string GetScriptName()
|
||||
{
|
||||
return LayerProperty.PropertyDescription.Name ?? LayerProperty.Path;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void UpdateWithDelta(TimeSpan delta)
|
||||
public ILayerProperty BaseLayerProperty => LayerProperty;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsEnabled
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("DataBinding");
|
||||
get => _isEnabled;
|
||||
set
|
||||
{
|
||||
_isEnabled = value;
|
||||
|
||||
// Data bindings cannot go back in time like brushes
|
||||
if (delta < TimeSpan.Zero)
|
||||
delta = TimeSpan.Zero;
|
||||
|
||||
_easingProgress = _easingProgress.Add(delta);
|
||||
if (_easingProgress > EasingTime)
|
||||
_easingProgress = EasingTime;
|
||||
|
||||
// Tell Apply() to apply a new value next call
|
||||
_reapplyValue = false;
|
||||
if (_isEnabled)
|
||||
OnDataBindingEnabled(new DataBindingEventArgs(this));
|
||||
else
|
||||
OnDataBindingDisabled(new DataBindingEventArgs(this));
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ReadOnlyCollection<IDataBindingProperty> Properties => _properties.AsReadOnly();
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Apply()
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("DataBinding");
|
||||
|
||||
if (Converter == null)
|
||||
if (!IsEnabled)
|
||||
return;
|
||||
|
||||
// If Update() has not been called, reapply the previous value
|
||||
if (_reapplyValue)
|
||||
{
|
||||
Converter.ApplyValue(_lastAppliedValue);
|
||||
return;
|
||||
}
|
||||
|
||||
TProperty converterValue = Converter.GetValue();
|
||||
TProperty value = GetValue(converterValue);
|
||||
Converter.ApplyValue(value);
|
||||
|
||||
_lastAppliedValue = value;
|
||||
_reapplyValue = true;
|
||||
}
|
||||
|
||||
private string GetScriptName()
|
||||
{
|
||||
if (LayerProperty.GetAllDataBindingRegistrations().Count == 1)
|
||||
return LayerProperty.PropertyDescription.Name ?? LayerProperty.Path;
|
||||
return $"{LayerProperty.PropertyDescription.Name ?? LayerProperty.Path} - {Registration?.DisplayName}";
|
||||
Script.DataBindingExitNode.ApplyToDataBinding();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -227,6 +191,19 @@ namespace Artemis.Core
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<DataBindingEventArgs>? DataBindingPropertyRegistered;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<DataBindingEventArgs>? DataBindingPropertiesCleared;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<DataBindingEventArgs>? DataBindingEnabled;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<DataBindingEventArgs>? DataBindingDisabled;
|
||||
|
||||
|
||||
#region Storage
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -234,14 +211,6 @@ namespace Artemis.Core
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("DataBinding");
|
||||
|
||||
// General
|
||||
DataBindingRegistration<TLayerProperty, TProperty>? registration = LayerProperty.GetDataBindingRegistration<TProperty>(Entity.Identifier);
|
||||
if (registration != null)
|
||||
ApplyRegistration(registration);
|
||||
|
||||
EasingTime = Entity.EasingTime;
|
||||
EasingFunction = (Easings.Functions) Entity.EasingFunction;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -249,8 +218,8 @@ namespace Artemis.Core
|
||||
{
|
||||
Script.Dispose();
|
||||
Script = Entity.NodeScript != null
|
||||
? new NodeScript<TProperty>(GetScriptName(), "The value to put into the data binding", Entity.NodeScript, LayerProperty.ProfileElement.Profile)
|
||||
: new NodeScript<TProperty>(GetScriptName(), "The value to put into the data binding", LayerProperty.ProfileElement.Profile);
|
||||
? new DataBindingNodeScript<TLayerProperty>(GetScriptName(), "The value to put into the data binding", this, Entity.NodeScript, LayerProperty.ProfileElement.Profile)
|
||||
: new DataBindingNodeScript<TLayerProperty>(GetScriptName(), "The value to put into the data binding", this, LayerProperty.ProfileElement.Profile);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -259,17 +228,7 @@ namespace Artemis.Core
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("DataBinding");
|
||||
|
||||
if (!LayerProperty.Entity.DataBindingEntities.Contains(Entity))
|
||||
LayerProperty.Entity.DataBindingEntities.Add(Entity);
|
||||
|
||||
// Don't save an invalid state
|
||||
if (Registration != null)
|
||||
Entity.Identifier = Registration.DisplayName;
|
||||
|
||||
Entity.EasingTime = EasingTime;
|
||||
Entity.EasingFunction = (int) EasingFunction;
|
||||
|
||||
Script?.Save();
|
||||
Script.Save();
|
||||
Entity.NodeScript = Script?.Entity;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a data binding converter that acts as the bridge between a
|
||||
/// <see cref="DataBinding{TLayerProperty, TProperty}" /> and a <see cref="LayerProperty{T}" />
|
||||
/// </summary>
|
||||
public abstract class DataBindingConverter<TLayerProperty, TProperty> : IDataBindingConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the data binding this converter is applied to
|
||||
/// </summary>
|
||||
public DataBinding<TLayerProperty, TProperty>? DataBinding { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether or not this data binding converter supports the <see cref="Sum" /> method
|
||||
/// </summary>
|
||||
public bool SupportsSum { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether or not this data binding converter supports the <see cref="Interpolate" /> method
|
||||
/// </summary>
|
||||
public bool SupportsInterpolate { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the sum of <paramref name="a" /> and <paramref name="b" />
|
||||
/// </summary>
|
||||
public abstract TProperty Sum(TProperty a, TProperty b);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the the interpolated value between <paramref name="a" /> and <paramref name="b" /> on a scale (generally)
|
||||
/// between <c>0.0</c> and <c>1.0</c> defined by the <paramref name="progress" />
|
||||
/// <para>Note: The progress may go be negative or go beyond <c>1.0</c> depending on the easing method used</para>
|
||||
/// </summary>
|
||||
/// <param name="a">The value to interpolate away from</param>
|
||||
/// <param name="b">The value to interpolate towards</param>
|
||||
/// <param name="progress">The progress of the interpolation between 0.0 and 1.0</param>
|
||||
/// <returns></returns>
|
||||
public abstract TProperty Interpolate(TProperty a, TProperty b, double progress);
|
||||
|
||||
/// <summary>
|
||||
/// Applies the <paramref name="value" /> to the layer property
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public virtual void ApplyValue(TProperty value)
|
||||
{
|
||||
if (DataBinding?.Registration == null)
|
||||
throw new ArtemisCoreException("Data binding converter is not yet initialized");
|
||||
DataBinding.Registration.Setter(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current base value of the data binding
|
||||
/// </summary>
|
||||
public virtual TProperty GetValue()
|
||||
{
|
||||
if (DataBinding?.Registration == null)
|
||||
throw new ArtemisCoreException("Data binding converter is not yet initialized");
|
||||
return DataBinding.Registration.Getter();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the provided object to a type of <typeparamref name="TProperty" />
|
||||
/// </summary>
|
||||
public virtual TProperty ConvertFromObject(object? source)
|
||||
{
|
||||
return (TProperty) Convert.ChangeType(source, typeof(TProperty))!;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the data binding converter has been initialized and the <see cref="DataBinding" /> is available
|
||||
/// </summary>
|
||||
protected virtual void OnInitialized()
|
||||
{
|
||||
}
|
||||
|
||||
internal void Initialize(DataBinding<TLayerProperty, TProperty> dataBinding)
|
||||
{
|
||||
if (dataBinding.Registration == null)
|
||||
throw new ArtemisCoreException("Cannot initialize a data binding converter for a data binding without a registration");
|
||||
|
||||
DataBinding = dataBinding;
|
||||
OnInitialized();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Type SupportedType => typeof(TProperty);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class DataBindingProperty<TProperty> : IDataBindingProperty
|
||||
{
|
||||
internal DataBindingProperty(Func<TProperty> getter, Action<TProperty?> setter, string displayName)
|
||||
{
|
||||
Getter = getter ?? throw new ArgumentNullException(nameof(getter));
|
||||
Setter = setter ?? throw new ArgumentNullException(nameof(setter));
|
||||
DisplayName = displayName ?? throw new ArgumentNullException(nameof(displayName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the function to call to get the value of the property
|
||||
/// </summary>
|
||||
public Func<TProperty> Getter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the action to call to set the value of the property
|
||||
/// </summary>
|
||||
public Action<TProperty?> Setter { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string DisplayName { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Type ValueType => typeof(TProperty);
|
||||
|
||||
/// <inheritdoc />
|
||||
public object? GetValue()
|
||||
{
|
||||
return Getter();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SetValue(object? value)
|
||||
{
|
||||
if (value is TProperty match)
|
||||
Setter(match);
|
||||
else
|
||||
throw new ArgumentException("Value must match the type of the data binding registration", nameof(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Artemis.Storage.Entities.Profile.DataBindings;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class DataBindingRegistration<TLayerProperty, TProperty> : IDataBindingRegistration
|
||||
{
|
||||
internal DataBindingRegistration(LayerProperty<TLayerProperty> layerProperty, DataBindingConverter<TLayerProperty, TProperty> converter,
|
||||
Func<TProperty> getter, Action<TProperty> setter, string displayName)
|
||||
{
|
||||
LayerProperty = layerProperty ?? throw new ArgumentNullException(nameof(layerProperty));
|
||||
Converter = converter ?? throw new ArgumentNullException(nameof(converter));
|
||||
Getter = getter ?? throw new ArgumentNullException(nameof(getter));
|
||||
Setter = setter ?? throw new ArgumentNullException(nameof(setter));
|
||||
DisplayName = displayName ?? throw new ArgumentNullException(nameof(displayName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the layer property this registration was made on
|
||||
/// </summary>
|
||||
public LayerProperty<TLayerProperty> LayerProperty { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the converter that's used by the data binding
|
||||
/// </summary>
|
||||
public DataBindingConverter<TLayerProperty, TProperty> Converter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the function to call to get the value of the property
|
||||
/// </summary>
|
||||
public Func<TProperty> Getter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the action to call to set the value of the property
|
||||
/// </summary>
|
||||
public Action<TProperty> Setter { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string DisplayName { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public Type ValueType => typeof(TProperty);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data binding created using this registration
|
||||
/// </summary>
|
||||
public DataBinding<TLayerProperty, TProperty>? DataBinding { get; internal set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public IDataBinding? GetDataBinding()
|
||||
{
|
||||
return DataBinding;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IDataBinding? CreateDataBinding()
|
||||
{
|
||||
if (DataBinding != null)
|
||||
return DataBinding;
|
||||
|
||||
DataBindingEntity? dataBinding = LayerProperty.Entity.DataBindingEntities.FirstOrDefault(e => e.Identifier == DisplayName);
|
||||
if (dataBinding == null)
|
||||
return null;
|
||||
|
||||
DataBinding = new DataBinding<TLayerProperty, TProperty>(LayerProperty, dataBinding);
|
||||
return DataBinding;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ClearDataBinding()
|
||||
{
|
||||
if (DataBinding == null)
|
||||
return;
|
||||
|
||||
// The related entity is left behind, just in case the data binding is added back later
|
||||
LayerProperty.DisableDataBinding(DataBinding);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object? GetValue()
|
||||
{
|
||||
return Getter();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using Artemis.Core.Modules;
|
||||
|
||||
namespace Artemis.Core
|
||||
@@ -7,22 +8,51 @@ namespace Artemis.Core
|
||||
/// 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, IDisposable
|
||||
public interface IDataBinding : IStorageModel, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Updates the smoothing progress of the data binding and recalculates the value next <see cref="Apply" /> call
|
||||
/// Gets the layer property the data binding is applied to
|
||||
/// </summary>
|
||||
/// <param name="delta">The delta to apply during update</param>
|
||||
void UpdateWithDelta(TimeSpan delta);
|
||||
ILayerProperty BaseLayerProperty { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Applies the data binding to the layer property
|
||||
/// Gets a list of sub-properties this data binding applies to
|
||||
/// </summary>
|
||||
ReadOnlyCollection<IDataBindingProperty> Properties { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the data binding is enabled or not
|
||||
/// </summary>
|
||||
bool IsEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Applies the pending value of the data binding to the property
|
||||
/// </summary>
|
||||
void Apply();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// If the data binding is enabled, loads the node script for that data binding
|
||||
/// </summary>
|
||||
void LoadNodeScript();
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a data binding property has been added
|
||||
/// </summary>
|
||||
public event EventHandler<DataBindingEventArgs>? DataBindingPropertyRegistered;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when all data binding properties have been removed
|
||||
/// </summary>
|
||||
public event EventHandler<DataBindingEventArgs>? DataBindingPropertiesCleared;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a data binding has been enabled
|
||||
/// </summary>
|
||||
public event EventHandler<DataBindingEventArgs>? DataBindingEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a data binding has been disabled
|
||||
/// </summary>
|
||||
public event EventHandler<DataBindingEventArgs>? DataBindingDisabled;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a data binding converter that acts as the bridge between a
|
||||
/// <see cref="DataBinding{TLayerProperty, TProperty}" /> and a <see cref="LayerProperty{T}" />
|
||||
/// </summary>
|
||||
public interface IDataBindingConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the type this converter supports
|
||||
/// </summary>
|
||||
public Type SupportedType { get; }
|
||||
}
|
||||
}
|
||||
+8
-18
@@ -5,7 +5,7 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Represents a data binding registration
|
||||
/// </summary>
|
||||
public interface IDataBindingRegistration
|
||||
public interface IDataBindingProperty
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the display name of the data binding registration
|
||||
@@ -18,25 +18,15 @@ namespace Artemis.Core
|
||||
Type ValueType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the data binding applied using this registration
|
||||
/// </summary>
|
||||
public IDataBinding? GetDataBinding();
|
||||
|
||||
/// <summary>
|
||||
/// If found, creates a data binding from storage
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IDataBinding? CreateDataBinding();
|
||||
|
||||
/// <summary>
|
||||
/// If present, removes the current data binding
|
||||
/// </summary>
|
||||
void ClearDataBinding();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the data binding
|
||||
/// Gets the value of the property this registration points to
|
||||
/// </summary>
|
||||
/// <returns>A value matching the type of <see cref="ValueType" /></returns>
|
||||
object? GetValue();
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of the property this registration points to
|
||||
/// </summary>
|
||||
/// <param name="value">A value matching the type of <see cref="ValueType" /></param>
|
||||
void SetValue(object? value);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Artemis.Storage.Entities.Profile;
|
||||
|
||||
namespace Artemis.Core
|
||||
@@ -23,6 +22,21 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
LayerPropertyGroup LayerPropertyGroup { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data binding of this property
|
||||
/// </summary>
|
||||
IDataBinding BaseDataBinding { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the layer has any data binding properties
|
||||
/// </summary>
|
||||
public bool HasDataBinding { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether data bindings are supported on this type of property
|
||||
/// </summary>
|
||||
public bool DataBindingsSupported { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unique path of the property on the layer
|
||||
/// </summary>
|
||||
@@ -47,11 +61,6 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
void Initialize(RenderProfileElement profileElement, LayerPropertyGroup group, PropertyEntity entity, bool fromStorage, PropertyDescriptionAttribute description, string path);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list off all data binding registrations
|
||||
/// </summary>
|
||||
List<IDataBindingRegistration> GetAllDataBindingRegistrations();
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to load and add the provided keyframe entity to the layer property
|
||||
/// </summary>
|
||||
@@ -70,6 +79,12 @@ namespace Artemis.Core
|
||||
/// <param name="timeline">The timeline to apply to the property</param>
|
||||
void Update(Timeline timeline);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Updates just the data binding instead of the entire layer
|
||||
/// </summary>
|
||||
void UpdateDataBinding();
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the layer property is disposed
|
||||
/// </summary>
|
||||
@@ -104,25 +119,5 @@ namespace Artemis.Core
|
||||
/// Occurs when a keyframe was removed from the layer property
|
||||
/// </summary>
|
||||
public event EventHandler<LayerPropertyEventArgs>? KeyframeRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a data binding property has been added
|
||||
/// </summary>
|
||||
public event EventHandler<LayerPropertyEventArgs>? DataBindingPropertyRegistered;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when all data binding properties have been removed
|
||||
/// </summary>
|
||||
public event EventHandler<LayerPropertyEventArgs>? DataBindingPropertiesCleared;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a data binding has been enabled
|
||||
/// </summary>
|
||||
public event EventHandler<LayerPropertyEventArgs>? DataBindingEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a data binding has been disabled
|
||||
/// </summary>
|
||||
public event EventHandler<LayerPropertyEventArgs>? DataBindingDisabled;
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ namespace Artemis.Core
|
||||
Path = null!;
|
||||
Entity = null!;
|
||||
PropertyDescription = null!;
|
||||
DataBinding = null!;
|
||||
|
||||
CurrentValue = default!;
|
||||
DefaultValue = default!;
|
||||
@@ -57,93 +58,10 @@ namespace Artemis.Core
|
||||
{
|
||||
_disposed = true;
|
||||
|
||||
foreach (IDataBinding dataBinding in _dataBindings)
|
||||
dataBinding.Dispose();
|
||||
|
||||
DataBinding.Dispose();
|
||||
Disposed?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="Updated" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnUpdated()
|
||||
{
|
||||
Updated?.Invoke(this, new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="CurrentValueSet" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnCurrentValueSet()
|
||||
{
|
||||
CurrentValueSet?.Invoke(this, new LayerPropertyEventArgs(this));
|
||||
LayerPropertyGroup.OnLayerPropertyOnCurrentValueSet(new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="VisibilityChanged" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnVisibilityChanged()
|
||||
{
|
||||
VisibilityChanged?.Invoke(this, new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="KeyframesToggled" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnKeyframesToggled()
|
||||
{
|
||||
KeyframesToggled?.Invoke(this, new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="KeyframeAdded" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnKeyframeAdded()
|
||||
{
|
||||
KeyframeAdded?.Invoke(this, new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="KeyframeRemoved" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnKeyframeRemoved()
|
||||
{
|
||||
KeyframeRemoved?.Invoke(this, new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DataBindingPropertyRegistered" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDataBindingPropertyRegistered()
|
||||
{
|
||||
DataBindingPropertyRegistered?.Invoke(this, new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DataBindingDisabled" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDataBindingPropertiesCleared()
|
||||
{
|
||||
DataBindingPropertiesCleared?.Invoke(this, new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DataBindingEnabled" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDataBindingEnabled(LayerPropertyEventArgs e)
|
||||
{
|
||||
DataBindingEnabled?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DataBindingDisabled" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDataBindingDisabled(LayerPropertyEventArgs e)
|
||||
{
|
||||
DataBindingDisabled?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public PropertyDescriptionAttribute PropertyDescription { get; internal set; }
|
||||
|
||||
@@ -162,7 +80,16 @@ namespace Artemis.Core
|
||||
CurrentValue = BaseValue;
|
||||
|
||||
UpdateKeyframes(timeline);
|
||||
UpdateDataBindings(timeline);
|
||||
UpdateDataBinding();
|
||||
|
||||
// UpdateDataBinding called OnUpdated()
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void UpdateDataBinding()
|
||||
{
|
||||
DataBinding.Update();
|
||||
DataBinding.Apply();
|
||||
|
||||
OnUpdated();
|
||||
}
|
||||
@@ -174,39 +101,6 @@ namespace Artemis.Core
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler? Disposed;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? Updated;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? CurrentValueSet;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? VisibilityChanged;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? KeyframesToggled;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? KeyframeAdded;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? KeyframeRemoved;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? DataBindingPropertyRegistered;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? DataBindingPropertiesCleared;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? DataBindingEnabled;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? DataBindingDisabled;
|
||||
|
||||
#region Hierarchy
|
||||
|
||||
private bool _isHidden;
|
||||
@@ -480,137 +374,19 @@ namespace Artemis.Core
|
||||
|
||||
#region Data bindings
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
internal readonly List<IDataBindingRegistration> _dataBindingRegistrations = new();
|
||||
|
||||
internal readonly List<IDataBinding> _dataBindings = new();
|
||||
// ReSharper restore InconsistentNaming
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether data bindings are supported on this type of property
|
||||
/// Gets the data binding of this property
|
||||
/// </summary>
|
||||
public bool DataBindingsSupported { get; protected internal set; } = true;
|
||||
public DataBinding<T> DataBinding { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether the layer has any active data bindings
|
||||
/// </summary>
|
||||
public bool HasDataBinding => GetAllDataBindingRegistrations().Any(r => r.GetDataBinding() != null);
|
||||
/// <inheritdoc />
|
||||
public bool DataBindingsSupported => DataBinding.Properties.Any();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a data binding registration by the display name used to register it
|
||||
/// <para>Note: The expression must exactly match the one used to register the data binding</para>
|
||||
/// </summary>
|
||||
public DataBindingRegistration<T, TProperty>? GetDataBindingRegistration<TProperty>(string identifier)
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("LayerProperty");
|
||||
/// <inheritdoc />
|
||||
public IDataBinding BaseDataBinding => DataBinding;
|
||||
|
||||
IDataBindingRegistration? match = _dataBindingRegistrations.FirstOrDefault(r => r is DataBindingRegistration<T, TProperty> registration &&
|
||||
registration.DisplayName == identifier);
|
||||
return (DataBindingRegistration<T, TProperty>?) match;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list containing all data binding registrations of this layer property
|
||||
/// </summary>
|
||||
/// <returns>A list containing all data binding registrations of this layer property</returns>
|
||||
public List<IDataBindingRegistration> GetAllDataBindingRegistrations()
|
||||
{
|
||||
return _dataBindingRegistrations;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a data binding property so that is available to the data binding system
|
||||
/// </summary>
|
||||
/// <typeparam name="TProperty">The type of the layer property</typeparam>
|
||||
/// <param name="getter">The function to call to get the value of the property</param>
|
||||
/// <param name="setter">The action to call to set the value of the property</param>
|
||||
/// <param name="converter">The converter to use while applying the data binding</param>
|
||||
/// <param name="displayName">The display name of the data binding property</param>
|
||||
public DataBindingRegistration<T, TProperty> RegisterDataBindingProperty<TProperty>(Func<TProperty> getter, Action<TProperty> setter, DataBindingConverter<T, TProperty> converter,
|
||||
string displayName)
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("LayerProperty");
|
||||
if (_dataBindingRegistrations.Any(d => d.DisplayName == displayName))
|
||||
throw new ArtemisCoreException($"A databinding property named '{displayName}' is already registered.");
|
||||
|
||||
DataBindingRegistration<T, TProperty> registration = new(this, converter, getter, setter, displayName);
|
||||
_dataBindingRegistrations.Add(registration);
|
||||
|
||||
// If not yet initialized, load the data binding related to the registration if available
|
||||
if (_isInitialized)
|
||||
{
|
||||
IDataBinding? dataBinding = registration.CreateDataBinding();
|
||||
if (dataBinding != null)
|
||||
_dataBindings.Add(dataBinding);
|
||||
}
|
||||
|
||||
OnDataBindingPropertyRegistered();
|
||||
return registration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all data binding properties so they are no longer available to the data binding system
|
||||
/// </summary>
|
||||
public void ClearDataBindingProperties()
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("LayerProperty");
|
||||
|
||||
foreach (IDataBindingRegistration dataBindingRegistration in _dataBindingRegistrations)
|
||||
dataBindingRegistration.ClearDataBinding();
|
||||
_dataBindingRegistrations.Clear();
|
||||
|
||||
OnDataBindingPropertiesCleared();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables a data binding for the provided <paramref name="dataBindingRegistration" />
|
||||
/// </summary>
|
||||
/// <returns>The newly created data binding</returns>
|
||||
public DataBinding<T, TProperty> EnableDataBinding<TProperty>(DataBindingRegistration<T, TProperty> dataBindingRegistration)
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("LayerProperty");
|
||||
|
||||
if (dataBindingRegistration.LayerProperty != this)
|
||||
throw new ArtemisCoreException("Cannot enable a data binding using a data binding registration of a different layer property");
|
||||
if (dataBindingRegistration.DataBinding != null)
|
||||
throw new ArtemisCoreException("Provided data binding registration already has an enabled data binding");
|
||||
|
||||
DataBinding<T, TProperty> dataBinding = new(dataBindingRegistration);
|
||||
_dataBindings.Add(dataBinding);
|
||||
|
||||
OnDataBindingEnabled(new LayerPropertyEventArgs(dataBinding.LayerProperty));
|
||||
return dataBinding;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables the provided data binding
|
||||
/// </summary>
|
||||
/// <param name="dataBinding">The data binding to remove</param>
|
||||
public void DisableDataBinding<TProperty>(DataBinding<T, TProperty> dataBinding)
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("LayerProperty");
|
||||
|
||||
_dataBindings.Remove(dataBinding);
|
||||
|
||||
if (dataBinding.Registration != null)
|
||||
dataBinding.Registration.DataBinding = null;
|
||||
dataBinding.Dispose();
|
||||
OnDataBindingDisabled(new LayerPropertyEventArgs(dataBinding.LayerProperty));
|
||||
}
|
||||
|
||||
private void UpdateDataBindings(Timeline timeline)
|
||||
{
|
||||
foreach (IDataBinding dataBinding in _dataBindings)
|
||||
{
|
||||
dataBinding.Update(timeline);
|
||||
dataBinding.Apply();
|
||||
}
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public bool HasDataBinding => DataBinding.IsEnabled;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -694,6 +470,7 @@ namespace Artemis.Core
|
||||
Entity = entity ?? throw new ArgumentNullException(nameof(entity));
|
||||
PropertyDescription = description ?? throw new ArgumentNullException(nameof(description));
|
||||
IsLoadedFromStorage = fromStorage;
|
||||
DataBinding = new DataBinding<T>(this);
|
||||
|
||||
if (PropertyDescription.DisableKeyframes)
|
||||
KeyframesSupported = false;
|
||||
@@ -737,13 +514,7 @@ namespace Artemis.Core
|
||||
// ignored for now
|
||||
}
|
||||
|
||||
_dataBindings.Clear();
|
||||
foreach (IDataBindingRegistration dataBindingRegistration in _dataBindingRegistrations)
|
||||
{
|
||||
IDataBinding? dataBinding = dataBindingRegistration.CreateDataBinding();
|
||||
if (dataBinding != null)
|
||||
_dataBindings.Add(dataBinding);
|
||||
}
|
||||
DataBinding.Load();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -762,9 +533,8 @@ namespace Artemis.Core
|
||||
Entity.KeyframeEntities.Clear();
|
||||
Entity.KeyframeEntities.AddRange(Keyframes.Select(k => k.GetKeyframeEntity()));
|
||||
|
||||
Entity.DataBindingEntities.Clear();
|
||||
foreach (IDataBinding dataBinding in _dataBindings)
|
||||
dataBinding.Save();
|
||||
DataBinding.Save();
|
||||
Entity.DataBinding = DataBinding.Entity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -775,5 +545,79 @@ namespace Artemis.Core
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler? Disposed;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? Updated;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? CurrentValueSet;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? VisibilityChanged;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? KeyframesToggled;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? KeyframeAdded;
|
||||
|
||||
/// <inheritdoc />
|
||||
public event EventHandler<LayerPropertyEventArgs>? KeyframeRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="Updated" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnUpdated()
|
||||
{
|
||||
Updated?.Invoke(this, new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="CurrentValueSet" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnCurrentValueSet()
|
||||
{
|
||||
CurrentValueSet?.Invoke(this, new LayerPropertyEventArgs(this));
|
||||
LayerPropertyGroup.OnLayerPropertyOnCurrentValueSet(new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="VisibilityChanged" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnVisibilityChanged()
|
||||
{
|
||||
VisibilityChanged?.Invoke(this, new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="KeyframesToggled" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnKeyframesToggled()
|
||||
{
|
||||
KeyframesToggled?.Invoke(this, new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="KeyframeAdded" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnKeyframeAdded()
|
||||
{
|
||||
KeyframeAdded?.Invoke(this, new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="KeyframeRemoved" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnKeyframeRemoved()
|
||||
{
|
||||
KeyframeRemoved?.Invoke(this, new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -113,11 +113,8 @@ namespace Artemis.Core
|
||||
? new NodeScript<bool>($"Activate {_typeDisplayName}", $"Whether or not this {_typeDisplayName} should be active", RenderElementEntity.NodeScript, Profile)
|
||||
: new NodeScript<bool>($"Activate {_typeDisplayName}", $"Whether or not this {_typeDisplayName} should be active", Profile);
|
||||
|
||||
foreach (ILayerProperty layerProperty in GetAllLayerProperties())
|
||||
{
|
||||
foreach (IDataBindingRegistration dataBindingRegistration in layerProperty.GetAllDataBindingRegistrations())
|
||||
dataBindingRegistration.GetDataBinding()?.LoadNodeScript();
|
||||
}
|
||||
foreach (ILayerProperty layerProperty in GetAllLayerProperties())
|
||||
layerProperty.BaseDataBinding.LoadNodeScript();
|
||||
}
|
||||
|
||||
internal void OnLayerEffectsUpdated()
|
||||
|
||||
Reference in new issue
Block a user