/// <inheritdoc /> public override void DataFieldCached <TTarget, TSource>( ref TTarget value, string name, TTarget defaultValue, ReadConvertFunc <TTarget, TSource> ReadConvertFunc, WriteConvertFunc <TTarget, TSource>?WriteConvertFunc = null, bool alwaysWrite = false) { if (Reading) { if (_context != null && _context.TryGetCachedField <TTarget>(name, out var theValue)) { // Itermediate field so value doesn't get reset to default(T) if this fails. value = theValue; return; } foreach (var map in ReadMaps !) { if (map.TryGetNode(name, out var node)) { value = ReadConvertFunc((TSource)NodeToType(typeof(TSource), node)); _context?.SetCachedField(name, value); return; } } value = defaultValue; _context?.SetCachedField(name, value); } else { DataField(ref value, name, defaultValue, ReadConvertFunc, WriteConvertFunc, alwaysWrite); } }
/// <summary> /// Writes or reads a simple field by reference. /// Runs the provided delegate to do conversion from a more easy to (de)serialize data type. /// </summary> /// <param name="value">The reference to the field that will be read/written into.</param> /// <param name="name">The name of the field in the serialization medium. Most likely the name in YAML.</param> /// <param name="defaultValue">A default value. Used if the field does not exist while reading or to know if writing would be redundant.</param> /// <param name="ReadConvertFunc"> /// A delegate invoked to convert the intermediate serialization object <typeparamref name="TSource" /> /// to the actual value <typeparamref name="TTarget" /> while reading. /// </param> /// <param name="WriteConvertFunc"> /// A delegate invoked to convert the actual value <typeparamref name="TTarget" /> /// to an intermediate serialization object <typeparamref name="TSource" /> that will be written. /// </param> /// <param name="alwaysWrite">If true, always write this field to map saving, even if it matches the default.</param> /// <typeparam name="TTarget">The type of the field that will be read/written.</typeparam> /// <typeparam name="TSource">The type of the intermediate object that will be (de)serialized.</typeparam> public abstract void DataField <TTarget, TSource>( ref TTarget value, string name, TTarget defaultValue, ReadConvertFunc <TTarget, TSource> ReadConvertFunc, WriteConvertFunc <TTarget, TSource>?WriteConvertFunc = null, bool alwaysWrite = false ) where TSource : notnull;
/// <summary> /// Writes or reads a simple field by reference. /// This method can cache results and share them with other objects. /// As such, when reading, your value may NOT be private. /// This can cut out parsing steps and memory cost for commonly used objects such as walls. /// This method can cache results and share them with other objects. /// As such, when reading, your value may NOT be private. Do not modify it as if it's purely your own. /// This can cut out parsing steps and memory cost for commonly used objects such as walls. /// </summary> /// <param name="value">The reference to the field that will be read/written into.</param> /// <param name="name">The name of the field in the serialization medium. Most likely the name in YAML.</param> /// <param name="defaultValue">A default value. Used if the field does not exist while reading or to know if writing would be redundant.</param> /// <param name="ReadConvertFunc"> /// A delegate invoked to convert the intermediate serialization object <typeparamref name="TSource" /> /// to the actual value <typeparamref name="TTarget" /> while reading. /// </param> /// <param name="WriteConvertFunc"> /// A delegate invoked to convert the actual value <typeparamref name="TTarget" /> /// to an intermediate serialization object <typeparamref name="TSource" /> that will be written. /// </param> /// <param name="alwaysWrite">If true, always write this field to map saving, even if it matches the default.</param> /// <typeparam name="TTarget">The type of the field that will be read/written.</typeparam> /// <typeparam name="TSource">The type of the intermediate object that will be (de)serialized.</typeparam> public virtual void DataFieldCached <TTarget, TSource>( ref TTarget value, string name, TTarget defaultValue, ReadConvertFunc <TTarget, TSource> ReadConvertFunc, WriteConvertFunc <TTarget, TSource>?WriteConvertFunc = null, bool alwaysWrite = false ) where TSource : notnull { DataField(ref value, name, defaultValue, ReadConvertFunc, WriteConvertFunc, alwaysWrite); }
/// <inheritdoc /> 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) { foreach (var map in ReadMaps !) { if (map.TryGetNode(name, out var node)) { value = ReadConvertFunc((TSource)NodeToType(typeof(TSource), node)); return; } } value = defaultValue; } else { if (WriteConvertFunc == null) { // TODO: More verbosity diagnostics. Logger.WarningS(LogCategory, "Field '{0}' not written due to lack of WriteConvertFunc.", name); return; } // don't write if value is null or default if (!alwaysWrite && IsValueDefault(name, value, defaultValue, WithFormat <TTarget> .NoFormat)) { return; } var key = name; var val = value == null?TypeToNode(WriteConvertFunc(defaultValue !)) : TypeToNode(WriteConvertFunc(value !)); // write the concrete type tag if (typeof(TTarget).IsAbstract || typeof(TTarget).IsInterface) { var concreteType = value == null ? defaultValue !.GetType() : value.GetType(); val.Tag = $"!type:{concreteType.Name}"; } WriteMap !.Add(key, val); } }
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; } } }