mirror of
https://github.com/Artemis-RGB/Artemis
synced 2026-11-12 03:48:56 +00:00
Core - Added XML comments to all remaining public members/methods
Core - Refactored a lot of code for nullable reference types
This commit is contained in:
1 parent
61fc96742d
commit
a3cd32f6c4
107 files changed
+1150
-649
No files matched your search
+9
-6
@@ -2,27 +2,30 @@
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a description attribute used to decorate layer properties
|
||||
/// </summary>
|
||||
public class PropertyDescriptionAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// The user-friendly name for this property, shown in the UI
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The user-friendly description for this property, shown in the UI
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
public string? Description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Input prefix to show before input elements in the UI
|
||||
/// </summary>
|
||||
public string InputPrefix { get; set; }
|
||||
public string? InputPrefix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Input affix to show behind input elements in the UI
|
||||
/// </summary>
|
||||
public string InputAffix { get; set; }
|
||||
public string? InputAffix { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The input drag step size, used in the UI
|
||||
@@ -32,12 +35,12 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Minimum input value, only enforced in the UI
|
||||
/// </summary>
|
||||
public object MinInputValue { get; set; }
|
||||
public object? MinInputValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Maximum input value, only enforced in the UI
|
||||
/// </summary>
|
||||
public object MaxInputValue { get; set; }
|
||||
public object? MaxInputValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not keyframes are always disabled
|
||||
|
||||
+5
-2
@@ -2,16 +2,19 @@
|
||||
|
||||
namespace Artemis.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a description attribute used to decorate layer property groups
|
||||
/// </summary>
|
||||
public class PropertyGroupDescriptionAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// The user-friendly name for this property, shown in the UI.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The user-friendly description for this property, shown in the UI.
|
||||
/// </summary>
|
||||
public string Description { get; set; }
|
||||
public string? Description { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -25,9 +25,22 @@ namespace Artemis.Core
|
||||
/// </summary>
|
||||
protected LayerProperty()
|
||||
{
|
||||
// Cant define generic types as nullable ¯\_(ツ)_/¯
|
||||
CurrentValue = default!;
|
||||
DefaultValue = default!;
|
||||
|
||||
_baseValue = default!;
|
||||
_keyframes = new List<LayerPropertyKeyframe<T>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the type of the property
|
||||
/// </summary>
|
||||
public Type GetPropertyType()
|
||||
{
|
||||
return typeof(T);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public PropertyDescriptionAttribute PropertyDescription { get; internal set; }
|
||||
|
||||
@@ -57,14 +70,6 @@ namespace Artemis.Core
|
||||
dataBinding.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the type of the property
|
||||
/// </summary>
|
||||
public Type GetPropertyType()
|
||||
{
|
||||
return typeof(T);
|
||||
}
|
||||
|
||||
#region Hierarchy
|
||||
|
||||
private bool _isHidden;
|
||||
@@ -150,11 +155,13 @@ namespace Artemis.Core
|
||||
throw new ObjectDisposedException("LayerProperty");
|
||||
|
||||
if (time == null || !KeyframesEnabled || !KeyframesSupported)
|
||||
{
|
||||
BaseValue = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If on a keyframe, update the keyframe
|
||||
LayerPropertyKeyframe<T> currentKeyframe = Keyframes.FirstOrDefault(k => k.Position == time.Value);
|
||||
LayerPropertyKeyframe<T>? currentKeyframe = Keyframes.FirstOrDefault(k => k.Position == time.Value);
|
||||
// Create a new keyframe if none found
|
||||
if (currentKeyframe == null)
|
||||
AddKeyframe(new LayerPropertyKeyframe<T>(value, time.Value, Easings.Functions.Linear, this));
|
||||
@@ -222,12 +229,12 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Gets the current keyframe in the timeline according to the current progress
|
||||
/// </summary>
|
||||
public LayerPropertyKeyframe<T> CurrentKeyframe { get; protected set; }
|
||||
public LayerPropertyKeyframe<T>? CurrentKeyframe { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next keyframe in the timeline according to the current progress
|
||||
/// </summary>
|
||||
public LayerPropertyKeyframe<T> NextKeyframe { get; protected set; }
|
||||
public LayerPropertyKeyframe<T>? NextKeyframe { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds a keyframe to the layer property
|
||||
@@ -249,26 +256,6 @@ namespace Artemis.Core
|
||||
OnKeyframeAdded();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a keyframe from the layer property
|
||||
/// </summary>
|
||||
/// <param name="keyframe">The keyframe to remove</param>
|
||||
public LayerPropertyKeyframe<T> CopyKeyframe(LayerPropertyKeyframe<T> keyframe)
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("LayerProperty");
|
||||
|
||||
LayerPropertyKeyframe<T> newKeyframe = new LayerPropertyKeyframe<T>(
|
||||
keyframe.Value,
|
||||
keyframe.Position,
|
||||
keyframe.EasingFunction,
|
||||
keyframe.LayerProperty
|
||||
);
|
||||
AddKeyframe(newKeyframe);
|
||||
|
||||
return newKeyframe;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a keyframe from the layer property
|
||||
/// </summary>
|
||||
@@ -282,7 +269,6 @@ namespace Artemis.Core
|
||||
return;
|
||||
|
||||
_keyframes.Remove(keyframe);
|
||||
keyframe.LayerProperty = null;
|
||||
SortKeyframes();
|
||||
OnKeyframeRemoved();
|
||||
}
|
||||
@@ -303,14 +289,25 @@ namespace Artemis.Core
|
||||
// The current keyframe is the last keyframe before the current time
|
||||
CurrentKeyframe = _keyframes.LastOrDefault(k => k.Position <= timeline.Position);
|
||||
// Keyframes are sorted by position so we can safely assume the next keyframe's position is after the current
|
||||
int nextIndex = _keyframes.IndexOf(CurrentKeyframe) + 1;
|
||||
NextKeyframe = _keyframes.Count > nextIndex ? _keyframes[nextIndex] : null;
|
||||
if (CurrentKeyframe != null)
|
||||
{
|
||||
int nextIndex = _keyframes.IndexOf(CurrentKeyframe) + 1;
|
||||
NextKeyframe = _keyframes.Count > nextIndex ? _keyframes[nextIndex] : null;
|
||||
}
|
||||
else
|
||||
{
|
||||
NextKeyframe = null;
|
||||
}
|
||||
|
||||
// No need to update the current value if either of the keyframes are null
|
||||
if (CurrentKeyframe == null)
|
||||
{
|
||||
CurrentValue = _keyframes.Any() ? _keyframes[0].Value : BaseValue;
|
||||
}
|
||||
else if (NextKeyframe == null)
|
||||
{
|
||||
CurrentValue = CurrentKeyframe.Value;
|
||||
}
|
||||
// Only determine progress and current value if both keyframes are present
|
||||
else
|
||||
{
|
||||
@@ -325,8 +322,11 @@ namespace Artemis.Core
|
||||
|
||||
#region Data bindings
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
internal readonly List<IDataBindingRegistration> _dataBindingRegistrations = new List<IDataBindingRegistration>();
|
||||
|
||||
internal readonly List<IDataBinding> _dataBindings = new List<IDataBinding>();
|
||||
// ReSharper restore InconsistentNaming
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether data bindings are supported on this type of property
|
||||
@@ -342,27 +342,36 @@ namespace Artemis.Core
|
||||
/// Gets a data binding registration by the expression 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>(Expression<Func<T, TProperty>> propertyExpression)
|
||||
public DataBindingRegistration<T, TProperty>? GetDataBindingRegistration<TProperty>(Expression<Func<T, TProperty>> propertyExpression)
|
||||
{
|
||||
return GetDataBindingRegistration<TProperty>(propertyExpression.ToString());
|
||||
}
|
||||
|
||||
public DataBindingRegistration<T, TProperty> GetDataBindingRegistration<TProperty>(string expression)
|
||||
internal DataBindingRegistration<T, TProperty>? GetDataBindingRegistration<TProperty>(string expression)
|
||||
{
|
||||
if (_disposed)
|
||||
throw new ObjectDisposedException("LayerProperty");
|
||||
|
||||
IDataBindingRegistration match = _dataBindingRegistrations.FirstOrDefault(r => r is DataBindingRegistration<T, TProperty> registration &&
|
||||
registration.PropertyExpression.ToString() == expression);
|
||||
|
||||
return (DataBindingRegistration<T, TProperty>) match;
|
||||
IDataBindingRegistration? match = _dataBindingRegistrations.FirstOrDefault(r => r is DataBindingRegistration<T, TProperty> registration &&
|
||||
registration.PropertyExpression.ToString() == expression);
|
||||
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="propertyExpression">The expression pointing to the value to register</param>
|
||||
/// <param name="converter">The converter to use while applying the data binding</param>
|
||||
public void RegisterDataBindingProperty<TProperty>(Expression<Func<T, TProperty>> propertyExpression, DataBindingConverter<T, TProperty> converter)
|
||||
{
|
||||
if (_disposed)
|
||||
@@ -372,10 +381,8 @@ namespace Artemis.Core
|
||||
throw new ArtemisCoreException("Provided expression is invalid, it must be 'value => value' or 'value => value.Property'");
|
||||
|
||||
if (converter.SupportedType != propertyExpression.ReturnType)
|
||||
{
|
||||
throw new ArtemisCoreException($"Cannot register data binding property for property {PropertyDescription.Name} " +
|
||||
"because the provided converter does not support the property's type");
|
||||
}
|
||||
|
||||
_dataBindingRegistrations.Add(new DataBindingRegistration<T, TProperty>(this, converter, propertyExpression));
|
||||
}
|
||||
@@ -412,7 +419,8 @@ namespace Artemis.Core
|
||||
|
||||
_dataBindings.Remove(dataBinding);
|
||||
|
||||
dataBinding.Registration.DataBinding = null;
|
||||
if (dataBinding.Registration != null)
|
||||
dataBinding.Registration.DataBinding = null;
|
||||
dataBinding.Dispose();
|
||||
OnDataBindingDisabled(new LayerPropertyEventArgs<T>(dataBinding.LayerProperty));
|
||||
}
|
||||
@@ -471,17 +479,15 @@ namespace Artemis.Core
|
||||
if (!IsLoadedFromStorage)
|
||||
ApplyDefaultValue();
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Entity.Value != null)
|
||||
BaseValue = JsonConvert.DeserializeObject<T>(Entity.Value);
|
||||
}
|
||||
catch (JsonException e)
|
||||
catch (JsonException)
|
||||
{
|
||||
// ignored for now
|
||||
}
|
||||
}
|
||||
|
||||
CurrentValue = BaseValue;
|
||||
KeyframesEnabled = Entity.KeyframesEnabled;
|
||||
@@ -494,7 +500,7 @@ namespace Artemis.Core
|
||||
.Select(k => new LayerPropertyKeyframe<T>(JsonConvert.DeserializeObject<T>(k.Value), k.Position, (Easings.Functions) k.EasingFunction, this))
|
||||
);
|
||||
}
|
||||
catch (JsonException e)
|
||||
catch (JsonException)
|
||||
{
|
||||
// ignored for now
|
||||
}
|
||||
@@ -502,15 +508,14 @@ namespace Artemis.Core
|
||||
_dataBindings.Clear();
|
||||
foreach (IDataBindingRegistration dataBindingRegistration in _dataBindingRegistrations)
|
||||
{
|
||||
IDataBinding dataBinding = dataBindingRegistration.CreateDataBinding();
|
||||
IDataBinding? dataBinding = dataBindingRegistration.CreateDataBinding();
|
||||
if (dataBinding != null)
|
||||
_dataBindings.Add(dataBinding);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the property to the underlying property entity that was configured when calling
|
||||
/// <see cref="ApplyToLayerProperty" />
|
||||
/// Saves the property to the underlying property entity
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
@@ -542,79 +547,103 @@ namespace Artemis.Core
|
||||
/// <summary>
|
||||
/// Occurs once every frame when the layer property is updated
|
||||
/// </summary>
|
||||
public event EventHandler<LayerPropertyEventArgs<T>> Updated;
|
||||
public event EventHandler<LayerPropertyEventArgs<T>>? Updated;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the current value of the layer property was updated by some form of input
|
||||
/// </summary>
|
||||
public event EventHandler<LayerPropertyEventArgs<T>> CurrentValueSet;
|
||||
public event EventHandler<LayerPropertyEventArgs<T>>? CurrentValueSet;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when the <see cref="IsHidden" /> value of the layer property was updated
|
||||
/// </summary>
|
||||
public event EventHandler<LayerPropertyEventArgs<T>> VisibilityChanged;
|
||||
public event EventHandler<LayerPropertyEventArgs<T>>? VisibilityChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when keyframes are enabled/disabled
|
||||
/// </summary>
|
||||
public event EventHandler<LayerPropertyEventArgs<T>> KeyframesToggled;
|
||||
public event EventHandler<LayerPropertyEventArgs<T>>? KeyframesToggled;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a new keyframe was added to the layer property
|
||||
/// </summary>
|
||||
public event EventHandler<LayerPropertyEventArgs<T>> KeyframeAdded;
|
||||
public event EventHandler<LayerPropertyEventArgs<T>>? KeyframeAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a keyframe was removed from the layer property
|
||||
/// </summary>
|
||||
public event EventHandler<LayerPropertyEventArgs<T>> KeyframeRemoved;
|
||||
public event EventHandler<LayerPropertyEventArgs<T>>? KeyframeRemoved;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a data binding has been enabled
|
||||
/// </summary>
|
||||
public event EventHandler<LayerPropertyEventArgs<T>> DataBindingEnabled;
|
||||
public event EventHandler<LayerPropertyEventArgs<T>>? DataBindingEnabled;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a data binding has been disabled
|
||||
/// </summary>
|
||||
public event EventHandler<LayerPropertyEventArgs<T>> DataBindingDisabled;
|
||||
public event EventHandler<LayerPropertyEventArgs<T>>? DataBindingDisabled;
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="Updated" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnUpdated()
|
||||
{
|
||||
Updated?.Invoke(this, new LayerPropertyEventArgs<T>(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="CurrentValueSet" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnCurrentValueSet()
|
||||
{
|
||||
CurrentValueSet?.Invoke(this, new LayerPropertyEventArgs<T>(this));
|
||||
LayerPropertyGroup.OnLayerPropertyOnCurrentValueSet(new LayerPropertyEventArgs(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="VisibilityChanged" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnVisibilityChanged()
|
||||
{
|
||||
VisibilityChanged?.Invoke(this, new LayerPropertyEventArgs<T>(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="KeyframesToggled" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnKeyframesToggled()
|
||||
{
|
||||
KeyframesToggled?.Invoke(this, new LayerPropertyEventArgs<T>(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="KeyframeAdded" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnKeyframeAdded()
|
||||
{
|
||||
KeyframeAdded?.Invoke(this, new LayerPropertyEventArgs<T>(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="KeyframeRemoved" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnKeyframeRemoved()
|
||||
{
|
||||
KeyframeRemoved?.Invoke(this, new LayerPropertyEventArgs<T>(this));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DataBindingEnabled" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDataBindingEnabled(LayerPropertyEventArgs<T> e)
|
||||
{
|
||||
DataBindingEnabled?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes the <see cref="DataBindingDisabled" /> event
|
||||
/// </summary>
|
||||
protected virtual void OnDataBindingDisabled(LayerPropertyEventArgs<T> e)
|
||||
{
|
||||
DataBindingDisabled?.Invoke(this, e);
|
||||
|
||||
@@ -21,9 +21,9 @@ namespace Artemis.Core
|
||||
public LayerPropertyKeyframe(T value, TimeSpan position, Easings.Functions easingFunction, LayerProperty<T> layerProperty)
|
||||
{
|
||||
_position = position;
|
||||
_layerProperty = layerProperty;
|
||||
_value = value;
|
||||
|
||||
Value = value;
|
||||
LayerProperty = layerProperty;
|
||||
EasingFunction = easingFunction;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user