public override bool TryReadDataFieldCached <T>(string name, WithFormat <T> format, [MaybeNullWhen(false)] out T value) { if (!Reading) { throw new InvalidOperationException("Cannot use ReadDataField while not reading."); } if (_context != null && _context.TryGetCachedField(name, out value)) { return(true); } foreach (var map in ReadMaps !) { if (map.TryGetNode(name, out var node)) { var customFormatter = format.GetYamlSerializer(); value = (T)customFormatter.NodeToType(typeof(T), node, this); _context?.SetCachedField(name, value); return(true); } } value = default; return(false); }
// TODO: Theoretical optimization. // Might be a good idea to make DataField<T> use caching for value types without references too. /// <inheritdoc /> public override void DataField <T>(ref T value, string name, T defaultValue, WithFormat <T> format, bool alwaysWrite = false) { if (Reading) // read { foreach (var map in ReadMaps !) { if (map.TryGetNode(name, out var node)) { var customFormatter = format.GetYamlSerializer(); value = (T)customFormatter.NodeToType(typeof(T), node, this); return; } } value = defaultValue; return; } else // write { // don't write if value is null or default if (!alwaysWrite && IsValueDefault(name, value, defaultValue, format)) { return; } // if value AND defaultValue are null then IsValueDefault above will abort. var customFormatter = format.GetYamlSerializer(); var key = name; var val = value == null?customFormatter.TypeToNode(defaultValue !, this) : customFormatter.TypeToNode(value, this); // write the concrete type tag AssignTag(typeof(T), value, defaultValue, val); WriteMap !.Add(key, val); } }
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; } } }
bool IsValueDefault <T>(string field, T value, T providedDefault, WithFormat <T> format) { if ((value != null || providedDefault == null) && (value == null || IsSerializedEqual(value, providedDefault))) { return(true); } if (_context != null) { return(_context.IsValueDefault(field, value, format)); } return(false); }
// TODO: Theoretical optimization. // Might be a good idea to make DataField<T> use caching for value types without references too. /// <inheritdoc /> public override void DataField <T>(ref T value, string name, T defaultValue, WithFormat <T> format, bool alwaysWrite = false) { if (Reading) // read { foreach (var map in ReadMaps) { if (map.TryGetNode(name, out var node)) { var customFormatter = format.GetYamlSerializer(); value = (T)customFormatter.NodeToType(typeof(T), node, this); return; } } value = defaultValue; return; } else // write { // don't write if value is null or default if (!alwaysWrite && IsValueDefault(name, value, defaultValue)) { return; } var customFormatter = format.GetYamlSerializer(); var key = name; var val = value == null?customFormatter.TypeToNode(defaultValue, this) : customFormatter.TypeToNode(value, this); // write the concrete type tag if (typeof(T).IsAbstract || typeof(T).IsInterface) { var concreteType = value == null?defaultValue.GetType() : value.GetType(); val.Tag = $"!type:{concreteType.Name}"; } WriteMap.Add(key, val); } }
/// <inheritdoc /> public override void DataFieldCached <T>(ref T value, string name, T defaultValue, WithFormat <T> format, bool alwaysWrite = false) { if (Reading) // read { if (_context != null && _context.TryGetCachedField <T>(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)) { var customFormatter = format.GetYamlSerializer(); value = (T)customFormatter.NodeToType(typeof(T), node, this); _context?.SetCachedField(name, value); return; } } value = defaultValue; _context?.SetCachedField(name, value); return; } else // write { DataField(ref value, name, defaultValue, format, alwaysWrite); } }
public YamlCustomFormatSerializer(WithFormat <T> formatter) { _formatter = formatter; }
public virtual bool IsValueDefault <T>(string field, T value, WithFormat <T> format) { return(false); }
public override bool TryReadDataField <T>(string name, WithFormat <T> format, [MaybeNullWhen(false)] out T value) { value = default; return(false); }
/// <summary> /// Writes or reads a simple field by reference. /// </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="withFormat">The formatter to use for representing this particular value in the medium.</param> /// <param name="alwaysWrite">If true, always write this field to map saving, even if it matches the default.</param> /// <typeparam name="T">The type of the field that will be read/written.</typeparam> public abstract void DataField <T>(ref T value, string name, T defaultValue, WithFormat <T> withFormat, bool alwaysWrite = false);
public virtual bool TryReadDataFieldCached <T>(string name, WithFormat <T> format, [MaybeNullWhen(false)] out T value) { return(TryReadDataField(name, format, out value)); }
public abstract bool TryReadDataField <T>(string name, WithFormat <T> format, [MaybeNullWhen(false)] out T value);
/// <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. 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="withFormat">The formatter to use for representing this particular value in the medium.</param> /// <param name="alwaysWrite">If true, always write this field to map saving, even if it matches the default.</param> /// <typeparam name="T">The type of the field that will be read/written.</typeparam> public virtual void DataFieldCached <T>(ref T value, string name, T defaultValue, WithFormat <T> withFormat, bool alwaysWrite = false) { DataField(ref value, name, defaultValue, withFormat, alwaysWrite); }
/// <summary> /// Create a YamlFlagSerializer using the given bitflag representation type. /// </summary> /// <param name="type"> /// The bitflag enum for which the constructors will be used to represent /// bits being set in the integer value. /// </param> /// <exception cref="FlagSerializerException"> /// Thrown if the bitflag type is not a <c>enum</c>, or does not have the /// <see cref="System.Flags"/> attribute. /// </exception> public YamlFlagSerializer(Type type, WithFormat <int> formatter) : base(formatter) { _flagType = type; }