// 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 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); }
/// <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); } }
// 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); } }