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:
Robert committed 2020-11-16 20:16:06 +01:00
1 parent 61fc96742d
commit a3cd32f6c4
107 files changed
+1150 -649

No files matched your search

@@ -6,10 +6,10 @@ namespace Artemis.Core
/// <inheritdoc />
public class DataBinding<TLayerProperty, TProperty> : IDataBinding
{
private TProperty _currentValue;
private TProperty _currentValue = default!;
private TProperty _previousValue = default!;
private bool _disposed;
private TimeSpan _easingProgress;
private TProperty _previousValue;
internal DataBinding(DataBindingRegistration<TLayerProperty, TProperty> dataBindingRegistration)
{
@@ -34,7 +34,7 @@ namespace Artemis.Core
/// <summary>
/// Gets the data binding registration this data binding is based upon
/// </summary>
public DataBindingRegistration<TLayerProperty, TProperty> Registration { get; private set; }
public DataBindingRegistration<TLayerProperty, TProperty>? Registration { get; private set; }
/// <summary>
/// Gets the layer property this data binding targets
@@ -44,12 +44,12 @@ namespace Artemis.Core
/// <summary>
/// Gets the converter used to apply this data binding to the <see cref="LayerProperty" />
/// </summary>
public DataBindingConverter<TLayerProperty, TProperty> Converter { get; private set; }
public DataBindingConverter<TLayerProperty, TProperty>? Converter { get; private set; }
/// <summary>
/// Gets the data binding mode
/// </summary>
public IDataBindingMode<TLayerProperty, TProperty> DataBindingMode { get; private set; }
public IDataBindingMode<TLayerProperty, TProperty>? DataBindingMode { get; private set; }
/// <summary>
/// Gets or sets the easing time of the data binding
@@ -93,9 +93,9 @@ namespace Artemis.Core
/// <summary>
/// Returns the type of the target property of this data binding
/// </summary>
public Type GetTargetType()
public Type? GetTargetType()
{
return Registration.PropertyExpression.ReturnType;
return Registration?.PropertyExpression.ReturnType;
}
private void ResetEasing(TProperty value)
@@ -111,15 +111,15 @@ namespace Artemis.Core
throw new ArgumentNullException(nameof(dataBindingRegistration));
dataBindingRegistration.DataBinding = this;
Converter = dataBindingRegistration?.Converter;
Converter = dataBindingRegistration.Converter;
Registration = dataBindingRegistration;
if (GetTargetType().IsValueType)
if (GetTargetType()!.IsValueType)
{
if (_currentValue == null)
_currentValue = default;
_currentValue = default!;
if (_previousValue == null)
_previousValue = default;
_previousValue = default!;
}
Converter?.Initialize(this);
@@ -127,7 +127,7 @@ namespace Artemis.Core
private TProperty GetInterpolatedValue()
{
if (_easingProgress == EasingTime || !Converter.SupportsInterpolate)
if (_easingProgress == EasingTime || Converter == null || !Converter.SupportsInterpolate)
return _currentValue;
double easingAmount = _easingProgress.TotalSeconds / EasingTime.TotalSeconds;
@@ -180,7 +180,8 @@ namespace Artemis.Core
{
_disposed = true;
Registration.DataBinding = null;
if (Registration != null)
Registration.DataBinding = null;
DataBindingMode?.Dispose();
}
@@ -234,7 +235,7 @@ namespace Artemis.Core
throw new ObjectDisposedException("DataBinding");
// General
DataBindingRegistration<TLayerProperty, TProperty> registration = LayerProperty.GetDataBindingRegistration<TProperty>(Entity.TargetExpression);
DataBindingRegistration<TLayerProperty, TProperty>? registration = LayerProperty.GetDataBindingRegistration<TProperty>(Entity.TargetExpression);
if (registration != null)
ApplyRegistration(registration);
@@ -253,8 +254,10 @@ namespace Artemis.Core
if (!LayerProperty.Entity.DataBindingEntities.Contains(Entity))
LayerProperty.Entity.DataBindingEntities.Add(Entity);
// General
Entity.TargetExpression = Registration.PropertyExpression.ToString();
// Don't save an invalid state
if (Registration != null)
Entity.TargetExpression = Registration.PropertyExpression.ToString();
Entity.EasingTime = EasingTime;
Entity.EasingFunction = (int) EasingFunction;
@@ -13,22 +13,22 @@ namespace Artemis.Core
/// <summary>
/// Gets a dynamically compiled getter pointing to the data bound property
/// </summary>
public Func<TLayerProperty, TProperty> GetExpression { get; private set; }
public Func<TLayerProperty, TProperty>? GetExpression { get; private set; }
/// <summary>
/// Gets a dynamically compiled setter pointing to the data bound property used for value types
/// </summary>
public Action<TProperty> ValueTypeSetExpression { get; private set; }
public Action<TProperty>? ValueTypeSetExpression { get; private set; }
/// <summary>
/// Gets a dynamically compiled setter pointing to the data bound property used for reference types
/// </summary>
public Action<TLayerProperty, TProperty> ReferenceTypeSetExpression { get; private set; }
public Action<TLayerProperty, TProperty>? ReferenceTypeSetExpression { get; private set; }
/// <summary>
/// Gets the data binding this converter is applied to
/// </summary>
public DataBinding<TLayerProperty, TProperty> DataBinding { get; private set; }
public DataBinding<TLayerProperty, TProperty>? DataBinding { get; private set; }
/// <summary>
/// Gets whether or not this data binding converter supports the <see cref="Sum" /> method
@@ -65,6 +65,8 @@ namespace Artemis.Core
/// <param name="value"></param>
public virtual void ApplyValue(TProperty value)
{
if (DataBinding == null)
throw new ArtemisCoreException("Data binding converter is not yet initialized");
if (ReferenceTypeSetExpression != null)
ReferenceTypeSetExpression(DataBinding.LayerProperty.CurrentValue, value);
else if (ValueTypeSetExpression != null)
@@ -76,6 +78,8 @@ namespace Artemis.Core
/// </summary>
public virtual TProperty GetValue()
{
if (DataBinding == null || GetExpression == null)
throw new ArtemisCoreException("Data binding converter is not yet initialized");
return GetExpression(DataBinding.LayerProperty.CurrentValue);
}
@@ -84,7 +88,7 @@ namespace Artemis.Core
/// </summary>
public virtual TProperty ConvertFromObject(object? source)
{
return (TProperty) Convert.ChangeType(source, typeof(TProperty));
return (TProperty) Convert.ChangeType(source, typeof(TProperty))!;
}
/// <summary>
@@ -96,6 +100,9 @@ namespace Artemis.Core
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;
GetExpression = dataBinding.Registration.PropertyExpression.Compile();
CreateSetExpression();
@@ -106,14 +113,14 @@ namespace Artemis.Core
private void CreateSetExpression()
{
// If the registration does not point towards a member of LayerProperty<T>.CurrentValue, assign directly to LayerProperty<T>.CurrentValue
if (DataBinding.Registration.Member == null)
if (DataBinding!.Registration?.Member == null)
{
CreateSetCurrentValueExpression();
return;
}
// Ensure the member of LayerProperty<T>.CurrentValue has a setter
MethodInfo setterMethod = null;
MethodInfo? setterMethod = null;
if (DataBinding.Registration.Member is PropertyInfo propertyInfo)
setterMethod = propertyInfo.GetSetMethod();
// If there is no setter, the built-in data binding cannot do its job, stay null
@@ -130,6 +137,9 @@ namespace Artemis.Core
private void CreateSetReferenceTypeExpression()
{
if (DataBinding!.Registration?.Member == null)
throw new ArtemisCoreException("Cannot create value setter for data binding without a registration");
ParameterExpression propertyValue = Expression.Parameter(typeof(TProperty), "propertyValue");
ParameterExpression parameter = Expression.Parameter(typeof(TLayerProperty), "currentValue");
MemberExpression memberAccess = Expression.MakeMemberAccess(parameter, DataBinding.Registration.Member);
@@ -141,6 +151,9 @@ namespace Artemis.Core
private void CreateSetValueTypeExpression()
{
if (DataBinding!.Registration?.Member == null)
throw new ArtemisCoreException("Cannot create value setter for data binding without a registration");
ParameterExpression propertyValue = Expression.Parameter(typeof(TProperty), "propertyValue");
ParameterExpression variableCurrent = Expression.Variable(typeof(TLayerProperty), "current");
ConstantExpression layerProperty = Expression.Constant(DataBinding.LayerProperty);
@@ -161,7 +174,7 @@ namespace Artemis.Core
private void CreateSetCurrentValueExpression()
{
ParameterExpression propertyValue = Expression.Parameter(typeof(TProperty), "propertyValue");
ConstantExpression layerProperty = Expression.Constant(DataBinding.LayerProperty);
ConstantExpression layerProperty = Expression.Constant(DataBinding!.LayerProperty);
MemberExpression layerPropertyMemberAccess = Expression.MakeMemberAccess(layerProperty,
DataBinding.LayerProperty.GetType().GetMember(nameof(DataBinding.LayerProperty.CurrentValue))[0]);
@@ -38,28 +38,28 @@ namespace Artemis.Core
/// <summary>
/// Gets the member the <see cref="PropertyExpression" /> targets
/// <para><c>null</c> if the <see cref="PropertyExpression" /> is not a member expression</para>
/// <para><see langword="null"/> if the <see cref="PropertyExpression" /> is not a member expression</para>
/// </summary>
public MemberInfo Member { get; }
public MemberInfo? Member { get; }
/// <summary>
/// Gets the data binding created using this registration
/// </summary>
public DataBinding<TLayerProperty, TProperty> DataBinding { get; internal set; }
public DataBinding<TLayerProperty, TProperty>? DataBinding { get; internal set; }
/// <inheritdoc />
public IDataBinding GetDataBinding()
public IDataBinding? GetDataBinding()
{
return DataBinding;
}
/// <inheritdoc />
public IDataBinding CreateDataBinding()
public IDataBinding? CreateDataBinding()
{
if (DataBinding != null)
return DataBinding;
DataBindingEntity dataBinding = LayerProperty.Entity.DataBindingEntities.FirstOrDefault(e => e.TargetExpression == PropertyExpression.ToString());
DataBindingEntity? dataBinding = LayerProperty.Entity.DataBindingEntities.FirstOrDefault(e => e.TargetExpression == PropertyExpression.ToString());
if (dataBinding == null)
return null;
@@ -8,12 +8,12 @@
/// <summary>
/// Returns the data binding applied using this registration
/// </summary>
public IDataBinding GetDataBinding();
public IDataBinding? GetDataBinding();
/// <summary>
/// If found, creates a data binding from storage
/// </summary>
/// <returns></returns>
IDataBinding CreateDataBinding();
IDataBinding? CreateDataBinding();
}
}
@@ -21,13 +21,13 @@ namespace Artemis.Core
Load();
}
internal ConditionalDataBindingEntity Entity { get; }
/// <summary>
/// Gets a list of conditions applied to this data binding
/// </summary>
public ReadOnlyCollection<DataBindingCondition<TLayerProperty, TProperty>> Conditions => _conditions.AsReadOnly();
internal ConditionalDataBindingEntity Entity { get; }
/// <inheritdoc />
public DataBinding<TLayerProperty, TProperty> DataBinding { get; }
@@ -37,9 +37,7 @@ namespace Artemis.Core
if (_disposed)
throw new ObjectDisposedException("ConditionalDataBinding");
DataBindingCondition<TLayerProperty, TProperty> condition = Conditions.FirstOrDefault(c => c.Evaluate());
if (condition != null)
Console.WriteLine();
DataBindingCondition<TLayerProperty, TProperty>? condition = Conditions.FirstOrDefault(c => c.Evaluate());
return condition == null ? baseValue : condition.Value;
}
@@ -75,7 +73,7 @@ namespace Artemis.Core
return condition;
}
/// <summary>
/// Removes a condition from the conditional data binding's <see cref="Conditions" /> collection and disposes it
/// </summary>
@@ -111,7 +109,7 @@ namespace Artemis.Core
}
#endregion
#region Storage
/// <inheritdoc />
@@ -138,8 +136,11 @@ namespace Artemis.Core
/// <summary>
/// Occurs when a condition is added or removed
/// </summary>
public event EventHandler ConditionsUpdated;
public event EventHandler? ConditionsUpdated;
/// <summary>
/// Invokes the <see cref="ConditionsUpdated" /> event
/// </summary>
protected virtual void OnConditionsUpdated()
{
ConditionsUpdated?.Invoke(this, EventArgs.Empty);
@@ -18,6 +18,8 @@ namespace Artemis.Core
ConditionalDataBinding = conditionalDataBinding ?? throw new ArgumentNullException(nameof(conditionalDataBinding));
Order = conditionalDataBinding.Conditions.Count + 1;
Condition = new DataModelConditionGroup(null);
Value = default!;
Entity = new DataBindingConditionEntity();
Save();
}
@@ -26,6 +28,9 @@ namespace Artemis.Core
{
ConditionalDataBinding = conditionalDataBinding ?? throw new ArgumentNullException(nameof(conditionalDataBinding));
Entity = entity;
Condition = null!;
Value = default!;
Load();
}
@@ -83,7 +88,7 @@ namespace Artemis.Core
? new DataModelConditionGroup(null, Entity.Condition)
: new DataModelConditionGroup(null);
Value = Entity.Value == null ? default : JsonConvert.DeserializeObject<TProperty>(Entity.Value);
Value = (Entity.Value == null ? default : JsonConvert.DeserializeObject<TProperty>(Entity.Value))!;
Order = Entity.Order;
}
@@ -15,7 +15,7 @@ namespace Artemis.Core
/// Gets the plugin this data binding modifier belongs to
/// <para>Note: Not set until after registering</para>
/// </summary>
public Plugin Plugin { get; internal set; }
public Plugin? Plugin { get; internal set; }
/// <summary>
/// Gets the value type of this modifier type
@@ -35,17 +35,17 @@ namespace Artemis.Core
/// <summary>
/// Gets or sets the icon of this modifier
/// </summary>
public abstract string Icon { get; }
public abstract string? Icon { get; }
/// <summary>
/// Gets the description of this modifier
/// </summary>
public virtual string Description => null;
public virtual string? Description => null;
/// <summary>
/// Gets the category of this modifier
/// </summary>
public virtual string Category => null;
public virtual string? Category => null;
/// <summary>
/// Returns whether the given type is supported by the modifier
@@ -69,14 +69,26 @@ namespace Artemis.Core
/// </para>
/// </summary>
/// <param name="currentValue">The current value before modification, type should match <see cref="ValueType" /></param>
/// <param name="parameterValue">The parameter to use for the modification, type should match <see cref="ParameterType" /></param>
/// <param name="parameterValue">
/// The parameter to use for the modification, type should match <see cref="ParameterType" />
/// </param>
/// <returns>The modified value, with a type of <see cref="ValueType" /></returns>
internal abstract object? InternalApply(object? currentValue, object? parameterValue);
}
/// <summary>
/// Represents a part of a modifier type
/// </summary>
public enum ModifierTypePart
{
/// <summary>
/// The value part of a modifier, backed by <see cref="DataBindingModifierType{TValue}.ValueType" />
/// </summary>
Value,
/// <summary>
/// The parameter part of a modifier, backed by <see cref="DataBindingModifierType{TValue,TParameter}.ParameterType" />
/// </summary>
Parameter
}
}
@@ -103,8 +103,8 @@ namespace Artemis.Core
return;
}
Type targetType = DirectDataBinding.DataBinding.GetTargetType();
if (!modifierType.SupportsType(targetType, ModifierTypePart.Value))
Type? targetType = DirectDataBinding.DataBinding.GetTargetType();
if (targetType != null && !modifierType.SupportsType(targetType, ModifierTypePart.Value))
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}");
@@ -158,7 +158,7 @@ namespace Artemis.Core
/// 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)
public void UpdateParameterStatic(object? staticValue)
{
if (_disposed)
throw new ObjectDisposedException("DataBindingModifier");
@@ -167,10 +167,10 @@ namespace Artemis.Core
ParameterPath?.Dispose();
ParameterPath = null;
Type parameterType = ModifierType?.ParameterType ?? DirectDataBinding.DataBinding.GetTargetType();
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)
if (parameterType == null || staticValue != null && staticValue.GetType() == parameterType)
ParameterStaticValue = staticValue;
else if (staticValue != null)
ParameterStaticValue = Convert.ChangeType(staticValue, parameterType);
@@ -189,7 +189,7 @@ namespace Artemis.Core
// Modifier type
if (Entity.ModifierTypePluginGuid != null && ModifierType == null)
{
BaseDataBindingModifierType modifierType = DataBindingModifierTypeStore.Get(Entity.ModifierTypePluginGuid.Value, Entity.ModifierType)?.DataBindingModifierType;
BaseDataBindingModifierType? modifierType = DataBindingModifierTypeStore.Get(Entity.ModifierTypePluginGuid.Value, Entity.ModifierType)?.DataBindingModifierType;
if (modifierType != null)
UpdateModifierType(modifierType);
}
@@ -203,18 +203,21 @@ namespace Artemis.Core
else if (ParameterType == ProfileRightSideType.Static && Entity.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;
Type? parameterType = ModifierType?.ParameterType ?? DirectDataBinding.DataBinding.GetTargetType();
object? staticValue = null;
try
{
staticValue = JsonConvert.DeserializeObject(Entity.ParameterStaticValue, parameterType);
staticValue = parameterType != null
? JsonConvert.DeserializeObject(Entity.ParameterStaticValue, parameterType)
: JsonConvert.DeserializeObject(Entity.ParameterStaticValue);
}
// If deserialization fails, use the type's default
catch (JsonSerializationException e)
{
DeserializationLogger.LogModifierDeserializationFailure(GetType().Name, e);
staticValue = Activator.CreateInstance(parameterType);
if (parameterType != null)
staticValue = Activator.CreateInstance(parameterType);
}
UpdateParameterStatic(staticValue);
@@ -235,7 +238,7 @@ namespace Artemis.Core
DirectDataBinding.Entity.Modifiers.Add(Entity);
// Modifier
if (ModifierType != null)
if (ModifierType?.Plugin != null)
{
Entity.ModifierType = ModifierType.GetType().Name;
Entity.ModifierTypePluginGuid = ModifierType.Plugin.Guid;
@@ -280,17 +283,17 @@ namespace Artemis.Core
#region Event handlers
private void DataBindingModifierTypeStoreOnDataBindingModifierAdded(object sender, DataBindingModifierTypeStoreEvent e)
private void DataBindingModifierTypeStoreOnDataBindingModifierAdded(object? sender, DataBindingModifierTypeStoreEvent e)
{
if (ModifierType != null)
return;
BaseDataBindingModifierType modifierType = e.TypeRegistration.DataBindingModifierType;
if (modifierType.Plugin.Guid == Entity.ModifierTypePluginGuid && modifierType.GetType().Name == Entity.ModifierType)
if (modifierType.Plugin!.Guid == Entity.ModifierTypePluginGuid && modifierType.GetType().Name == Entity.ModifierType)
UpdateModifierType(modifierType);
}
private void DataBindingModifierTypeStoreOnDataBindingModifierRemoved(object sender, DataBindingModifierTypeStoreEvent e)
private void DataBindingModifierTypeStoreOnDataBindingModifierRemoved(object? sender, DataBindingModifierTypeStoreEvent e)
{
if (e.TypeRegistration.DataBindingModifierType == ModifierType)
UpdateModifierType(null);
@@ -42,7 +42,7 @@ namespace Artemis.Core
if (_disposed)
throw new ObjectDisposedException("DirectDataBinding");
if (SourcePath == null || !SourcePath.IsValid)
if (SourcePath == null || !SourcePath.IsValid || DataBinding.Converter == null)
return baseValue;
object? dataBindingValue = SourcePath.GetValue();
@@ -188,6 +188,9 @@ namespace Artemis.Core
/// </summary>
public event EventHandler? ModifiersUpdated;
/// <summary>
/// Invokes the <see cref="ModifiersUpdated" /> event
/// </summary>
protected virtual void OnModifiersUpdated()
{
ModifiersUpdated?.Invoke(this, EventArgs.Empty);