mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
Make AddComponent load default DataField values (#1112)
Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
This commit is contained in:
@@ -6,6 +6,7 @@ using Robust.Shared.Exceptions;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
@@ -127,6 +128,8 @@ namespace Robust.Shared.GameObjects
|
||||
ComponentAdded?.Invoke(this, new ComponentEventArgs(component));
|
||||
}
|
||||
|
||||
component.ExposeData(DefaultValueSerializer.Reader());
|
||||
|
||||
component.OnAdd();
|
||||
|
||||
if (entity.Initialized || entity.Initializing)
|
||||
|
||||
69
Robust.Shared/Serialization/DefaultValueSerializer.cs
Normal file
69
Robust.Shared/Serialization/DefaultValueSerializer.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq.Expressions;
|
||||
using Robust.Shared.Interfaces.Serialization;
|
||||
|
||||
namespace Robust.Shared.Serialization
|
||||
{
|
||||
public sealed class DefaultValueSerializer : ObjectSerializer
|
||||
{
|
||||
public static DefaultValueSerializer Reader()
|
||||
{
|
||||
return new DefaultValueSerializer()
|
||||
{
|
||||
Reading = true,
|
||||
};
|
||||
}
|
||||
|
||||
private DefaultValueSerializer() {}
|
||||
|
||||
public override void DataField<T>(ref T value, string name, T defaultValue, WithFormat<T> withFormat, bool alwaysWrite = false)
|
||||
{
|
||||
if (Reading)
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals(value, default))
|
||||
value = defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public override T ReadDataField<T>(string name, T defaultValue)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public override bool TryReadDataField<T>(string name, WithFormat<T> format, [MaybeNullWhen(false)] out T value)
|
||||
{
|
||||
value = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void DataField<TTarget, TSource>(
|
||||
ref TTarget value,
|
||||
string name,
|
||||
TTarget defaultValue,
|
||||
ReadConvertFunc<TTarget, TSource> ReadConvertFunc,
|
||||
WriteConvertFunc<TTarget, TSource>? WriteConvertFunc = null,
|
||||
bool alwaysWrite = false
|
||||
)
|
||||
{
|
||||
if (Reading)
|
||||
{
|
||||
if (EqualityComparer<TTarget>.Default.Equals(value, default))
|
||||
value = defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public override void DataReadFunction<T>(string name, T defaultValue, ReadFunctionDelegate<T> func)
|
||||
{
|
||||
if (Reading)
|
||||
{
|
||||
func(defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
public override void DataWriteFunction<T>(string name, T defaultValue, WriteFunctionDelegate<T> func, bool alwaysWrite = false)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Robust.Shared.Interfaces.Reflection;
|
||||
using Robust.Shared.Interfaces.Serialization;
|
||||
using Robust.Shared.IoC;
|
||||
@@ -78,7 +79,43 @@ namespace Robust.Shared.Serialization
|
||||
/// szr.DataField(this, x => x.SomeProperty, "some-property", SomeDefaultValue);
|
||||
/// </example>
|
||||
/// </remarks>
|
||||
public abstract void DataField<TRoot, T>(TRoot root, Expression<Func<TRoot,T>> expr, string name, T defaultValue, bool alwaysWrite = false);
|
||||
public virtual void DataField<TRoot, T>(TRoot o, Expression<Func<TRoot,T>> expr, string name, T defaultValue, bool alwaysWrite = false)
|
||||
{
|
||||
if (o == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(o));
|
||||
}
|
||||
|
||||
if (expr == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(expr));
|
||||
}
|
||||
|
||||
if (!(expr.Body is MemberExpression mExpr))
|
||||
{
|
||||
throw new NotSupportedException("Cannot handle expressions of types other than MemberExpression.");
|
||||
}
|
||||
|
||||
|
||||
WriteFunctionDelegate<T> getter;
|
||||
ReadFunctionDelegate<T> setter;
|
||||
switch (mExpr.Member)
|
||||
{
|
||||
case FieldInfo fi:
|
||||
getter = () => (T) fi.GetValue(o)!;
|
||||
setter = v => fi.SetValue(o, v);
|
||||
break;
|
||||
case PropertyInfo pi:
|
||||
getter = () => (T) pi.GetValue(o)!;
|
||||
setter = v => pi.SetValue(o, v);
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("Cannot handle member expressions of types other than FieldInfo or PropertyInfo.");
|
||||
}
|
||||
|
||||
DataReadWriteFunction(name, defaultValue, setter, getter, alwaysWrite);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Writes or reads a simple field by reference.
|
||||
@@ -230,22 +267,22 @@ namespace Robust.Shared.Serialization
|
||||
/// <summary>
|
||||
/// Try- pattern version of <see cref="ReadDataField" />.
|
||||
/// </summary>
|
||||
public virtual bool TryReadDataField<T>(string name, out T value)
|
||||
public virtual bool TryReadDataField<T>(string name, [MaybeNullWhen(false)] out T value)
|
||||
{
|
||||
return TryReadDataField(name, WithFormat<T>.NoFormat, out value);
|
||||
}
|
||||
|
||||
public abstract bool TryReadDataField<T>(string name, WithFormat<T> format, out T value);
|
||||
public abstract bool TryReadDataField<T>(string name, WithFormat<T> format, [MaybeNullWhen(false)] out T value);
|
||||
|
||||
/// <summary>
|
||||
/// Try- pattern version of <see cref="ReadDataFieldCached" />.
|
||||
/// </summary>
|
||||
public virtual bool TryReadDataFieldCached<T>(string name, out T value)
|
||||
public virtual bool TryReadDataFieldCached<T>(string name, [MaybeNullWhen(false)] out T value)
|
||||
{
|
||||
return TryReadDataFieldCached(name, WithFormat<T>.NoFormat, out value);
|
||||
}
|
||||
|
||||
public virtual bool TryReadDataFieldCached<T>(string name, WithFormat<T> format, out T value)
|
||||
public virtual bool TryReadDataFieldCached<T>(string name, WithFormat<T> format, [MaybeNullWhen(false)] out T value)
|
||||
{
|
||||
return TryReadDataField(name, format, out value);
|
||||
}
|
||||
|
||||
@@ -152,43 +152,6 @@ namespace Robust.Shared.Serialization
|
||||
}
|
||||
|
||||
|
||||
public override void DataField<TRoot, T>(TRoot o, Expression<Func<TRoot,T>> expr, string name, T defaultValue, bool alwaysWrite = false)
|
||||
{
|
||||
if (o == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(o));
|
||||
}
|
||||
|
||||
if (expr == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(expr));
|
||||
}
|
||||
|
||||
if (!(expr.Body is MemberExpression mExpr))
|
||||
{
|
||||
throw new NotSupportedException("Cannot handle expressions of types other than MemberExpression.");
|
||||
}
|
||||
|
||||
|
||||
WriteFunctionDelegate<T> getter;
|
||||
ReadFunctionDelegate<T> setter;
|
||||
switch (mExpr.Member)
|
||||
{
|
||||
case FieldInfo fi:
|
||||
getter = () => (T) fi.GetValue(o)!;
|
||||
setter = v => fi.SetValue(o, v);
|
||||
break;
|
||||
case PropertyInfo pi:
|
||||
getter = () => (T) pi.GetValue(o)!;
|
||||
setter = v => pi.SetValue(o, v);
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("Cannot handle member expressions of types other than FieldInfo or PropertyInfo.");
|
||||
}
|
||||
|
||||
DataReadWriteFunction(name, defaultValue, setter, getter, alwaysWrite);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void DataFieldCached<T>(ref T value, string name, T defaultValue, WithFormat<T> format, bool alwaysWrite = false)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user