mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
Prototype load parallelization (#3502)
This commit is contained in:
committed by
GitHub
parent
2aafb21772
commit
84733a335c
@@ -35,7 +35,8 @@ END TEMPLATE-->
|
||||
|
||||
### Breaking changes
|
||||
|
||||
*None yet*
|
||||
* `ITypeReader<,>.Read(...)` and `ITypeCopier<>.Copy(...)` have had their `bool skipHook` parameter replaced with a `SerializationHookContext` to facilitate multithreaded prototype loading.
|
||||
* Prototypes are now loaded in parallel across multiple threads. Type serializers, property setters, etc... must be thread safe and not rely on an active IoC instance.
|
||||
|
||||
### New features
|
||||
|
||||
@@ -43,16 +44,21 @@ END TEMPLATE-->
|
||||
|
||||
### Bugfixes
|
||||
|
||||
*None yet*
|
||||
* Mapped string serializer once again is initialized with prototype strongs, reducing bandwidth usage.
|
||||
|
||||
### Other
|
||||
|
||||
*None yet*
|
||||
* Drastically improved startup time by running prototype loading in parallel.
|
||||
* `AfterDeserialization` hooks are still ran on the main thread during load to avoid issues.
|
||||
* Various systems in the serialization system such as `SerializationManager` or `ReflectionManager` have had various methods made thread safe.
|
||||
* `TileAliasPrototype` no longer has a load priority set.
|
||||
* Straightened out terminology in prototypes: to refer to the type of a prototype (e.g. `EntityPrototype` itself), use "kind".
|
||||
* This was previously mixed between "type" and "variant".
|
||||
|
||||
### Internal
|
||||
|
||||
*None yet*
|
||||
|
||||
* `SpanSplitExtensions` has been taken behind the shed for being horrifically wrong unsafe code that should never have been entered into a keyboard ever. A simpler helper method replaces its use in `Box2Serializer`.
|
||||
* `PrototypeManager.cs` has been split apart into multiple files.
|
||||
|
||||
## 0.73.0.0
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Globalization;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -19,7 +20,7 @@ namespace Robust.Benchmarks.Serialization
|
||||
}
|
||||
|
||||
public int Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<int>? instanceProvider = null)
|
||||
{
|
||||
return int.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
@@ -32,7 +33,7 @@ namespace Robust.Benchmarks.Serialization
|
||||
return new ValueDataNode(value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
public int CreateCopy(ISerializationManager serializationManager, int source, bool skipHook,
|
||||
public int CreateCopy(ISerializationManager serializationManager, int source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return source;
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace Robust.Client
|
||||
deps.Register<IGameTiming, ClientGameTiming>();
|
||||
deps.Register<IClientGameTiming, ClientGameTiming>();
|
||||
deps.Register<IPrototypeManager, ClientPrototypeManager>();
|
||||
deps.Register<IPrototypeManagerInternal, ClientPrototypeManager>();
|
||||
deps.Register<IMapManager, NetworkedMapManager>();
|
||||
deps.Register<IMapManagerInternal, NetworkedMapManager>();
|
||||
deps.Register<INetworkedMapManager, NetworkedMapManager>();
|
||||
|
||||
@@ -157,7 +157,9 @@ namespace Robust.Client.Graphics.Clyde
|
||||
{
|
||||
FullMode = BoundedChannelFullMode.Wait,
|
||||
SingleReader = true,
|
||||
SingleWriter = true
|
||||
SingleWriter = true,
|
||||
// For unblocking continuations.
|
||||
AllowSynchronousContinuations = true
|
||||
});
|
||||
|
||||
_eventReader = eventChannel.Reader;
|
||||
|
||||
@@ -150,7 +150,9 @@ internal partial class Clyde
|
||||
{
|
||||
FullMode = BoundedChannelFullMode.Wait,
|
||||
SingleReader = true,
|
||||
SingleWriter = true
|
||||
SingleWriter = true,
|
||||
// For unblocking continuations.
|
||||
AllowSynchronousContinuations = true
|
||||
});
|
||||
|
||||
_eventReader = eventChannel.Reader;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Robust.Client.Serialization
|
||||
{
|
||||
public AppearanceVisualizer Read(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<AppearanceVisualizer>? instanceProvider = null)
|
||||
{
|
||||
Type? type = null;
|
||||
@@ -38,7 +38,7 @@ namespace Robust.Client.Serialization
|
||||
|
||||
var newNode = node.Copy();
|
||||
newNode.Remove("type");
|
||||
return (AppearanceVisualizer) serializationManager.Read(type, newNode, context, skipHook)!;
|
||||
return (AppearanceVisualizer) serializationManager.Read(type, newNode, hookCtx, context)!;
|
||||
}
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, MappingDataNode node,
|
||||
|
||||
@@ -8,6 +8,7 @@ using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.Enums;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Utility;
|
||||
using static Robust.Client.UserInterface.Controls.BaseButton;
|
||||
@@ -133,11 +134,11 @@ public sealed class TileSpawningUIController : UIController
|
||||
if (!string.IsNullOrEmpty(searchStr))
|
||||
{
|
||||
tileDefs = tileDefs.Where(s =>
|
||||
s.Name.Contains(searchStr, StringComparison.InvariantCultureIgnoreCase) ||
|
||||
Loc.GetString(s.Name).Contains(searchStr, StringComparison.CurrentCultureIgnoreCase) ||
|
||||
s.ID.Contains(searchStr, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
tileDefs = tileDefs.OrderBy(d => d.Name);
|
||||
tileDefs = tileDefs.OrderBy(d => Loc.GetString(d.Name));
|
||||
|
||||
_shownTiles.Clear();
|
||||
_shownTiles.AddRange(tileDefs);
|
||||
@@ -151,7 +152,7 @@ public sealed class TileSpawningUIController : UIController
|
||||
{
|
||||
texture = _resources.GetResource<TextureResource>(path);
|
||||
}
|
||||
_window.TileList.AddItem(entry.Name, texture);
|
||||
_window.TileList.AddItem(Loc.GetString(entry.Name), texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace Robust.Server
|
||||
[Dependency] private readonly IServerConsoleHost _consoleHost = default!;
|
||||
[Dependency] private readonly IParallelManagerInternal _parallelMgr = default!;
|
||||
[Dependency] private readonly ProfManager _prof = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly IPrototypeManagerInternal _prototype = default!;
|
||||
[Dependency] private readonly IPlacementManager _placement = default!;
|
||||
[Dependency] private readonly IServerViewVariablesInternal _viewVariables = default!;
|
||||
[Dependency] private readonly ISerializationManager _serialization = default!;
|
||||
@@ -317,11 +317,11 @@ namespace Robust.Server
|
||||
|
||||
//IoCManager.Resolve<IMapLoader>().LoadedMapData +=
|
||||
// IoCManager.Resolve<IRobustMappedStringSerializer>().AddStrings;
|
||||
_prototype.LoadedData += (yaml, name) =>
|
||||
_prototype.LoadedData += data =>
|
||||
{
|
||||
if (!_stringSerializer.Locked)
|
||||
{
|
||||
_stringSerializer.AddStrings(yaml);
|
||||
_stringSerializer.AddStrings(data.Root);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Robust.Server.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
@@ -25,9 +26,9 @@ internal sealed class MapChunkSerializer : ITypeSerializer<MapChunk, MappingData
|
||||
}
|
||||
|
||||
public MapChunk Read(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<MapChunk>? instantiationDelegate = null)
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<MapChunk>? instantiationDelegate = null)
|
||||
{
|
||||
var ind = (Vector2i) serializationManager.Read(typeof(Vector2i), node["ind"], context, skipHook)!;
|
||||
var ind = (Vector2i) serializationManager.Read(typeof(Vector2i), node["ind"], hookCtx, context)!;
|
||||
var tileNode = (ValueDataNode)node["tiles"];
|
||||
var tileBytes = Convert.FromBase64String(tileNode.Value);
|
||||
|
||||
@@ -128,7 +129,7 @@ internal sealed class MapChunkSerializer : ITypeSerializer<MapChunk, MappingData
|
||||
return Convert.ToBase64String(barr);
|
||||
}
|
||||
|
||||
public MapChunk CreateCopy(ISerializationManager serializationManager, MapChunk source, bool skipHook,
|
||||
public MapChunk CreateCopy(ISerializationManager serializationManager, MapChunk source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
var mapManager = ((SerializationManager)serializationManager).DependencyCollection.Resolve<IMapManager>();
|
||||
|
||||
@@ -59,6 +59,7 @@ namespace Robust.Server
|
||||
deps.Register<IPlayerManager, PlayerManager>();
|
||||
deps.Register<ISharedPlayerManager, PlayerManager>();
|
||||
deps.Register<IPrototypeManager, ServerPrototypeManager>();
|
||||
deps.Register<IPrototypeManagerInternal, ServerPrototypeManager>();
|
||||
deps.Register<IResourceManager, ResourceManager>();
|
||||
deps.Register<IResourceManagerInternal, ResourceManager>();
|
||||
deps.Register<EntityManager, ServerEntityManager>();
|
||||
|
||||
@@ -19,7 +19,9 @@ namespace Robust.Shared.Asynchronous
|
||||
var channel = Channel.CreateUnbounded<Mail>(new UnboundedChannelOptions
|
||||
{
|
||||
SingleReader = true,
|
||||
SingleWriter = false
|
||||
SingleWriter = false,
|
||||
// For unblocking continuations.
|
||||
AllowSynchronousContinuations = true
|
||||
});
|
||||
|
||||
_channelReader = channel.Reader;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
@@ -30,15 +31,15 @@ public sealed class SoundSpecifierTypeSerializer :
|
||||
}
|
||||
|
||||
public SoundSpecifier Read(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<SoundSpecifier>? instanceProvider = null)
|
||||
{
|
||||
var type = GetType(node);
|
||||
return (SoundSpecifier)serializationManager.Read(type, node, context, skipHook)!;
|
||||
return (SoundSpecifier)serializationManager.Read(type, node, hookCtx, context)!;
|
||||
}
|
||||
|
||||
public SoundSpecifier Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<SoundSpecifier>? instanceProvider = null)
|
||||
{
|
||||
return new SoundPathSpecifier(node.Value);
|
||||
|
||||
@@ -6,6 +6,7 @@ using JetBrains.Annotations;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -108,7 +109,7 @@ internal sealed class MapSerializationContext : ISerializationContext, IEntityLo
|
||||
EntityUid ITypeReader<EntityUid, ValueDataNode>.Read(ISerializationManager serializationManager,
|
||||
ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context, ISerializationManager.InstantiationDelegate<EntityUid>? _)
|
||||
{
|
||||
if (node.Value == "invalid")
|
||||
|
||||
@@ -4,6 +4,7 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics.Dynamics;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
@@ -31,13 +32,13 @@ public sealed class FixtureSerializer : ITypeSerializer<List<Fixture>, SequenceD
|
||||
}
|
||||
|
||||
public List<Fixture> Read(ISerializationManager serializationManager, SequenceDataNode node, IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<List<Fixture>>? instantiation = default)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<List<Fixture>>? instantiation = default)
|
||||
{
|
||||
var value = instantiation != null ? instantiation() : new List<Fixture>(node.Count);
|
||||
|
||||
foreach (var subNode in node)
|
||||
{
|
||||
var fixture = serializationManager.Read<Fixture>(subNode, context, skipHook);
|
||||
var fixture = serializationManager.Read<Fixture>(subNode, hookCtx, context);
|
||||
value.Add(fixture);
|
||||
}
|
||||
|
||||
|
||||
40
Robust.Shared/Prototypes/Attributes.cs
Normal file
40
Robust.Shared/Prototypes/Attributes.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
|
||||
namespace Robust.Shared.Prototypes;
|
||||
|
||||
/// <summary>
|
||||
/// Quick attribute to give the prototype its type string.
|
||||
/// To prevent needing to instantiate it because interfaces can't declare statics.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
|
||||
[BaseTypeRequired(typeof(IPrototype))]
|
||||
[MeansImplicitUse]
|
||||
[MeansDataDefinition]
|
||||
[Virtual]
|
||||
public class PrototypeAttribute : Attribute
|
||||
{
|
||||
private readonly string type;
|
||||
public string Type => type;
|
||||
public readonly int LoadPriority = 1;
|
||||
|
||||
public PrototypeAttribute(string type, int loadPriority = 1)
|
||||
{
|
||||
this.type = type;
|
||||
LoadPriority = loadPriority;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
|
||||
[BaseTypeRequired(typeof(IPrototype))]
|
||||
[MeansImplicitUse]
|
||||
[MeansDataDefinition]
|
||||
[MeansDataRecord]
|
||||
public sealed class PrototypeRecordAttribute : PrototypeAttribute
|
||||
{
|
||||
public PrototypeRecordAttribute(string type, int loadPriority = 1) : base(type, loadPriority)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
49
Robust.Shared/Prototypes/Exceptions.cs
Normal file
49
Robust.Shared/Prototypes/Exceptions.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Robust.Shared.Prototypes;
|
||||
|
||||
[Serializable]
|
||||
[Virtual]
|
||||
public class PrototypeLoadException : Exception
|
||||
{
|
||||
public PrototypeLoadException()
|
||||
{
|
||||
}
|
||||
|
||||
public PrototypeLoadException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public PrototypeLoadException(string message, Exception inner) : base(message, inner)
|
||||
{
|
||||
}
|
||||
|
||||
public PrototypeLoadException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
[Virtual]
|
||||
public class UnknownPrototypeException : Exception
|
||||
{
|
||||
public override string Message => "Unknown prototype: " + Prototype;
|
||||
public readonly string? Prototype;
|
||||
|
||||
public UnknownPrototypeException(string prototype)
|
||||
{
|
||||
Prototype = prototype;
|
||||
}
|
||||
|
||||
public UnknownPrototypeException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
Prototype = (string?) info.GetValue("prototype", typeof(string));
|
||||
}
|
||||
|
||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||
{
|
||||
base.GetObjectData(info, context);
|
||||
info.AddValue("prototype", Prototype, typeof(string));
|
||||
}
|
||||
}
|
||||
265
Robust.Shared/Prototypes/IPrototypeManager.cs
Normal file
265
Robust.Shared/Prototypes/IPrototypeManager.cs
Normal file
@@ -0,0 +1,265 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.Shared.Prototypes;
|
||||
|
||||
/// <summary>
|
||||
/// Handle storage and loading of YAML prototypes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Terminology:
|
||||
/// "Kinds" are the types of prototypes there are, like <see cref="EntityPrototype"/>.
|
||||
/// "Prototypes" are simply filled-in prototypes from YAML.
|
||||
/// </remarks>
|
||||
public interface IPrototypeManager
|
||||
{
|
||||
void Initialize();
|
||||
|
||||
/// <summary>
|
||||
/// Returns an <see cref="IEnumerable{T}"/> of all registered prototype kinds by their ID.
|
||||
/// </summary>
|
||||
IEnumerable<string> GetPrototypeKinds();
|
||||
|
||||
/// <summary>
|
||||
/// Return an <see cref="IEnumerable{T}"/> of all prototypes of a certain kind.
|
||||
/// </summary>
|
||||
/// <exception cref="KeyNotFoundException">
|
||||
/// Thrown if the type of prototype is not registered.
|
||||
/// </exception>
|
||||
IEnumerable<T> EnumeratePrototypes<T>() where T : class, IPrototype;
|
||||
|
||||
/// <summary>
|
||||
/// Return an <see cref="IEnumerable{T}"/> of all prototypes of a certain kind.
|
||||
/// </summary>
|
||||
/// <exception cref="KeyNotFoundException">
|
||||
/// Thrown if the kind of prototype is not registered.
|
||||
/// </exception>
|
||||
IEnumerable<IPrototype> EnumeratePrototypes(Type kind);
|
||||
|
||||
/// <summary>
|
||||
/// Return an <see cref="IEnumerable{T}"/> of all prototypes of a certain kind.
|
||||
/// </summary>
|
||||
/// <exception cref="KeyNotFoundException">
|
||||
/// Thrown if the kind of prototype is not registered.
|
||||
/// </exception>
|
||||
IEnumerable<IPrototype> EnumeratePrototypes(string variant);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an <see cref="IEnumerable{T}"/> of all parents of a prototype of a certain kind.
|
||||
/// </summary>
|
||||
IEnumerable<T> EnumerateParents<T>(string kind, bool includeSelf = false)
|
||||
where T : class, IPrototype, IInheritingPrototype;
|
||||
|
||||
/// <summary>
|
||||
/// Returns an <see cref="IEnumerable{T}"/> of parents of a prototype of a certain kind.
|
||||
/// </summary>
|
||||
IEnumerable<IPrototype> EnumerateParents(Type kind, string id, bool includeSelf = false);
|
||||
|
||||
/// <summary>
|
||||
/// Index for a <see cref="IPrototype"/> by ID.
|
||||
/// </summary>
|
||||
/// <exception cref="KeyNotFoundException">
|
||||
/// Thrown if the type of prototype is not registered.
|
||||
/// </exception>
|
||||
T Index<T>(string id) where T : class, IPrototype;
|
||||
|
||||
/// <summary>
|
||||
/// Index for a <see cref="IPrototype"/> by ID.
|
||||
/// </summary>
|
||||
/// <exception cref="KeyNotFoundException">
|
||||
/// Thrown if the ID does not exist or the kind of prototype is not registered.
|
||||
/// </exception>
|
||||
IPrototype Index(Type kind, string id);
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a prototype of type <typeparamref name="T"/> with the specified <param name="id"/> exists.
|
||||
/// </summary>
|
||||
bool HasIndex<T>(string id) where T : class, IPrototype;
|
||||
|
||||
bool TryIndex<T>(string id, [NotNullWhen(true)] out T? prototype) where T : class, IPrototype;
|
||||
bool TryIndex(Type kind, string id, [NotNullWhen(true)] out IPrototype? prototype);
|
||||
|
||||
bool HasMapping<T>(string id);
|
||||
bool TryGetMapping(Type kind, string id, [NotNullWhen(true)] out MappingDataNode? mappings);
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a prototype variant <param name="variant"/> exists.
|
||||
/// </summary>
|
||||
/// <param name="variant">Identifier for the prototype variant.</param>
|
||||
/// <returns>Whether the prototype variant exists.</returns>
|
||||
[Obsolete("Variant is outdated naming, use *kind* functions instead")]
|
||||
bool HasVariant(string variant);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Type for a prototype variant.
|
||||
/// </summary>
|
||||
/// <param name="variant">Identifier for the prototype variant.</param>
|
||||
/// <returns>The specified prototype Type.</returns>
|
||||
/// <exception cref="KeyNotFoundException">
|
||||
/// Thrown when the specified prototype variant isn't registered or doesn't exist.
|
||||
/// </exception>
|
||||
[Obsolete("Variant is outdated naming, use *kind* functions instead")]
|
||||
Type GetVariantType(string variant);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the Type for a prototype variant.
|
||||
/// </summary>
|
||||
/// <param name="variant">Identifier for the prototype variant.</param>
|
||||
/// <param name="prototype">The specified prototype Type, or null.</param>
|
||||
/// <returns>Whether the prototype type was found and <see cref="prototype"/> isn't null.</returns>
|
||||
[Obsolete("Variant is outdated naming, use *kind* functions instead")]
|
||||
bool TryGetVariantType(string variant, [NotNullWhen(true)] out Type? prototype);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a prototype's variant.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="variant"></param>
|
||||
/// <returns></returns>
|
||||
[Obsolete("Variant is outdated naming, use *kind* functions instead")]
|
||||
bool TryGetVariantFrom(Type type, [NotNullWhen(true)] out string? variant);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a prototype's variant.
|
||||
/// </summary>
|
||||
/// <param name="prototype">The prototype in question.</param>
|
||||
/// <param name="variant">Identifier for the prototype variant, or null.</param>
|
||||
/// <returns>Whether the prototype variant was successfully retrieved.</returns>
|
||||
[Obsolete("Variant is outdated naming, use *kind* functions instead")]
|
||||
bool TryGetVariantFrom(IPrototype prototype, [NotNullWhen(true)] out string? variant);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a prototype's variant.
|
||||
/// </summary>
|
||||
/// <param name="variant">Identifier for the prototype variant, or null.</param>
|
||||
/// <typeparam name="T">The prototype in question.</typeparam>
|
||||
/// <returns>Whether the prototype variant was successfully retrieved.</returns>
|
||||
[Obsolete("Variant is outdated naming, use *kind* functions instead")]
|
||||
bool TryGetVariantFrom<T>([NotNullWhen(true)] out string? variant) where T : class, IPrototype;
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a prototype kind <param name="kind"/> exists.
|
||||
/// </summary>
|
||||
/// <param name="kind">Identifier for the prototype kind.</param>
|
||||
/// <returns>Whether the prototype kind exists.</returns>
|
||||
bool HasKind(string kind);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Type for a prototype kind.
|
||||
/// </summary>
|
||||
/// <param name="kind">Identifier for the prototype kind.</param>
|
||||
/// <returns>The specified prototype Type.</returns>
|
||||
/// <exception cref="KeyNotFoundException">
|
||||
/// Thrown when the specified prototype kind isn't registered or doesn't exist.
|
||||
/// </exception>
|
||||
Type GetKindType(string kind);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the Type for a prototype kind.
|
||||
/// </summary>
|
||||
/// <param name="kind">Identifier for the prototype kind.</param>
|
||||
/// <param name="prototype">The specified prototype Type, or null.</param>
|
||||
/// <returns>Whether the prototype type was found and <see cref="prototype"/> isn't null.</returns>
|
||||
bool TryGetKindType(string kind, [NotNullWhen(true)] out Type? prototype);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a prototype's kind.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="kind"></param>
|
||||
/// <returns></returns>
|
||||
bool TryGetKindFrom(Type type, [NotNullWhen(true)] out string? kind);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a prototype's kind.
|
||||
/// </summary>
|
||||
/// <param name="prototype">The prototype in question.</param>
|
||||
/// <param name="kind">Identifier for the prototype kind, or null.</param>
|
||||
/// <returns>Whether the prototype kind was successfully retrieved.</returns>
|
||||
bool TryGetKindFrom(IPrototype prototype, [NotNullWhen(true)] out string? kind);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a prototype's kind.
|
||||
/// </summary>
|
||||
/// <param name="kind">Identifier for the prototype kind, or null.</param>
|
||||
/// <typeparam name="T">The prototype in question.</typeparam>
|
||||
/// <returns>Whether the prototype kind was successfully retrieved.</returns>
|
||||
bool TryGetKindFrom<T>([NotNullWhen(true)] out string? kind) where T : class, IPrototype;
|
||||
|
||||
/// <summary>
|
||||
/// Load prototypes from files in a directory, recursively.
|
||||
/// </summary>
|
||||
void LoadDirectory(ResourcePath path, bool overwrite = false, Dictionary<Type, HashSet<string>>? changed = null);
|
||||
|
||||
Dictionary<string, HashSet<ErrorNode>> ValidateDirectory(ResourcePath path);
|
||||
|
||||
void LoadFromStream(TextReader stream, bool overwrite = false, Dictionary<Type, HashSet<string>>? changed = null);
|
||||
|
||||
void LoadString(string str, bool overwrite = false, Dictionary<Type, HashSet<string>>? changed = null);
|
||||
|
||||
void RemoveString(string prototypes);
|
||||
|
||||
/// <summary>
|
||||
/// Clear out all prototypes and reset to a blank slate.
|
||||
/// </summary>
|
||||
void Clear();
|
||||
|
||||
/// <summary>
|
||||
/// Syncs all inter-prototype data. Call this when operations adding new prototypes are done.
|
||||
/// </summary>
|
||||
void ResolveResults();
|
||||
|
||||
/// <summary>
|
||||
/// Reload the changes from LoadString
|
||||
/// </summary>
|
||||
/// <param name="prototypes">Changes from load string</param>
|
||||
void ReloadPrototypes(Dictionary<Type, HashSet<string>> prototypes);
|
||||
|
||||
/// <summary>
|
||||
/// Registers a specific prototype name to be ignored.
|
||||
/// </summary>
|
||||
void RegisterIgnore(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Loads a single prototype class type into the manager.
|
||||
/// </summary>
|
||||
/// <param name="protoClass">A prototype class type that implements IPrototype. This type also
|
||||
/// requires a <see cref="PrototypeAttribute"/> with a non-empty class string.</param>
|
||||
[Obsolete("Prototype type is outdated naming, use *king* functions instead")]
|
||||
void RegisterType(Type protoClass);
|
||||
|
||||
/// <summary>
|
||||
/// Loads a single prototype kind into the manager.
|
||||
/// </summary>
|
||||
/// <param name="kind">
|
||||
/// The type of the prototype kind that implements <see cref="IPrototype"/>. This type also
|
||||
/// requires a <see cref="PrototypeAttribute"/> with a non-empty class string.
|
||||
/// </param>
|
||||
void RegisterKind(Type kind);
|
||||
|
||||
/// <summary>
|
||||
/// Fired when prototype are reloaded. The event args contain the modified prototypes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This does NOT fire on initial prototype load.
|
||||
/// </remarks>
|
||||
event Action<PrototypesReloadedEventArgs> PrototypesReloaded;
|
||||
}
|
||||
|
||||
internal interface IPrototypeManagerInternal : IPrototypeManager
|
||||
{
|
||||
event Action<DataNodeDocument>? LoadedData;
|
||||
}
|
||||
|
||||
public sealed record PrototypesReloadedEventArgs(
|
||||
IReadOnlyDictionary<Type, PrototypesReloadedEventArgs.PrototypeChangeSet> ByType)
|
||||
{
|
||||
public sealed record PrototypeChangeSet(IReadOnlyDictionary<string, IPrototype> Modified);
|
||||
}
|
||||
@@ -25,6 +25,7 @@ public sealed class MultiRootInheritanceGraph<T> where T : notnull
|
||||
}
|
||||
|
||||
public T[]? GetParents(T id) => _parents.GetValueOrDefault(id);
|
||||
public int GetParentsCount(T id) => _parents.GetValueOrDefault(id)?.Length ?? 0;
|
||||
|
||||
public bool TryGetParents(T id, [NotNullWhen(true)] out T[]? parents)
|
||||
{
|
||||
|
||||
337
Robust.Shared/Prototypes/PrototypeManager.YamlLoad.cs
Normal file
337
Robust.Shared/Prototypes/PrototypeManager.YamlLoad.cs
Normal file
@@ -0,0 +1,337 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.Shared.Prototypes;
|
||||
|
||||
public partial class PrototypeManager
|
||||
{
|
||||
public event Action<DataNodeDocument>? LoadedData;
|
||||
|
||||
/// <inheritdoc />
|
||||
public void LoadDirectory(ResourcePath path, bool overwrite = false,
|
||||
Dictionary<Type, HashSet<string>>? changed = null)
|
||||
{
|
||||
_hasEverBeenReloaded = true;
|
||||
var streams = Resources.ContentFindFiles(path)
|
||||
.Where(filePath => filePath.Extension == "yml" && !filePath.Filename.StartsWith("."))
|
||||
.ToArray();
|
||||
|
||||
// Shuffle to avoid input data patterns causing uneven thread workloads.
|
||||
RandomExtensions.Shuffle(streams.AsSpan(), new System.Random());
|
||||
|
||||
var sawmill = _logManager.GetSawmill("eng");
|
||||
|
||||
var results = streams.AsParallel()
|
||||
.Select<ResourcePath, (ResourcePath, IEnumerable<ExtractedMappingData>)>(file =>
|
||||
{
|
||||
try
|
||||
{
|
||||
using var reader = ReadFile(file, !overwrite);
|
||||
|
||||
if (reader == null)
|
||||
return (file, Array.Empty<ExtractedMappingData>());
|
||||
|
||||
var extractedList = new List<ExtractedMappingData>();
|
||||
foreach (var document in DataNodeParser.ParseYamlStream(reader))
|
||||
{
|
||||
LoadedData?.Invoke(document);
|
||||
|
||||
var seq = (SequenceDataNode)document.Root;
|
||||
foreach (var mapping in seq.Sequence)
|
||||
{
|
||||
var data = ExtractMapping((MappingDataNode)mapping);
|
||||
if (data != null)
|
||||
extractedList.Add(data);
|
||||
}
|
||||
}
|
||||
|
||||
return (file, extractedList);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
sawmill.Error($"Exception whilst loading prototypes from {file}:\n{e}");
|
||||
return (file, Array.Empty<ExtractedMappingData>());
|
||||
}
|
||||
});
|
||||
|
||||
foreach (var (file, result) in results)
|
||||
{
|
||||
foreach (var mapping in result)
|
||||
{
|
||||
try
|
||||
{
|
||||
MergeMapping(mapping, overwrite, changed);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
sawmill.Error($"Exception whilst loading prototypes from {file}:\n{e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<string, HashSet<ErrorNode>> ValidateDirectory(ResourcePath path)
|
||||
{
|
||||
var streams = Resources.ContentFindFiles(path).ToList().AsParallel()
|
||||
.Where(filePath => filePath.Extension == "yml" && !filePath.Filename.StartsWith("."));
|
||||
|
||||
var dict = new Dictionary<string, HashSet<ErrorNode>>();
|
||||
foreach (var resourcePath in streams)
|
||||
{
|
||||
using var reader = ReadFile(resourcePath);
|
||||
|
||||
if (reader == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var yamlStream = new YamlStream();
|
||||
yamlStream.Load(reader);
|
||||
|
||||
for (var i = 0; i < yamlStream.Documents.Count; i++)
|
||||
{
|
||||
var rootNode = (YamlSequenceNode)yamlStream.Documents[i].RootNode;
|
||||
foreach (YamlMappingNode node in rootNode.Cast<YamlMappingNode>())
|
||||
{
|
||||
var type = node.GetNode("type").AsString();
|
||||
if (!_kindNames.ContainsKey(type))
|
||||
{
|
||||
if (_ignoredPrototypeTypes.Contains(type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new PrototypeLoadException($"Unknown prototype type: '{type}'");
|
||||
}
|
||||
|
||||
var mapping = node.ToDataNodeCast<MappingDataNode>();
|
||||
mapping.Remove("type");
|
||||
var errorNodes = _serializationManager.ValidateNode(_kindNames[type], mapping).GetErrors()
|
||||
.ToHashSet();
|
||||
if (errorNodes.Count == 0) continue;
|
||||
if (!dict.TryGetValue(resourcePath.ToString(), out var hashSet))
|
||||
dict[resourcePath.ToString()] = new HashSet<ErrorNode>();
|
||||
dict[resourcePath.ToString()].UnionWith(errorNodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
private StreamReader? ReadFile(ResourcePath file, bool @throw = true)
|
||||
{
|
||||
var retries = 0;
|
||||
|
||||
// This might be shit-code, but its pjb-responded-idk-when-asked shit-code.
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
var reader = new StreamReader(Resources.ContentFileRead(file), EncodingHelpers.UTF8);
|
||||
return reader;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
if (retries > 10)
|
||||
{
|
||||
if (@throw)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
_sawmill.Error($"Error reloading prototypes in file {file}:\n{e}");
|
||||
return null;
|
||||
}
|
||||
|
||||
retries++;
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadFile(ResourcePath file, bool overwrite = false, Dictionary<Type, HashSet<string>>? changed = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var reader = ReadFile(file, !overwrite);
|
||||
|
||||
if (reader == null)
|
||||
return;
|
||||
|
||||
var i = 0;
|
||||
foreach (var document in DataNodeParser.ParseYamlStream(reader))
|
||||
{
|
||||
LoadedData?.Invoke(document);
|
||||
|
||||
try
|
||||
{
|
||||
var seq = (SequenceDataNode)document.Root;
|
||||
foreach (var mapping in seq.Sequence)
|
||||
{
|
||||
var extracted = ExtractMapping((MappingDataNode) mapping);
|
||||
if (extracted == null)
|
||||
continue;
|
||||
|
||||
MergeMapping(extracted, overwrite, changed);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_sawmill.Error($"Exception whilst loading prototypes from {file}#{i}:\n{e}");
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_sawmill.Error("YamlException whilst loading prototypes from {0}: {1}", file, e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private ExtractedMappingData? ExtractMapping(MappingDataNode dataNode)
|
||||
{
|
||||
var type = dataNode.Get<ValueDataNode>("type").Value;
|
||||
if (!_kindNames.TryGetValue(type, out var kind))
|
||||
{
|
||||
if (_ignoredPrototypeTypes.Contains(type))
|
||||
return null;
|
||||
|
||||
throw new PrototypeLoadException($"Unknown prototype type: '{type}'");
|
||||
}
|
||||
|
||||
var kindData = _kinds[kind];
|
||||
|
||||
if (!dataNode.TryGet<ValueDataNode>(IdDataFieldAttribute.Name, out var idNode))
|
||||
throw new PrototypeLoadException($"Prototype type {type} is missing an 'id' datafield.");
|
||||
|
||||
var id = idNode.Value;
|
||||
string[]? parents = null;
|
||||
|
||||
if (kindData.Inheritance != null)
|
||||
{
|
||||
if (dataNode.TryGet(ParentDataFieldAttribute.Name, out var parentNode))
|
||||
{
|
||||
parents = _serializationManager.Read<string[]>(parentNode);
|
||||
}
|
||||
}
|
||||
|
||||
return new ExtractedMappingData(kind, id, parents, dataNode);
|
||||
}
|
||||
|
||||
private void MergeMapping(
|
||||
ExtractedMappingData mapping,
|
||||
bool overwrite,
|
||||
Dictionary<Type, HashSet<string>>? changed)
|
||||
{
|
||||
var (kind, id, parents, data) = mapping;
|
||||
|
||||
var kindData = _kinds[kind];
|
||||
|
||||
if (!overwrite && kindData.Results.ContainsKey(id))
|
||||
throw new PrototypeLoadException($"Duplicate ID: '{id}' for kind '{kind}");
|
||||
|
||||
kindData.Results[id] = data;
|
||||
|
||||
if (kindData.Inheritance is { } inheritance)
|
||||
{
|
||||
if (parents != null)
|
||||
{
|
||||
inheritance.Add(id, parents);
|
||||
}
|
||||
else
|
||||
{
|
||||
inheritance.Add(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed == null)
|
||||
return;
|
||||
|
||||
var set = changed.GetOrNew(kind);
|
||||
set.Add(id);
|
||||
}
|
||||
|
||||
public void LoadFromStream(TextReader stream, bool overwrite = false,
|
||||
Dictionary<Type, HashSet<string>>? changed = null)
|
||||
{
|
||||
_hasEverBeenReloaded = true;
|
||||
|
||||
var i = 0;
|
||||
foreach (var document in DataNodeParser.ParseYamlStream(stream))
|
||||
{
|
||||
LoadedData?.Invoke(document);
|
||||
|
||||
try
|
||||
{
|
||||
var rootNode = (SequenceDataNode)document.Root;
|
||||
foreach (var node in rootNode.Cast<MappingDataNode>())
|
||||
{
|
||||
var extracted = ExtractMapping(node);
|
||||
if (extracted == null)
|
||||
continue;
|
||||
|
||||
MergeMapping(extracted, overwrite, changed);
|
||||
}
|
||||
|
||||
i += 1;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new PrototypeLoadException($"Failed to load prototypes from document#{i}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadString(string str, bool overwrite = false, Dictionary<Type, HashSet<string>>? changed = null)
|
||||
{
|
||||
LoadFromStream(new StringReader(str), overwrite, changed);
|
||||
}
|
||||
|
||||
public void RemoveString(string prototypes)
|
||||
{
|
||||
var reader = new StringReader(prototypes);
|
||||
|
||||
foreach (var document in DataNodeParser.ParseYamlStream(reader))
|
||||
{
|
||||
var root = (SequenceDataNode)document.Root;
|
||||
foreach (var node in root.Cast<MappingDataNode>())
|
||||
{
|
||||
var typeString = node.Get<ValueDataNode>("type").Value;
|
||||
if (!_kindNames.TryGetValue(typeString, out var kind))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var kindData = _kinds[kind];
|
||||
|
||||
var id = node.Get<ValueDataNode>("id").Value;
|
||||
|
||||
if (kindData.Inheritance is { } tree)
|
||||
tree.Remove(id, true);
|
||||
|
||||
kindData.Instances.Remove(id);
|
||||
kindData.Results.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// All these fields can be null in case the
|
||||
private sealed record ExtractedMappingData(
|
||||
Type Kind,
|
||||
string Id,
|
||||
string[]? Parents,
|
||||
MappingDataNode Data);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ namespace Robust.Shared.Prototypes;
|
||||
/// Prototype that represents an alias from one tile ID to another.
|
||||
/// Tile alias prototypes, unlike tile prototypes, are implemented here, as they're really just fed to TileDefinitionManager.
|
||||
/// </summary>
|
||||
[Prototype("tileAlias", -1)]
|
||||
[Prototype("tileAlias")]
|
||||
public sealed class TileAliasPrototype : IPrototype
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -80,5 +80,17 @@ namespace Robust.Shared.Random
|
||||
|
||||
return random.NextDouble() <= chance;
|
||||
}
|
||||
|
||||
internal static void Shuffle<T>(Span<T> array, System.Random random)
|
||||
{
|
||||
var n = array.Length;
|
||||
while (n > 1)
|
||||
{
|
||||
n--;
|
||||
var k = random.Next(n + 1);
|
||||
(array[k], array[n]) =
|
||||
(array[n], array[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
namespace Robust.Shared.Reflection
|
||||
@@ -24,8 +26,7 @@ namespace Robust.Shared.Reflection
|
||||
|
||||
public event EventHandler<ReflectionUpdateEventArgs>? OnAssemblyAdded;
|
||||
|
||||
[ViewVariables]
|
||||
public IReadOnlyList<Assembly> Assemblies => assemblies;
|
||||
[ViewVariables] public IReadOnlyList<Assembly> Assemblies => assemblies;
|
||||
|
||||
private readonly Dictionary<(Type baseType, string typeName), Type?> _yamlTypeTagCache = new();
|
||||
|
||||
@@ -34,6 +35,9 @@ namespace Robust.Shared.Reflection
|
||||
private readonly Dictionary<string, Enum> _enumCache = new();
|
||||
private readonly Dictionary<Enum, string> _reverseEnumCache = new();
|
||||
|
||||
private readonly ReaderWriterLockSlim _enumCacheLock = new();
|
||||
private readonly ReaderWriterLockSlim _yamlTypeTagCacheLock = new();
|
||||
|
||||
private readonly List<Type> _getAllTypesCache = new();
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -80,7 +84,7 @@ namespace Robust.Shared.Reflection
|
||||
{
|
||||
foreach (var type in typeSet)
|
||||
{
|
||||
var attribute = (ReflectAttribute?) Attribute.GetCustomAttribute(type, typeof(ReflectAttribute));
|
||||
var attribute = (ReflectAttribute?)Attribute.GetCustomAttribute(type, typeof(ReflectAttribute));
|
||||
|
||||
if (!(attribute?.Discoverable ?? ReflectAttribute.DEFAULT_DISCOVERABLE))
|
||||
continue;
|
||||
@@ -133,53 +137,56 @@ namespace Robust.Shared.Reflection
|
||||
|
||||
public bool TryLooseGetType(string name, [NotNullWhen(true)] out Type? type)
|
||||
{
|
||||
if (_looseTypeCache.TryGetValue(name, out type))
|
||||
return true;
|
||||
|
||||
// Check standard types first.
|
||||
switch (name)
|
||||
lock (_looseTypeCache)
|
||||
{
|
||||
case "Byte":
|
||||
type = typeof(byte);
|
||||
_looseTypeCache[name] = type;
|
||||
if (_looseTypeCache.TryGetValue(name, out type))
|
||||
return true;
|
||||
case "Bool":
|
||||
type = typeof(bool);
|
||||
_looseTypeCache[name] = type;
|
||||
return true;
|
||||
case "Double":
|
||||
type = typeof(double);
|
||||
_looseTypeCache[name] = type;
|
||||
return true;
|
||||
case "SByte":
|
||||
type = typeof(sbyte);
|
||||
_looseTypeCache[name] = type;
|
||||
return true;
|
||||
case "Single":
|
||||
type = typeof(float);
|
||||
_looseTypeCache[name] = type;
|
||||
return true;
|
||||
case "String":
|
||||
type = typeof(string);
|
||||
_looseTypeCache[name] = type;
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
foreach (var tryType in assembly.DefinedTypes)
|
||||
// Check standard types first.
|
||||
switch (name)
|
||||
{
|
||||
if (tryType.FullName!.EndsWith(name))
|
||||
{
|
||||
type = tryType;
|
||||
case "Byte":
|
||||
type = typeof(byte);
|
||||
_looseTypeCache[name] = type;
|
||||
return true;
|
||||
case "Bool":
|
||||
type = typeof(bool);
|
||||
_looseTypeCache[name] = type;
|
||||
return true;
|
||||
case "Double":
|
||||
type = typeof(double);
|
||||
_looseTypeCache[name] = type;
|
||||
return true;
|
||||
case "SByte":
|
||||
type = typeof(sbyte);
|
||||
_looseTypeCache[name] = type;
|
||||
return true;
|
||||
case "Single":
|
||||
type = typeof(float);
|
||||
_looseTypeCache[name] = type;
|
||||
return true;
|
||||
case "String":
|
||||
type = typeof(string);
|
||||
_looseTypeCache[name] = type;
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
foreach (var tryType in assembly.DefinedTypes)
|
||||
{
|
||||
if (tryType.FullName!.EndsWith(name))
|
||||
{
|
||||
type = tryType;
|
||||
_looseTypeCache[name] = type;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type = default;
|
||||
return false;
|
||||
type = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -204,35 +211,46 @@ namespace Robust.Shared.Reflection
|
||||
/// <inheritdoc />
|
||||
public string GetEnumReference(Enum @enum)
|
||||
{
|
||||
if (_reverseEnumCache.TryGetValue(@enum, out var reference))
|
||||
return reference;
|
||||
|
||||
// if there is more than one enum with the same basic name, the reference may need to be the fully qualified name.
|
||||
// but if possible we want to avoid that and use a shorter string.
|
||||
|
||||
var fullName = @enum.GetType().FullName!;
|
||||
var dotIndex = fullName.LastIndexOf('.');
|
||||
if (dotIndex > 0 && dotIndex != fullName.Length)
|
||||
using (_enumCacheLock.ReadGuard())
|
||||
{
|
||||
var name = fullName.Substring(dotIndex + 1);
|
||||
reference = $"enum.{name}.{@enum}";
|
||||
|
||||
if (TryParseEnumReference(reference, out var resolvedEnum, false) && resolvedEnum == @enum)
|
||||
{
|
||||
// TryParse will have filled in the cache already.
|
||||
if (_reverseEnumCache.TryGetValue(@enum, out var reference))
|
||||
return reference;
|
||||
}
|
||||
}
|
||||
|
||||
// If that failed, just use the full name.
|
||||
reference = $"enum.{fullName}.{@enum}";
|
||||
_reverseEnumCache[@enum] = reference;
|
||||
_enumCache[reference] = @enum;
|
||||
return reference;
|
||||
using (_enumCacheLock.WriteGuard())
|
||||
{
|
||||
if (_reverseEnumCache.TryGetValue(@enum, out var reference))
|
||||
return reference;
|
||||
|
||||
// if there is more than one enum with the same basic name, the reference may need to be the fully qualified name.
|
||||
// but if possible we want to avoid that and use a shorter string.
|
||||
|
||||
var fullName = @enum.GetType().FullName!;
|
||||
var dotIndex = fullName.LastIndexOf('.');
|
||||
if (dotIndex > 0 && dotIndex != fullName.Length)
|
||||
{
|
||||
var name = fullName.Substring(dotIndex + 1);
|
||||
reference = $"enum.{name}.{@enum}";
|
||||
|
||||
if (TryParseEnumReference(reference, out var resolvedEnum, false) && resolvedEnum == @enum)
|
||||
{
|
||||
// TryParse will have filled in the cache already.
|
||||
return reference;
|
||||
}
|
||||
}
|
||||
|
||||
// If that failed, just use the full name.
|
||||
reference = $"enum.{fullName}.{@enum}";
|
||||
_reverseEnumCache[@enum] = reference;
|
||||
_enumCache[reference] = @enum;
|
||||
return reference;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool TryParseEnumReference(string reference, [NotNullWhen(true)] out Enum? @enum, bool shouldThrow = true)
|
||||
public bool TryParseEnumReference(string reference, [NotNullWhen(true)] out Enum? @enum,
|
||||
bool shouldThrow = true)
|
||||
{
|
||||
if (!reference.StartsWith("enum."))
|
||||
{
|
||||
@@ -242,9 +260,13 @@ namespace Robust.Shared.Reflection
|
||||
|
||||
reference = reference.Substring(5);
|
||||
|
||||
if (_enumCache.TryGetValue(reference, out @enum))
|
||||
return true;
|
||||
using (_enumCacheLock.ReadGuard())
|
||||
{
|
||||
if (_enumCache.TryGetValue(reference, out @enum))
|
||||
return true;
|
||||
}
|
||||
|
||||
// Doesn't exist, add it.
|
||||
var dotIndex = reference.LastIndexOf('.');
|
||||
var typeName = reference.Substring(0, dotIndex);
|
||||
|
||||
@@ -262,9 +284,13 @@ namespace Robust.Shared.Reflection
|
||||
continue;
|
||||
}
|
||||
|
||||
@enum = (Enum) Enum.Parse(type, value);
|
||||
_enumCache[reference] = @enum;
|
||||
_reverseEnumCache[@enum] = reference;
|
||||
using (_enumCacheLock.WriteGuard())
|
||||
{
|
||||
@enum = (Enum)Enum.Parse(type, value);
|
||||
_enumCache[reference] = @enum;
|
||||
_reverseEnumCache[@enum] = reference;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -276,47 +302,53 @@ namespace Robust.Shared.Reflection
|
||||
|
||||
public Type? YamlTypeTagLookup(Type baseType, string typeName)
|
||||
{
|
||||
if (_yamlTypeTagCache.TryGetValue((baseType, typeName), out var type))
|
||||
using (_yamlTypeTagCacheLock.ReadGuard())
|
||||
{
|
||||
return type;
|
||||
if (_yamlTypeTagCache.TryGetValue((baseType, typeName), out var type))
|
||||
return type;
|
||||
}
|
||||
|
||||
Type? found = null;
|
||||
foreach (var derivedType in GetAllChildren(baseType))
|
||||
using (_yamlTypeTagCacheLock.WriteGuard())
|
||||
{
|
||||
if (!derivedType.IsPublic)
|
||||
if (_yamlTypeTagCache.TryGetValue((baseType, typeName), out var type))
|
||||
return type;
|
||||
Type? found = null;
|
||||
foreach (var derivedType in GetAllChildren(baseType))
|
||||
{
|
||||
continue;
|
||||
if (!derivedType.IsPublic)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (derivedType.Name == typeName)
|
||||
{
|
||||
found = derivedType;
|
||||
break;
|
||||
}
|
||||
|
||||
var serializedAttribute = derivedType.GetCustomAttribute<SerializedTypeAttribute>();
|
||||
|
||||
if (serializedAttribute != null &&
|
||||
serializedAttribute.SerializeName == typeName)
|
||||
{
|
||||
found = derivedType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (derivedType.Name == typeName)
|
||||
// Fallback
|
||||
if (found == null)
|
||||
{
|
||||
found = derivedType;
|
||||
break;
|
||||
TryLooseGetType(typeName, out found);
|
||||
|
||||
// If we may have gotten the type but it's still abstract then don't return it.
|
||||
if (found == null || found.IsAbstract || !found.IsAssignableTo(baseType))
|
||||
found = null;
|
||||
}
|
||||
|
||||
var serializedAttribute = derivedType.GetCustomAttribute<SerializedTypeAttribute>();
|
||||
|
||||
if (serializedAttribute != null &&
|
||||
serializedAttribute.SerializeName == typeName)
|
||||
{
|
||||
found = derivedType;
|
||||
break;
|
||||
}
|
||||
_yamlTypeTagCache.Add((baseType, typeName), found);
|
||||
return found;
|
||||
}
|
||||
|
||||
// Fallback
|
||||
if (found == null)
|
||||
{
|
||||
TryLooseGetType(typeName, out found);
|
||||
|
||||
// If we may have gotten the type but it's still abstract then don't return it.
|
||||
if (found == null || found.IsAbstract || !found.IsAssignableTo(baseType))
|
||||
found = null;
|
||||
}
|
||||
|
||||
_yamlTypeTagCache.Add((baseType, typeName), found);
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ using JetBrains.Annotations;
|
||||
using NetSerializer;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Network.Messages;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.Shared.Serialization
|
||||
@@ -78,6 +80,8 @@ namespace Robust.Shared.Serialization
|
||||
/// <param name="yaml">The YAML to collect strings from.</param>
|
||||
void AddStrings(YamlStream yaml);
|
||||
|
||||
void AddStrings(DataNode dataNode);
|
||||
|
||||
/// <summary>
|
||||
/// Add strings from the given enumeration to the mapping.
|
||||
/// </summary>
|
||||
|
||||
@@ -10,8 +10,8 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
public delegate void PopulateDelegateSignature(
|
||||
ref T target,
|
||||
MappingDataNode mappingDataNode,
|
||||
ISerializationContext? context,
|
||||
bool skipHook);
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context);
|
||||
|
||||
public delegate MappingDataNode SerializeDelegateSignature(
|
||||
T obj,
|
||||
@@ -21,8 +21,8 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
public delegate void CopyDelegateSignature(
|
||||
T source,
|
||||
ref T target,
|
||||
ISerializationContext? context,
|
||||
bool skipHook);
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context);
|
||||
|
||||
private delegate ValidationNode ValidateFieldDelegate(
|
||||
DataNode node,
|
||||
|
||||
@@ -22,8 +22,8 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
|
||||
var targetParam = Expression.Parameter(typeof(T).MakeByRefType());
|
||||
var mappingDataParam = Expression.Parameter(typeof(MappingDataNode));
|
||||
var hookCtxParam = Expression.Parameter(typeof(SerializationHookContext));
|
||||
var contextParam = Expression.Parameter(typeof(ISerializationContext));
|
||||
var skipHookParam = Expression.Parameter(typeof(bool));
|
||||
|
||||
var expressions = new List<BlockExpression>();
|
||||
|
||||
@@ -57,8 +57,8 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
"Read",
|
||||
new []{fieldType, typeof(ValueDataNode), fieldDefinition.Attribute.CustomTypeSerializer},
|
||||
Expression.Convert(nodeVariable, typeof(ValueDataNode)),
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
Expression.Constant(null, typeof(ISerializationManager.InstantiationDelegate<>).MakeGenericType(fieldType)),
|
||||
Expression.Constant(!isNullable)), nullable))),
|
||||
Expression.Constant(typeof(ValueDataNode))));
|
||||
@@ -72,8 +72,8 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
"Read",
|
||||
new []{fieldType, typeof(SequenceDataNode), fieldDefinition.Attribute.CustomTypeSerializer},
|
||||
Expression.Convert(nodeVariable, typeof(SequenceDataNode)),
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
Expression.Constant(null, typeof(ISerializationManager.InstantiationDelegate<>).MakeGenericType(fieldType)),
|
||||
Expression.Constant(!isNullable)), nullable))),
|
||||
Expression.Constant(typeof(SequenceDataNode))));
|
||||
@@ -87,8 +87,8 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
"Read",
|
||||
new []{fieldType, typeof(MappingDataNode), fieldDefinition.Attribute.CustomTypeSerializer},
|
||||
Expression.Convert(nodeVariable, typeof(MappingDataNode)),
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
Expression.Constant(null, typeof(ISerializationManager.InstantiationDelegate<>).MakeGenericType(fieldType)),
|
||||
Expression.Constant(!isNullable)), nullable))),
|
||||
Expression.Constant(typeof(MappingDataNode))));
|
||||
@@ -114,8 +114,8 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
"Read",
|
||||
new[] { fieldDefinition.FieldType },
|
||||
nodeVariable,
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
Expression.Constant(null, typeof(ISerializationManager.InstantiationDelegate<>).MakeGenericType(fieldDefinition.FieldType)),
|
||||
Expression.Constant(!isNullable)));
|
||||
}
|
||||
@@ -158,8 +158,8 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
Expression.Block(expressions),
|
||||
targetParam,
|
||||
mappingDataParam,
|
||||
contextParam,
|
||||
skipHookParam).Compile();
|
||||
hookCtxParam,
|
||||
contextParam).Compile();
|
||||
}
|
||||
|
||||
private SerializeDelegateSignature EmitSerializeDelegate(SerializationManager manager)
|
||||
@@ -315,7 +315,7 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
var sourceParam = Expression.Parameter(typeof(T));
|
||||
var targetParam = Expression.Parameter(typeof(T).MakeByRefType());
|
||||
var contextParam = Expression.Parameter(typeof(ISerializationContext));
|
||||
var skipHookParam = Expression.Parameter(typeof(bool));
|
||||
var hookCtxParam = Expression.Parameter(typeof(SerializationHookContext));
|
||||
|
||||
var expressions = new List<Expression>();
|
||||
|
||||
@@ -348,8 +348,8 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
new[]{fieldType, fieldDefinition.Attribute.CustomTypeSerializer},
|
||||
sourceAccess,
|
||||
targetValue,
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
Expression.Constant(!isNullable)),
|
||||
Expression.Assign(finalTargetValue, Expression.Convert(targetValue, fieldDefinition.FieldType)));
|
||||
|
||||
@@ -381,8 +381,8 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
"CreateCopy",
|
||||
new []{fieldDefinition.FieldType, fieldDefinition.Attribute.CustomTypeSerializer},
|
||||
AccessExpression(i, sourceParam),
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
Expression.Constant(!isNullable));
|
||||
}
|
||||
else
|
||||
@@ -392,8 +392,8 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
"CreateCopy",
|
||||
new[] { fieldDefinition.FieldType },
|
||||
AccessExpression(i, sourceParam),
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
Expression.Constant(!isNullable));
|
||||
}
|
||||
|
||||
@@ -404,8 +404,8 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
Expression.Block(expressions),
|
||||
sourceParam,
|
||||
targetParam,
|
||||
contextParam,
|
||||
skipHookParam).Compile();
|
||||
hookCtxParam,
|
||||
contextParam).Compile();
|
||||
}
|
||||
|
||||
private ValidateFieldDelegate EmitFieldValidationDelegate(SerializationManager manager, int i)
|
||||
|
||||
@@ -87,6 +87,12 @@ namespace Robust.Shared.Serialization.Manager
|
||||
/// <param name="notNullableOverride">Set true if a reference Type should not allow null. Not necessary for value types.</param>
|
||||
/// <returns>The deserialized object or null.</returns>
|
||||
public object? Read(Type type, DataNode node, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false);
|
||||
public object? Read(
|
||||
Type type,
|
||||
DataNode node,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false);
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a node into a populated object of the given generic type <see cref="T"/>
|
||||
@@ -99,6 +105,12 @@ namespace Robust.Shared.Serialization.Manager
|
||||
/// <typeparam name="T">The type of object to create and populate.</typeparam>
|
||||
/// <returns>The deserialized object, or null.</returns>
|
||||
T Read<T>(DataNode node, ISerializationContext? context = null, bool skipHook = false, InstantiationDelegate<T>? instanceProvider = null, bool notNullableOverride = false);
|
||||
T Read<T>(
|
||||
DataNode node,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
InstantiationDelegate<T>? instanceProvider = null,
|
||||
bool notNullableOverride = false);
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -116,6 +128,15 @@ namespace Robust.Shared.Serialization.Manager
|
||||
T Read<T, TNode>(ITypeReader<T, TNode> reader, TNode node, ISerializationContext? context = null,
|
||||
bool skipHook = false, InstantiationDelegate<T>? instanceProvider = null, bool notNullableOverride = false) where TNode : DataNode;
|
||||
|
||||
T Read<T, TNode>(
|
||||
ITypeReader<T, TNode> reader,
|
||||
TNode node,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
InstantiationDelegate<T>? instanceProvider = null,
|
||||
bool notNullableOverride = false)
|
||||
where TNode : DataNode;
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a node into a populated object of the given generic type <see cref="T"/> using the provided <see cref="ITypeReader{TType,TNode}"/> type.
|
||||
/// </summary>
|
||||
@@ -131,6 +152,15 @@ namespace Robust.Shared.Serialization.Manager
|
||||
T Read<T, TNode, TReader>(TNode node, ISerializationContext? context = null,
|
||||
bool skipHook = false, InstantiationDelegate<T>? instanceProvider = null, bool notNullableOverride = false) where TNode : DataNode where TReader : ITypeReader<T, TNode>;
|
||||
|
||||
T Read<T, TNode, TReader>(
|
||||
TNode node,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
InstantiationDelegate<T>? instanceProvider = null,
|
||||
bool notNullableOverride = false)
|
||||
where TNode : DataNode
|
||||
where TReader : ITypeReader<T, TNode>;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Write
|
||||
@@ -226,6 +256,12 @@ namespace Robust.Shared.Serialization.Manager
|
||||
/// <param name="skipHook">Whether or not to skip running <see cref="ISerializationHooks"/></param>
|
||||
/// <param name="notNullableOverride">Set true if a reference Type should not allow null. Not necessary for value types.</param>
|
||||
void CopyTo(object source, ref object? target, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false);
|
||||
void CopyTo(
|
||||
object source,
|
||||
ref object? target,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false);
|
||||
|
||||
/// <summary>
|
||||
/// Copies the values of one object into another.
|
||||
@@ -239,6 +275,12 @@ namespace Robust.Shared.Serialization.Manager
|
||||
/// <param name="notNullableOverride">Set true if a reference Type should not allow null. Not necessary for value types.</param>
|
||||
/// <typeparam name="T">The type of the objects to copy from and into.</typeparam>
|
||||
void CopyTo<T>(T source, ref T? target, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false);
|
||||
void CopyTo<T>(
|
||||
T source,
|
||||
ref T? target,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false);
|
||||
|
||||
/// <summary>
|
||||
/// Copies the values of one object into another using a specified <see cref="ITypeCopier{TType}"/> instance.
|
||||
@@ -253,6 +295,13 @@ namespace Robust.Shared.Serialization.Manager
|
||||
/// <param name="notNullableOverride">Set true if a reference Type should not allow null. Not necessary for value types.</param>
|
||||
/// <typeparam name="T">The type of the objects to copy from and into.</typeparam>
|
||||
void CopyTo<T>(ITypeCopier<T> copier, T source, ref T? target, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false);
|
||||
void CopyTo<T>(
|
||||
ITypeCopier<T> copier,
|
||||
T source,
|
||||
ref T? target,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false);
|
||||
|
||||
/// <summary>
|
||||
/// Copies the values of one object into another using a specified <see cref="ITypeCopier{TType}"/> type.
|
||||
@@ -267,6 +316,13 @@ namespace Robust.Shared.Serialization.Manager
|
||||
/// <typeparam name="T">The type of the objects to copy from and into.</typeparam>
|
||||
/// <typeparam name="TCopier">The type of the <see cref="ITypeCopier{TType}"/>.</typeparam>
|
||||
void CopyTo<T, TCopier>(T source, ref T? target, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false) where TCopier : ITypeCopier<T>;
|
||||
void CopyTo<T, TCopier>(
|
||||
T source,
|
||||
ref T? target,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false)
|
||||
where TCopier : ITypeCopier<T>;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of the given object.
|
||||
@@ -279,6 +335,13 @@ namespace Robust.Shared.Serialization.Manager
|
||||
[MustUseReturnValue]
|
||||
object? CreateCopy(object? source, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false);
|
||||
|
||||
[MustUseReturnValue]
|
||||
object? CreateCopy(
|
||||
object? source,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of the given object.
|
||||
/// </summary>
|
||||
@@ -291,6 +354,13 @@ namespace Robust.Shared.Serialization.Manager
|
||||
[MustUseReturnValue]
|
||||
T CreateCopy<T>(T source, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false);
|
||||
|
||||
[MustUseReturnValue]
|
||||
T CreateCopy<T>(
|
||||
T source,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of the given object using a specified <see cref="ITypeCopyCreator{TType}"/> instance.
|
||||
/// </summary>
|
||||
@@ -304,6 +374,14 @@ namespace Robust.Shared.Serialization.Manager
|
||||
[MustUseReturnValue]
|
||||
T CreateCopy<T>(ITypeCopyCreator<T> copyCreator, T source, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false);
|
||||
|
||||
[MustUseReturnValue]
|
||||
T CreateCopy<T>(
|
||||
ITypeCopyCreator<T> copyCreator,
|
||||
T source,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of the given object using a specified <see cref="ITypeCopyCreator{TType}"/> type.
|
||||
/// </summary>
|
||||
@@ -317,6 +395,14 @@ namespace Robust.Shared.Serialization.Manager
|
||||
[MustUseReturnValue]
|
||||
T CreateCopy<T, TCopyCreator>(T source, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false) where TCopyCreator : ITypeCopyCreator<T>;
|
||||
|
||||
[MustUseReturnValue]
|
||||
T CreateCopy<T, TCopyCreator>(
|
||||
T source,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false)
|
||||
where TCopyCreator : ITypeCopyCreator<T>;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Flags And Constants
|
||||
|
||||
@@ -7,6 +7,9 @@ using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
// Avoid accidentally mixing up overloads.
|
||||
// ReSharper disable RedundantTypeArgumentsOfMethod
|
||||
|
||||
namespace Robust.Shared.Serialization.Manager;
|
||||
|
||||
public sealed partial class SerializationManager
|
||||
@@ -14,14 +17,14 @@ public sealed partial class SerializationManager
|
||||
private delegate void CopyToBoxingDelegate(
|
||||
object source,
|
||||
ref object target,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null);
|
||||
|
||||
private delegate bool CopyToGenericDelegate<T>(
|
||||
T source,
|
||||
ref T target,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false);
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null);
|
||||
|
||||
private readonly ConcurrentDictionary<Type, object> _copyToGenericDelegates = new();
|
||||
private readonly ConcurrentDictionary<(Type baseType, Type actualType), object> _copyToGenericBaseDelegates = new();
|
||||
@@ -34,7 +37,7 @@ public sealed partial class SerializationManager
|
||||
var managerConst = Expression.Constant(manager);
|
||||
var sourceParam = Expression.Parameter(typeof(object), "source");
|
||||
var targetParam = Expression.Parameter(typeof(object).MakeByRefType(), "target");
|
||||
var skipHookParam = Expression.Parameter(typeof(bool), "skipHook");
|
||||
var hookCtxParam = Expression.Parameter(typeof(SerializationHookContext), "hookCtx");
|
||||
var contextParam = Expression.Parameter(typeof(ISerializationContext), "context");
|
||||
|
||||
var targetVar = Expression.Variable(type);
|
||||
@@ -48,8 +51,8 @@ public sealed partial class SerializationManager
|
||||
new[] { type },
|
||||
Expression.Convert(sourceParam, type),
|
||||
targetVar,
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
Expression.Constant(false)), //we already handled the override before calling this
|
||||
Expression.Assign(targetParam, Expression.Convert(targetVar, typeof(object))));
|
||||
|
||||
@@ -57,7 +60,7 @@ public sealed partial class SerializationManager
|
||||
block,
|
||||
sourceParam,
|
||||
targetParam,
|
||||
skipHookParam,
|
||||
hookCtxParam,
|
||||
contextParam).Compile();
|
||||
}, this);
|
||||
}
|
||||
@@ -69,7 +72,7 @@ public sealed partial class SerializationManager
|
||||
var instanceParam = Expression.Constant(manager);
|
||||
var sourceParam = Expression.Parameter(baseType, "source");
|
||||
var targetParam = Expression.Parameter(baseType.MakeByRefType(), "target");
|
||||
var skipHookParam = Expression.Parameter(typeof(bool), "skipHook");
|
||||
var hookCtxParam = Expression.Parameter(typeof(SerializationHookContext), "hookCtx");
|
||||
var contextParam = Expression.Parameter(typeof(ISerializationContext), "context");
|
||||
|
||||
Expression call;
|
||||
@@ -90,8 +93,8 @@ public sealed partial class SerializationManager
|
||||
copierConstant,
|
||||
sourceVar,
|
||||
targetVar,
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
Expression.Constant(false)),
|
||||
Expression.Constant(true));
|
||||
}
|
||||
@@ -99,7 +102,7 @@ public sealed partial class SerializationManager
|
||||
{
|
||||
call = Expression.Call(instanceParam, nameof(CopyToInternal), new[] { actualType }, sourceVar, targetVar,
|
||||
Expression.Constant(manager.GetDefinition(actualType), typeof(DataDefinition<>).MakeGenericType(actualType)),
|
||||
instanceParam, skipHookParam, contextParam);
|
||||
instanceParam, hookCtxParam, contextParam);
|
||||
}
|
||||
|
||||
if (!sameType)
|
||||
@@ -113,7 +116,13 @@ public sealed partial class SerializationManager
|
||||
returnVar);
|
||||
}
|
||||
|
||||
return Expression.Lambda<CopyToGenericDelegate<T>>(call, sourceParam, targetParam, contextParam, skipHookParam).Compile();
|
||||
return Expression.Lambda<CopyToGenericDelegate<T>>(
|
||||
call,
|
||||
sourceParam,
|
||||
targetParam,
|
||||
hookCtxParam,
|
||||
contextParam)
|
||||
.Compile();
|
||||
}
|
||||
|
||||
var type = typeof(T);
|
||||
@@ -129,12 +138,12 @@ public sealed partial class SerializationManager
|
||||
|
||||
private delegate object CreateCopyBoxingDelegate(
|
||||
object source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null);
|
||||
|
||||
private delegate T CreateCopyGenericDelegate<T>(
|
||||
T source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null);
|
||||
|
||||
private readonly ConcurrentDictionary<Type, object> _createCopyGenericDelegates = new();
|
||||
@@ -146,7 +155,7 @@ public sealed partial class SerializationManager
|
||||
{
|
||||
var managerConst = Expression.Constant(manager);
|
||||
var sourceParam = Expression.Parameter(typeof(object), "source");
|
||||
var skipHookParam = Expression.Parameter(typeof(bool), "skipHook");
|
||||
var hookCtxParam = Expression.Parameter(typeof(SerializationHookContext), "hookCtx");
|
||||
var contextParam = Expression.Parameter(typeof(ISerializationContext), "context");
|
||||
|
||||
return Expression.Lambda<CreateCopyBoxingDelegate>(
|
||||
@@ -155,11 +164,11 @@ public sealed partial class SerializationManager
|
||||
nameof(CreateCopy),
|
||||
new[] { type },
|
||||
Expression.Convert(sourceParam, type),
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
Expression.Constant(false)), typeof(object)),
|
||||
sourceParam,
|
||||
skipHookParam,
|
||||
hookCtxParam,
|
||||
contextParam).Compile();
|
||||
}, this);
|
||||
}
|
||||
@@ -171,7 +180,7 @@ public sealed partial class SerializationManager
|
||||
{
|
||||
var instanceParam = Expression.Constant(manager);
|
||||
var sourceParam = Expression.Parameter(type, "source");
|
||||
var skipHookParam = Expression.Parameter(typeof(bool), "skipHook");
|
||||
var hookCtxParam = Expression.Parameter(typeof(SerializationHookContext), "hookCtx");
|
||||
var contextParam = Expression.Parameter(typeof(ISerializationContext), "context");
|
||||
|
||||
var actualType = type;
|
||||
@@ -188,8 +197,8 @@ public sealed partial class SerializationManager
|
||||
new []{type},
|
||||
copierConst,
|
||||
sourceParamAccess,
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
Expression.Constant(false));
|
||||
}
|
||||
else if (type.IsArray)
|
||||
@@ -199,8 +208,8 @@ public sealed partial class SerializationManager
|
||||
nameof(CreateArrayCopy),
|
||||
new[]{type.GetElementType()!},
|
||||
sourceParamAccess,
|
||||
contextParam,
|
||||
skipHookParam);
|
||||
hookCtxParam,
|
||||
contextParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -211,8 +220,8 @@ public sealed partial class SerializationManager
|
||||
nameof(CreateCopy),
|
||||
Type.EmptyTypes,
|
||||
Expression.Convert(sourceParam, typeof(object)),
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
Expression.Constant(false)), type);
|
||||
}
|
||||
else
|
||||
@@ -222,8 +231,8 @@ public sealed partial class SerializationManager
|
||||
nameof(CreateCopyInternal),
|
||||
new[] {type},
|
||||
sourceParamAccess,
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
Expression.Constant(manager.GetDefinition(type), typeof(DataDefinition<>).MakeGenericType(type)));
|
||||
}
|
||||
}
|
||||
@@ -231,7 +240,7 @@ public sealed partial class SerializationManager
|
||||
return Expression.Lambda<CreateCopyGenericDelegate<T>>(
|
||||
Expression.Convert(call, actualType),
|
||||
sourceParam,
|
||||
skipHookParam,
|
||||
hookCtxParam,
|
||||
contextParam).Compile();
|
||||
}, this);
|
||||
}
|
||||
@@ -249,7 +258,7 @@ public sealed partial class SerializationManager
|
||||
ref TCommon target,
|
||||
DataDefinition<TCommon>? definition,
|
||||
ISerializationManager serializationManager,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context)
|
||||
where TCommon : notnull
|
||||
{
|
||||
@@ -257,7 +266,7 @@ public sealed partial class SerializationManager
|
||||
context.SerializerProvider.TryGetTypeSerializer<ITypeCopier<TCommon>, TCommon>(out var copier))
|
||||
{
|
||||
var commonTarget = target;
|
||||
copier.CopyTo(this, source, ref commonTarget, skipHook, context);
|
||||
copier.CopyTo(this, source, ref commonTarget, hookCtx, context);
|
||||
}
|
||||
|
||||
if (ShouldReturnSource(typeof(TCommon))) //todo paul can be precomputed
|
||||
@@ -289,7 +298,7 @@ public sealed partial class SerializationManager
|
||||
|
||||
for (var i = 0; i < sourceArray.Length; i++)
|
||||
{
|
||||
newArray.SetValue(CreateCopy(sourceArray.GetValue(i), context, skipHook), i);
|
||||
newArray.SetValue(CreateCopy(sourceArray.GetValue(i), hookCtx, context), i);
|
||||
}
|
||||
|
||||
//todo paul serv3 fix
|
||||
@@ -303,22 +312,22 @@ public sealed partial class SerializationManager
|
||||
return false;
|
||||
}
|
||||
|
||||
definition.CopyTo(source, ref target, context, skipHook);
|
||||
definition.CopyTo(source, ref target, hookCtx, context);
|
||||
return true;
|
||||
}
|
||||
|
||||
private T[] CreateArrayCopy<T>(T[] source, ISerializationContext context, bool skipHook)
|
||||
private T[] CreateArrayCopy<T>(T[] source, SerializationHookContext hookCtx, ISerializationContext context)
|
||||
{
|
||||
var copy = new T[source.Length];
|
||||
for (int i = 0; i < source.Length; i++)
|
||||
{
|
||||
copy[i] = CreateCopy(source[i], context, skipHook);
|
||||
copy[i] = CreateCopy(source[i], hookCtx, context);
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
private T CreateCopyInternal<T>(T source, ISerializationContext context, bool skipHook, DataDefinition<T>? definition) where T : notnull
|
||||
private T CreateCopyInternal<T>(T source, SerializationHookContext hookCtx, ISerializationContext context, DataDefinition<T>? definition) where T : notnull
|
||||
{
|
||||
if (ShouldReturnSource(typeof(T)))
|
||||
return source;
|
||||
@@ -329,7 +338,7 @@ public sealed partial class SerializationManager
|
||||
var isRecord = definition?.IsRecord ?? false;
|
||||
var target = GetOrCreateInstantiator<T>(isRecord)();
|
||||
|
||||
if (!GetOrCreateCopyToGenericDelegate<T>(source)(source, ref target, context, skipHook))
|
||||
if (!GetOrCreateCopyToGenericDelegate<T>(source)(source, ref target, hookCtx, context))
|
||||
{
|
||||
throw new CopyToFailedException<T>();
|
||||
}
|
||||
@@ -342,6 +351,16 @@ public sealed partial class SerializationManager
|
||||
}
|
||||
|
||||
public void CopyTo(object? source, ref object? target, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false)
|
||||
{
|
||||
CopyTo(source, ref target, SerializationHookContext.ForSkipHooks(skipHook), context, notNullableOverride);
|
||||
}
|
||||
|
||||
public void CopyTo(
|
||||
object? source,
|
||||
ref object? target,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
@@ -352,7 +371,7 @@ public sealed partial class SerializationManager
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
target = CreateCopy(source, context, skipHook);
|
||||
target = CreateCopy(source, hookCtx, context);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -361,10 +380,20 @@ public sealed partial class SerializationManager
|
||||
throw new InvalidOperationException($"Could not find common type in Copy for types {source.GetType()} and {target.GetType()}!");
|
||||
}
|
||||
|
||||
GetOrCreateCopyToBoxingDelegate(commonType)(source, ref target, skipHook, context);
|
||||
GetOrCreateCopyToBoxingDelegate(commonType)(source, ref target, hookCtx, context);
|
||||
}
|
||||
|
||||
public void CopyTo<T>(T source, ref T? target, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false)
|
||||
{
|
||||
CopyTo<T>(source, ref target, SerializationHookContext.ForSkipHooks(skipHook), context, notNullableOverride);
|
||||
}
|
||||
|
||||
public void CopyTo<T>(
|
||||
T source,
|
||||
ref T? target,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
@@ -375,21 +404,37 @@ public sealed partial class SerializationManager
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
target = CreateCopy(source, context, skipHook)!;
|
||||
target = CreateCopy(source, hookCtx, context)!;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetOrCreateCopyToGenericDelegate<T>(source)(source, ref target, context))
|
||||
if (!GetOrCreateCopyToGenericDelegate<T>(source)(source, ref target, hookCtx, context))
|
||||
{
|
||||
target = CreateCopy(source, context);
|
||||
target = CreateCopy(source, hookCtx, context);
|
||||
}
|
||||
|
||||
if(!skipHook && target is ISerializationHooks hookres)
|
||||
hookres.AfterDeserialization();
|
||||
RunAfterHook(target, hookCtx);
|
||||
}
|
||||
|
||||
public void CopyTo<T>(ITypeCopier<T> copier, T source, ref T? target, ISerializationContext? context = null,
|
||||
bool skipHook = false, bool notNullableOverride = false)
|
||||
{
|
||||
CopyTo<T>(
|
||||
copier,
|
||||
source,
|
||||
ref target,
|
||||
SerializationHookContext.ForSkipHooks(skipHook),
|
||||
context,
|
||||
notNullableOverride);
|
||||
}
|
||||
|
||||
public void CopyTo<T>(
|
||||
ITypeCopier<T> copier,
|
||||
T source,
|
||||
ref T? target,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
@@ -400,19 +445,43 @@ public sealed partial class SerializationManager
|
||||
|
||||
target ??= GetOrCreateInstantiator<T>(false)();
|
||||
|
||||
copier.CopyTo(this, source, ref target, skipHook, context);
|
||||
copier.CopyTo(this, source, ref target, hookCtx, context);
|
||||
|
||||
if(!skipHook && target is ISerializationHooks hookres)
|
||||
hookres.AfterDeserialization();
|
||||
RunAfterHook(target, hookCtx);
|
||||
}
|
||||
|
||||
public void CopyTo<T, TCopier>(T source, ref T? target, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false)
|
||||
where TCopier : ITypeCopier<T>
|
||||
{
|
||||
CopyTo(GetOrCreateCustomTypeSerializer<TCopier>(), source, ref target, context, skipHook, notNullableOverride);
|
||||
CopyTo<T, TCopier>(
|
||||
source,
|
||||
ref target,
|
||||
SerializationHookContext.ForSkipHooks(skipHook),
|
||||
context,
|
||||
notNullableOverride);
|
||||
}
|
||||
|
||||
public void CopyTo<T, TCopier>(
|
||||
T source,
|
||||
ref T? target,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false)
|
||||
where TCopier : ITypeCopier<T>
|
||||
{
|
||||
CopyTo(GetOrCreateCustomTypeSerializer<TCopier>(), source, ref target, hookCtx, context, notNullableOverride);
|
||||
}
|
||||
|
||||
public object? CreateCopy(object? source, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false)
|
||||
{
|
||||
return CreateCopy(source, SerializationHookContext.ForSkipHooks(skipHook), context, notNullableOverride);
|
||||
}
|
||||
|
||||
public object? CreateCopy(
|
||||
object? source,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
@@ -420,10 +489,19 @@ public sealed partial class SerializationManager
|
||||
return null;
|
||||
}
|
||||
|
||||
return GetOrCreateCreateCopyBoxingDelegate(source.GetType())(source, skipHook, context);
|
||||
return GetOrCreateCreateCopyBoxingDelegate(source.GetType())(source, hookCtx, context);
|
||||
}
|
||||
|
||||
public T CreateCopy<T>(T source, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false)
|
||||
{
|
||||
return CreateCopy(source, SerializationHookContext.ForSkipHooks(skipHook), context, notNullableOverride);
|
||||
}
|
||||
|
||||
public T CreateCopy<T>(
|
||||
T source,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
@@ -431,17 +509,29 @@ public sealed partial class SerializationManager
|
||||
return default!;
|
||||
}
|
||||
|
||||
var res = GetOrCreateCreateCopyGenericDelegate<T>()(source, skipHook, context);
|
||||
if (!skipHook && res is ISerializationHooks hooks)
|
||||
{
|
||||
hooks.AfterDeserialization();
|
||||
}
|
||||
var res = GetOrCreateCreateCopyGenericDelegate<T>()(source, hookCtx, context);
|
||||
RunAfterHook(res, hookCtx);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
public T CreateCopy<T>(ITypeCopyCreator<T> copyCreator, T source, ISerializationContext? context = null,
|
||||
bool skipHook = false, bool notNullableOverride = false)
|
||||
{
|
||||
return CreateCopy<T>(
|
||||
copyCreator,
|
||||
source,
|
||||
SerializationHookContext.ForSkipHooks(skipHook),
|
||||
context,
|
||||
notNullableOverride);
|
||||
}
|
||||
|
||||
public T CreateCopy<T>(
|
||||
ITypeCopyCreator<T> copyCreator,
|
||||
T source,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
@@ -449,11 +539,8 @@ public sealed partial class SerializationManager
|
||||
return default!;
|
||||
}
|
||||
|
||||
var res = copyCreator.CreateCopy(this, source, skipHook, context);
|
||||
if (!skipHook && res is ISerializationHooks hooks)
|
||||
{
|
||||
hooks.AfterDeserialization();
|
||||
}
|
||||
var res = copyCreator.CreateCopy(this, source, hookCtx, context);
|
||||
RunAfterHook(res, hookCtx);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -461,6 +548,19 @@ public sealed partial class SerializationManager
|
||||
public T CreateCopy<T, TCopyCreator>(T source, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false)
|
||||
where TCopyCreator : ITypeCopyCreator<T>
|
||||
{
|
||||
return CreateCopy(GetOrCreateCustomTypeSerializer<TCopyCreator>(), source, context, skipHook, notNullableOverride);
|
||||
return CreateCopy<T, TCopyCreator>(
|
||||
source,
|
||||
SerializationHookContext.ForSkipHooks(skipHook),
|
||||
context,
|
||||
notNullableOverride);
|
||||
}
|
||||
|
||||
public T CreateCopy<T, TCopyCreator>(
|
||||
T source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false)
|
||||
where TCopyCreator : ITypeCopyCreator<T>
|
||||
{
|
||||
return CreateCopy(GetOrCreateCustomTypeSerializer<TCopyCreator>(), source, hookCtx, context, notNullableOverride);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,19 +12,22 @@ using Robust.Shared.Serialization.Markdown.Value;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
// Avoid accidentally mixing up overloads.
|
||||
// ReSharper disable RedundantTypeArgumentsOfMethod
|
||||
|
||||
namespace Robust.Shared.Serialization.Manager
|
||||
{
|
||||
public partial class SerializationManager
|
||||
{
|
||||
private delegate object? ReadBoxingDelegate(
|
||||
DataNode node,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false);
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null);
|
||||
|
||||
private delegate T ReadGenericDelegate<T>(
|
||||
DataNode node,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false,
|
||||
ISerializationManager.InstantiationDelegate<T>? instanceProvider = null);
|
||||
|
||||
private readonly ConcurrentDictionary<(Type type, bool notNullableOverride), ReadBoxingDelegate> _readBoxingDelegates = new();
|
||||
@@ -32,6 +35,21 @@ namespace Robust.Shared.Serialization.Manager
|
||||
private readonly ConcurrentDictionary<(Type value, Type node, bool notNullableOverride), object> _readGenericDelegates = new();
|
||||
|
||||
public T Read<T>(DataNode node, ISerializationContext? context = null, bool skipHook = false, ISerializationManager.InstantiationDelegate<T>? instanceProvider = null, bool notNullableOverride = false)
|
||||
{
|
||||
return Read<T>(
|
||||
node,
|
||||
SerializationHookContext.ForSkipHooks(skipHook),
|
||||
context,
|
||||
instanceProvider,
|
||||
notNullableOverride);
|
||||
}
|
||||
|
||||
public T Read<T>(
|
||||
DataNode node,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<T>? instanceProvider = null,
|
||||
bool notNullableOverride = false)
|
||||
{
|
||||
if (node.Tag?.StartsWith("!type:") ?? false)
|
||||
{
|
||||
@@ -58,19 +76,40 @@ namespace Robust.Shared.Serialization.Manager
|
||||
return ((ReadGenericDelegate<T>)_readGenericBaseDelegates.GetOrAdd(
|
||||
(typeof(T), type, node.GetType()!, notNullableOverride),
|
||||
static (tuple, manager) => ReadDelegateValueFactory(tuple.baseType, tuple.actualType, tuple.node, tuple.notNullableOverride, manager),
|
||||
this))(node, context, skipHook, instanceProvider);
|
||||
this))(node, hookCtx, context, instanceProvider);
|
||||
}
|
||||
|
||||
return ((ReadGenericDelegate<T>)_readGenericDelegates.GetOrAdd((typeof(T), node.GetType()!, notNullableOverride),
|
||||
static (tuple, manager) => ReadDelegateValueFactory(tuple.value, tuple.value, tuple.node, tuple.notNullableOverride, manager), this))(node, context, skipHook, instanceProvider);
|
||||
static (tuple, manager) => ReadDelegateValueFactory(tuple.value, tuple.value, tuple.node, tuple.notNullableOverride, manager), this))(node, hookCtx, context, instanceProvider);
|
||||
|
||||
}
|
||||
|
||||
public T Read<T, TNode>(ITypeReader<T, TNode> reader, TNode node, ISerializationContext? context = null,
|
||||
bool skipHook = false, ISerializationManager.InstantiationDelegate<T>? instanceProvider = null, bool notNullableOverride = false)
|
||||
where TNode : DataNode
|
||||
{
|
||||
var val = reader.Read(this, node, DependencyCollection, skipHook, context, instanceProvider);
|
||||
if(notNullableOverride) Debug.Assert(val != null, "Reader call returned null value! Forbidden!");
|
||||
return Read<T, TNode>(
|
||||
reader,
|
||||
node,
|
||||
SerializationHookContext.ForSkipHooks(skipHook),
|
||||
context,
|
||||
instanceProvider,
|
||||
notNullableOverride);
|
||||
}
|
||||
|
||||
public T Read<T, TNode>(
|
||||
ITypeReader<T, TNode> reader,
|
||||
TNode node,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<T>? instanceProvider = null,
|
||||
bool notNullableOverride = false)
|
||||
where TNode : DataNode
|
||||
{
|
||||
var val = reader.Read(this, node, DependencyCollection, hookCtx, context, instanceProvider);
|
||||
if (notNullableOverride)
|
||||
Debug.Assert(val != null, "Reader call returned null value! Forbidden!");
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -78,13 +117,45 @@ namespace Robust.Shared.Serialization.Manager
|
||||
bool skipHook = false, ISerializationManager.InstantiationDelegate<T>? instanceProvider = null, bool notNullableOverride = false) where TNode : DataNode
|
||||
where TReader : ITypeReader<T, TNode>
|
||||
{
|
||||
return Read(GetOrCreateCustomTypeSerializer<TReader>(), node, context, skipHook,
|
||||
instanceProvider, notNullableOverride);
|
||||
return Read<T, TNode, TReader>(
|
||||
node,
|
||||
SerializationHookContext.ForSkipHooks(skipHook),
|
||||
context,
|
||||
instanceProvider,
|
||||
notNullableOverride);
|
||||
}
|
||||
|
||||
public T Read<T, TNode, TReader>(
|
||||
TNode node,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<T>? instanceProvider = null,
|
||||
bool notNullableOverride = false)
|
||||
where TNode : DataNode
|
||||
where TReader : ITypeReader<T, TNode>
|
||||
{
|
||||
return Read(
|
||||
GetOrCreateCustomTypeSerializer<TReader>(),
|
||||
node,
|
||||
hookCtx,
|
||||
context,
|
||||
instanceProvider,
|
||||
notNullableOverride);
|
||||
}
|
||||
|
||||
public object? Read(Type type, DataNode node, ISerializationContext? context = null, bool skipHook = false, bool notNullableOverride = false)
|
||||
{
|
||||
return GetOrCreateBoxingReadDelegate(type, notNullableOverride)(node, context, skipHook);
|
||||
return Read(type, node, SerializationHookContext.ForSkipHooks(skipHook), context, notNullableOverride);
|
||||
}
|
||||
|
||||
public object? Read(
|
||||
Type type,
|
||||
DataNode node,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
bool notNullableOverride = false)
|
||||
{
|
||||
return GetOrCreateBoxingReadDelegate(type, notNullableOverride)(node, hookCtx, context);
|
||||
}
|
||||
|
||||
private ReadBoxingDelegate GetOrCreateBoxingReadDelegate(Type type, bool notNullableOverride = false)
|
||||
@@ -96,23 +167,23 @@ namespace Robust.Shared.Serialization.Manager
|
||||
|
||||
var nodeParam = Expression.Variable(typeof(DataNode));
|
||||
var contextParam = Expression.Variable(typeof(ISerializationContext));
|
||||
var skipHookParam = Expression.Variable(typeof(bool));
|
||||
var hookCtxParam = Expression.Variable(typeof(SerializationHookContext));
|
||||
|
||||
var call = Expression.Convert(Expression.Call(
|
||||
managerConst,
|
||||
nameof(Read),
|
||||
new[] { type },
|
||||
nodeParam,
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
Expression.Constant(null, typeof(ISerializationManager.InstantiationDelegate<>).MakeGenericType(type)),
|
||||
Expression.Constant(tuple.notNullableOverride)), typeof(object));
|
||||
|
||||
return Expression.Lambda<ReadBoxingDelegate>(
|
||||
call,
|
||||
nodeParam,
|
||||
contextParam,
|
||||
skipHookParam).Compile();
|
||||
hookCtxParam,
|
||||
contextParam).Compile();
|
||||
}, this);
|
||||
}
|
||||
|
||||
@@ -124,7 +195,7 @@ namespace Robust.Shared.Serialization.Manager
|
||||
|
||||
var nodeParam = Expression.Parameter(typeof(DataNode), "node");
|
||||
var contextParam = Expression.Parameter(typeof(ISerializationContext), "context");
|
||||
var skipHookParam = Expression.Parameter(typeof(bool), "skipHook");
|
||||
var hookCtxParam = Expression.Parameter(typeof(SerializationHookContext), "hookCtx");
|
||||
var instantiatorParam = Expression.Parameter(typeof(ISerializationManager.InstantiationDelegate<>).MakeGenericType(baseType), "instanceProvider");
|
||||
|
||||
actualType = actualType.EnsureNotNullableType();
|
||||
@@ -171,8 +242,8 @@ namespace Robust.Shared.Serialization.Manager
|
||||
new[] { actualType, nodeType },
|
||||
readerConst,
|
||||
Expression.Convert(nodeParam, nodeType),
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
BaseInstantiatorToActual(),
|
||||
Expression.Constant(notNullableOverride));
|
||||
}
|
||||
@@ -182,13 +253,23 @@ namespace Robust.Shared.Serialization.Manager
|
||||
|
||||
if (nodeType == typeof(ValueDataNode))
|
||||
{
|
||||
call = Expression.Call(managerConst, nameof(ReadArrayValue), new[] { elementType },
|
||||
Expression.Convert(nodeParam, typeof(ValueDataNode)), contextParam, skipHookParam);
|
||||
call = Expression.Call(
|
||||
managerConst,
|
||||
nameof(ReadArrayValue),
|
||||
new[] { elementType },
|
||||
Expression.Convert(nodeParam, typeof(ValueDataNode)),
|
||||
hookCtxParam,
|
||||
contextParam);
|
||||
}
|
||||
else if (nodeType == typeof(SequenceDataNode))
|
||||
{
|
||||
call = Expression.Call(managerConst, nameof(ReadArraySequence), new[] { elementType },
|
||||
Expression.Convert(nodeParam, typeof(SequenceDataNode)), contextParam, skipHookParam);
|
||||
call = Expression.Call(
|
||||
managerConst,
|
||||
nameof(ReadArraySequence),
|
||||
new[] { elementType },
|
||||
Expression.Convert(nodeParam, typeof(SequenceDataNode)),
|
||||
hookCtxParam,
|
||||
contextParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -231,12 +312,14 @@ namespace Robust.Shared.Serialization.Manager
|
||||
}
|
||||
else
|
||||
{
|
||||
var hooksConst = Expression.Constant(actualType.IsAssignableTo(typeof(ISerializationHooks)));
|
||||
|
||||
if (nodeType == typeof(ValueDataNode))
|
||||
{
|
||||
call = Expression.Call(managerConst, nameof(ReadGenericValue), new[] { actualType },
|
||||
Expression.Convert(nodeParam, typeof(ValueDataNode)), hooksConst, skipHookParam,
|
||||
call = Expression.Call(
|
||||
managerConst,
|
||||
nameof(ReadGenericValue),
|
||||
new[] { actualType },
|
||||
Expression.Convert(nodeParam, typeof(ValueDataNode)),
|
||||
hookCtxParam,
|
||||
instantiatorVariable);
|
||||
}
|
||||
else if (nodeType == typeof(MappingDataNode))
|
||||
@@ -244,9 +327,14 @@ namespace Robust.Shared.Serialization.Manager
|
||||
var definition = manager.GetDefinition(actualType);
|
||||
var definitionConst = Expression.Constant(definition, typeof(DataDefinition<>).MakeGenericType(actualType));
|
||||
|
||||
call = Expression.Call(managerConst, nameof(ReadGenericMapping), new[] { actualType },
|
||||
Expression.Convert(nodeParam, typeof(MappingDataNode)), definitionConst, hooksConst,
|
||||
contextParam, skipHookParam,
|
||||
call = Expression.Call(
|
||||
managerConst,
|
||||
nameof(ReadGenericMapping),
|
||||
new[] { actualType },
|
||||
Expression.Convert(nodeParam, typeof(MappingDataNode)),
|
||||
definitionConst,
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
instantiatorVariable);
|
||||
}
|
||||
else
|
||||
@@ -276,8 +364,8 @@ namespace Robust.Shared.Serialization.Manager
|
||||
new []{actualType, nodeType},
|
||||
serializerVar,
|
||||
Expression.Convert(nodeParam, nodeType),
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
skipHookParam,
|
||||
BaseInstantiatorToActual(),
|
||||
Expression.Constant(notNullableOverride)),
|
||||
call));
|
||||
@@ -311,8 +399,14 @@ namespace Robust.Shared.Serialization.Manager
|
||||
finalValue);
|
||||
}
|
||||
|
||||
return Expression.Lambda(typeof(ReadGenericDelegate<>).MakeGenericType(baseType), call, nodeParam,
|
||||
contextParam, skipHookParam, instantiatorParam).Compile();
|
||||
return Expression.Lambda(
|
||||
typeof(ReadGenericDelegate<>).MakeGenericType(baseType),
|
||||
call,
|
||||
nodeParam,
|
||||
hookCtxParam,
|
||||
contextParam,
|
||||
instantiatorParam)
|
||||
.Compile();
|
||||
}
|
||||
|
||||
private ISerializationManager.InstantiationDelegate<T>? UnwrapInstantiationDelegate<T>(
|
||||
@@ -344,24 +438,24 @@ namespace Robust.Shared.Serialization.Manager
|
||||
|
||||
private T[] ReadArrayValue<T>(
|
||||
ValueDataNode value,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
var array = new T[1];
|
||||
array[0] = Read<T>(value, context, skipHook);
|
||||
array[0] = Read<T>(value, hookCtx, context);
|
||||
return array;
|
||||
}
|
||||
|
||||
private T[] ReadArraySequence<T>(
|
||||
SequenceDataNode node,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
var array = new T[node.Sequence.Count];
|
||||
|
||||
for (var i = 0; i < node.Sequence.Count; i++)
|
||||
{
|
||||
array[i] = Read<T>(node.Sequence[i], context, skipHook);
|
||||
array[i] = Read<T>(node.Sequence[i], hookCtx, context);
|
||||
}
|
||||
|
||||
return array;
|
||||
@@ -387,8 +481,7 @@ namespace Robust.Shared.Serialization.Manager
|
||||
|
||||
private TValue ReadGenericValue<TValue>(
|
||||
ValueDataNode node,
|
||||
bool hooks,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationManager.InstantiationDelegate<TValue> instanceProvider)
|
||||
where TValue : notnull
|
||||
{
|
||||
@@ -400,10 +493,7 @@ namespace Robust.Shared.Serialization.Manager
|
||||
throw new ArgumentException($"No mapping node provided for type {type} at line: {node.Start.Line}");
|
||||
}
|
||||
|
||||
if (!skipHook && hooks)
|
||||
{
|
||||
((ISerializationHooks) instance).AfterDeserialization();
|
||||
}
|
||||
RunAfterHook(instance, hookCtx);
|
||||
|
||||
return instance;
|
||||
}
|
||||
@@ -411,9 +501,8 @@ namespace Robust.Shared.Serialization.Manager
|
||||
private TValue ReadGenericMapping<TValue>(
|
||||
MappingDataNode node,
|
||||
DataDefinition<TValue>? definition,
|
||||
bool hooks,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context,
|
||||
bool skipHook,
|
||||
ISerializationManager.InstantiationDelegate<TValue> instanceProvider)
|
||||
where TValue : notnull
|
||||
{
|
||||
@@ -424,12 +513,9 @@ namespace Robust.Shared.Serialization.Manager
|
||||
|
||||
var instance = instanceProvider();
|
||||
|
||||
definition.Populate(ref instance, node, context, skipHook);
|
||||
definition.Populate(ref instance, node, hookCtx, context);
|
||||
|
||||
if (!skipHook && hooks)
|
||||
{
|
||||
((ISerializationHooks) instance).AfterDeserialization();
|
||||
}
|
||||
RunAfterHook(instance, hookCtx);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,8 @@ public sealed partial class SerializationManager
|
||||
private List<Type> _typeNodeInterfaces = new();
|
||||
private List<Type> _typeInterfaces = new();
|
||||
|
||||
private readonly object _lock = new();
|
||||
|
||||
#region GetSerializerMethods
|
||||
|
||||
public bool TryGetTypeNodeSerializer<TInterface, TType, TNode>([NotNullWhen(true)] out TInterface? serializer)
|
||||
@@ -82,26 +84,30 @@ public sealed partial class SerializationManager
|
||||
|
||||
public bool TryGetTypeNodeSerializer(Type interfaceType, Type objectType, Type nodeType, [NotNullWhen(true)] out object? serializer)
|
||||
{
|
||||
if (_typeNodeSerializers.TryGetValue(interfaceType, out var typeNodeSerializers) &&
|
||||
typeNodeSerializers.TryGetValue((objectType, nodeType), out serializer))
|
||||
return true;
|
||||
|
||||
if (_genericTypeNodeSerializers.TryGetValue(interfaceType, out var genericTypeNodeSerializers) && objectType.IsGenericType)
|
||||
lock (_lock)
|
||||
{
|
||||
var typeDef = objectType.GetGenericTypeDefinition();
|
||||
foreach (var (key, val) in genericTypeNodeSerializers)
|
||||
if (_typeNodeSerializers.TryGetValue(interfaceType, out var typeNodeSerializers) &&
|
||||
typeNodeSerializers.TryGetValue((objectType, nodeType), out serializer))
|
||||
return true;
|
||||
|
||||
if (_genericTypeNodeSerializers.TryGetValue(interfaceType, out var genericTypeNodeSerializers) &&
|
||||
objectType.IsGenericType)
|
||||
{
|
||||
if (typeDef.HasSameMetadataDefinitionAs(key.ObjectType) && nodeType == key.NodeType)
|
||||
var typeDef = objectType.GetGenericTypeDefinition();
|
||||
foreach (var (key, val) in genericTypeNodeSerializers)
|
||||
{
|
||||
var serializerType = val.MakeGenericType(objectType.GetGenericArguments());
|
||||
serializer = RegisterSerializer(serializerType)!;
|
||||
return true;
|
||||
if (typeDef.HasSameMetadataDefinitionAs(key.ObjectType) && nodeType == key.NodeType)
|
||||
{
|
||||
var serializerType = val.MakeGenericType(objectType.GetGenericArguments());
|
||||
serializer = RegisterSerializer(serializerType)!;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
serializer = null;
|
||||
return false;
|
||||
serializer = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public TInterface GetTypeNodeSerializer<TInterface, TType, TNode>()
|
||||
@@ -135,26 +141,30 @@ public sealed partial class SerializationManager
|
||||
|
||||
public bool TryGetTypeSerializer(Type interfaceType, Type objectType, [NotNullWhen(true)] out object? serializer)
|
||||
{
|
||||
if (_typeSerializers.TryGetValue(interfaceType, out var typeSerializers) &&
|
||||
typeSerializers.TryGetValue(objectType, out serializer))
|
||||
return true;
|
||||
|
||||
if (_genericTypeSerializers.TryGetValue(interfaceType, out var genericTypeSerializers) && objectType.IsGenericType)
|
||||
lock (_lock)
|
||||
{
|
||||
var typeDef = objectType.GetGenericTypeDefinition();
|
||||
foreach (var (key, val) in genericTypeSerializers)
|
||||
if (_typeSerializers.TryGetValue(interfaceType, out var typeSerializers) &&
|
||||
typeSerializers.TryGetValue(objectType, out serializer))
|
||||
return true;
|
||||
|
||||
if (_genericTypeSerializers.TryGetValue(interfaceType, out var genericTypeSerializers) &&
|
||||
objectType.IsGenericType)
|
||||
{
|
||||
if (typeDef.HasSameMetadataDefinitionAs(key))
|
||||
var typeDef = objectType.GetGenericTypeDefinition();
|
||||
foreach (var (key, val) in genericTypeSerializers)
|
||||
{
|
||||
var serializerType = val.MakeGenericType(objectType.GetGenericArguments());
|
||||
serializer = RegisterSerializer(serializerType)!;
|
||||
return true;
|
||||
if (typeDef.HasSameMetadataDefinitionAs(key))
|
||||
{
|
||||
var serializerType = val.MakeGenericType(objectType.GetGenericArguments());
|
||||
serializer = RegisterSerializer(serializerType)!;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
serializer = null;
|
||||
return false;
|
||||
serializer = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public TInterface GetTypeSerializer<TInterface, TType>()
|
||||
@@ -182,45 +192,12 @@ public sealed partial class SerializationManager
|
||||
|
||||
private object RegisterSerializer(Type type, object obj)
|
||||
{
|
||||
foreach (var @interface in type.GetInterfaces())
|
||||
lock (_lock)
|
||||
{
|
||||
if(!@interface.IsGenericType) continue;
|
||||
|
||||
foreach (var typeInterface in _typeInterfaces)
|
||||
{
|
||||
if (@interface.GetGenericTypeDefinition().HasSameMetadataDefinitionAs(typeInterface))
|
||||
{
|
||||
var arguments = @interface.GetGenericArguments();
|
||||
if (arguments.Length != 1)
|
||||
throw new InvalidGenericParameterCountException();
|
||||
_typeSerializers.GetOrNew(typeInterface).Add(arguments[0], obj);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var typeInterface in _typeNodeInterfaces)
|
||||
{
|
||||
if (@interface.GetGenericTypeDefinition().HasSameMetadataDefinitionAs(typeInterface))
|
||||
{
|
||||
var arguments = @interface.GetGenericArguments();
|
||||
if (arguments.Length != 2)
|
||||
throw new InvalidGenericParameterCountException();
|
||||
_typeNodeSerializers.GetOrNew(typeInterface).Add((arguments[0], arguments[1]), obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public T? RegisterSerializer<T>() => (T?)RegisterSerializer(typeof(T));
|
||||
|
||||
public object? RegisterSerializer(Type type)
|
||||
{
|
||||
if (type.IsGenericTypeDefinition)
|
||||
{
|
||||
var typeArguments = type.GetGenericArguments();
|
||||
foreach (var @interface in type.GetInterfaces())
|
||||
{
|
||||
if (!@interface.IsGenericType) continue;
|
||||
|
||||
foreach (var typeInterface in _typeInterfaces)
|
||||
{
|
||||
if (@interface.GetGenericTypeDefinition().HasSameMetadataDefinitionAs(typeInterface))
|
||||
@@ -228,14 +205,7 @@ public sealed partial class SerializationManager
|
||||
var arguments = @interface.GetGenericArguments();
|
||||
if (arguments.Length != 1)
|
||||
throw new InvalidGenericParameterCountException();
|
||||
var objArguments = arguments[0].GetGenericArguments();
|
||||
for (int i = 0; i < typeArguments.Length; i++)
|
||||
{
|
||||
if (typeArguments[i] != objArguments[i])
|
||||
throw new GenericParameterMismatchException();
|
||||
}
|
||||
|
||||
_genericTypeSerializers.GetOrNew(typeInterface).Add(arguments[0], type);
|
||||
_typeSerializers.GetOrNew(typeInterface).Add(arguments[0], obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,22 +216,69 @@ public sealed partial class SerializationManager
|
||||
var arguments = @interface.GetGenericArguments();
|
||||
if (arguments.Length != 2)
|
||||
throw new InvalidGenericParameterCountException();
|
||||
var objArguments = arguments[0].GetGenericArguments();
|
||||
for (int i = 0; i < typeArguments.Length; i++)
|
||||
{
|
||||
if (typeArguments[i] != objArguments[i])
|
||||
throw new GenericParameterMismatchException();
|
||||
}
|
||||
|
||||
_genericTypeNodeSerializers.GetOrNew(typeInterface).Add((arguments[0], arguments[1]), type);
|
||||
_typeNodeSerializers.GetOrNew(typeInterface).Add((arguments[0], arguments[1]), obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
return RegisterSerializer(type, CreateSerializer(type));
|
||||
public T? RegisterSerializer<T>() => (T?)RegisterSerializer(typeof(T));
|
||||
|
||||
public object? RegisterSerializer(Type type)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (type.IsGenericTypeDefinition)
|
||||
{
|
||||
var typeArguments = type.GetGenericArguments();
|
||||
foreach (var @interface in type.GetInterfaces())
|
||||
{
|
||||
foreach (var typeInterface in _typeInterfaces)
|
||||
{
|
||||
if (@interface.GetGenericTypeDefinition().HasSameMetadataDefinitionAs(typeInterface))
|
||||
{
|
||||
var arguments = @interface.GetGenericArguments();
|
||||
if (arguments.Length != 1)
|
||||
throw new InvalidGenericParameterCountException();
|
||||
var objArguments = arguments[0].GetGenericArguments();
|
||||
for (int i = 0; i < typeArguments.Length; i++)
|
||||
{
|
||||
if (typeArguments[i] != objArguments[i])
|
||||
throw new GenericParameterMismatchException();
|
||||
}
|
||||
|
||||
_genericTypeSerializers.GetOrNew(typeInterface).Add(arguments[0], type);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var typeInterface in _typeNodeInterfaces)
|
||||
{
|
||||
if (@interface.GetGenericTypeDefinition().HasSameMetadataDefinitionAs(typeInterface))
|
||||
{
|
||||
var arguments = @interface.GetGenericArguments();
|
||||
if (arguments.Length != 2)
|
||||
throw new InvalidGenericParameterCountException();
|
||||
var objArguments = arguments[0].GetGenericArguments();
|
||||
for (int i = 0; i < typeArguments.Length; i++)
|
||||
{
|
||||
if (typeArguments[i] != objArguments[i])
|
||||
throw new GenericParameterMismatchException();
|
||||
}
|
||||
|
||||
_genericTypeNodeSerializers.GetOrNew(typeInterface)
|
||||
.Add((arguments[0], arguments[1]), type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return RegisterSerializer(type, CreateSerializer(type));
|
||||
}
|
||||
}
|
||||
|
||||
//todo paul serv3 is there a better way than comparing names here?
|
||||
@@ -269,31 +286,38 @@ public sealed partial class SerializationManager
|
||||
{
|
||||
if (!type.IsGenericTypeDefinition)
|
||||
throw new ArgumentException("Only generic type definitions can be signed up as interfaces", nameof(type));
|
||||
var genericTypeNode = typeof(BaseSerializerInterfaces.ITypeNodeInterface<,>);
|
||||
var genericType = typeof(BaseSerializerInterfaces.ITypeInterface<>);
|
||||
var genericParams = type.GetGenericArguments();
|
||||
foreach (var @interface in type.GetInterfaces())
|
||||
|
||||
// Note: lock is entered recursively.
|
||||
lock (_lock)
|
||||
{
|
||||
var genericInterface = @interface.GetGenericTypeDefinition();
|
||||
if (genericInterface.HasSameMetadataDefinitionAs(genericTypeNode))
|
||||
var genericTypeNode = typeof(BaseSerializerInterfaces.ITypeNodeInterface<,>);
|
||||
var genericType = typeof(BaseSerializerInterfaces.ITypeInterface<>);
|
||||
var genericParams = type.GetGenericArguments();
|
||||
foreach (var @interface in type.GetInterfaces())
|
||||
{
|
||||
var genericInterfaceParams = genericInterface.GetGenericArguments();
|
||||
for (int i = 0; i < genericParams.Length; i++)
|
||||
var genericInterface = @interface.GetGenericTypeDefinition();
|
||||
if (genericInterface.HasSameMetadataDefinitionAs(genericTypeNode))
|
||||
{
|
||||
if (genericParams[i].Name != genericInterfaceParams[i].Name)
|
||||
throw new GenericParameterMismatchException();
|
||||
var genericInterfaceParams = genericInterface.GetGenericArguments();
|
||||
for (int i = 0; i < genericParams.Length; i++)
|
||||
{
|
||||
if (genericParams[i].Name != genericInterfaceParams[i].Name)
|
||||
throw new GenericParameterMismatchException();
|
||||
}
|
||||
|
||||
_typeNodeInterfaces.Add(type);
|
||||
}
|
||||
_typeNodeInterfaces.Add(type);
|
||||
}
|
||||
else if (genericInterface.HasSameMetadataDefinitionAs(genericType))
|
||||
{
|
||||
var genericInterfaceParams = genericInterface.GetGenericArguments();
|
||||
for (int i = 0; i < genericParams.Length; i++)
|
||||
else if (genericInterface.HasSameMetadataDefinitionAs(genericType))
|
||||
{
|
||||
if (genericParams[i].Name != genericInterfaceParams[i].Name)
|
||||
throw new GenericParameterMismatchException();
|
||||
var genericInterfaceParams = genericInterface.GetGenericArguments();
|
||||
for (int i = 0; i < genericParams.Length; i++)
|
||||
{
|
||||
if (genericParams[i].Name != genericInterfaceParams[i].Name)
|
||||
throw new GenericParameterMismatchException();
|
||||
}
|
||||
|
||||
_typeInterfaces.Add(type);
|
||||
}
|
||||
_typeInterfaces.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,5 +271,20 @@ namespace Robust.Shared.Serialization.Manager
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
private static void RunAfterHook<TValue>(TValue instance, SerializationHookContext ctx)
|
||||
{
|
||||
#pragma warning disable CS0618
|
||||
if (ctx.SkipHooks || instance is not ISerializationHooks hooks)
|
||||
#pragma warning restore CS0618
|
||||
return;
|
||||
|
||||
DebugTools.Assert(!typeof(TValue).IsValueType, "ISerializationHooks must only be used on reference types");
|
||||
|
||||
if (ctx.DeferQueue != null)
|
||||
ctx.DeferQueue.TryWrite(hooks);
|
||||
else
|
||||
hooks.AfterDeserialization();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
57
Robust.Shared/Serialization/Markdown/DataNodeHelpers.cs
Normal file
57
Robust.Shared/Serialization/Markdown/DataNodeHelpers.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
|
||||
namespace Robust.Shared.Serialization.Markdown;
|
||||
|
||||
public static class DataNodeHelpers
|
||||
{
|
||||
public static IEnumerable<DataNode> GetAllNodes(DataNode node)
|
||||
{
|
||||
return node switch
|
||||
{
|
||||
MappingDataNode mapping => GetAllNodes(mapping),
|
||||
SequenceDataNode sequence => GetAllNodes(sequence),
|
||||
ValueDataNode value => GetAllNodes(value),
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(node))
|
||||
};
|
||||
}
|
||||
|
||||
private static IEnumerable<DataNode> GetAllNodes(MappingDataNode node)
|
||||
{
|
||||
yield return node;
|
||||
|
||||
foreach (var (k, v) in node)
|
||||
{
|
||||
foreach (var child in GetAllNodes(k))
|
||||
{
|
||||
yield return child;
|
||||
}
|
||||
|
||||
foreach (var child in GetAllNodes(v))
|
||||
{
|
||||
yield return child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<DataNode> GetAllNodes(SequenceDataNode node)
|
||||
{
|
||||
yield return node;
|
||||
|
||||
foreach (var s in node)
|
||||
{
|
||||
foreach (var child in GetAllNodes(s))
|
||||
{
|
||||
yield return child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<DataNode> GetAllNodes(ValueDataNode node)
|
||||
{
|
||||
yield return node;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,9 @@ using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using NetSerializer;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
@@ -346,6 +349,30 @@ namespace Robust.Shared.Serialization
|
||||
}
|
||||
}
|
||||
|
||||
public void AddStrings(DataNode dataNode)
|
||||
{
|
||||
if (Locked)
|
||||
{
|
||||
throw new InvalidOperationException("Mapped strings are locked, will not add.");
|
||||
}
|
||||
|
||||
foreach (var node in DataNodeHelpers.GetAllNodes(dataNode))
|
||||
{
|
||||
var t = node.Tag;
|
||||
if (!string.IsNullOrEmpty(t))
|
||||
AddString(t);
|
||||
|
||||
if (node is not ValueDataNode value)
|
||||
continue;
|
||||
|
||||
var v = value.Value;
|
||||
if (string.IsNullOrEmpty(v))
|
||||
continue;
|
||||
|
||||
AddString(v);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add strings from the given enumeration to the mapping.
|
||||
/// </summary>
|
||||
|
||||
@@ -15,6 +15,8 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Network.Messages;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
using static Robust.Shared.Utility.Base64Helpers;
|
||||
@@ -540,6 +542,14 @@ namespace Robust.Shared.Serialization
|
||||
}
|
||||
}
|
||||
|
||||
public void AddStrings(DataNode dataNode)
|
||||
{
|
||||
if (!_net.IsClient)
|
||||
{
|
||||
_dict.AddStrings(dataNode);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add strings from the given enumeration to the mapping.
|
||||
/// </summary>
|
||||
|
||||
22
Robust.Shared/Serialization/SerializationHookContext.cs
Normal file
22
Robust.Shared/Serialization/SerializationHookContext.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System.Threading.Channels;
|
||||
|
||||
namespace Robust.Shared.Serialization;
|
||||
|
||||
public sealed class SerializationHookContext
|
||||
{
|
||||
public static readonly SerializationHookContext DoSkipHooks = new(null, true);
|
||||
public static readonly SerializationHookContext DontSkipHooks = new(null, false);
|
||||
|
||||
#pragma warning disable CS0618
|
||||
public readonly ChannelWriter<ISerializationHooks>? DeferQueue;
|
||||
public readonly bool SkipHooks;
|
||||
|
||||
public SerializationHookContext(ChannelWriter<ISerializationHooks>? deferQueue, bool skipHooks)
|
||||
{
|
||||
DeferQueue = deferQueue;
|
||||
SkipHooks = skipHooks;
|
||||
}
|
||||
|
||||
public static SerializationHookContext ForSkipHooks(bool skip) => skip ? DoSkipHooks : DontSkipHooks;
|
||||
#pragma warning restore CS0618
|
||||
}
|
||||
@@ -16,7 +16,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
{
|
||||
public Angle Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<Angle>? instanceProvider = null)
|
||||
{
|
||||
@@ -49,7 +49,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
|
||||
[MustUseReturnValue]
|
||||
public Angle CreateCopy(ISerializationManager serializationManager, Angle source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new(source);
|
||||
|
||||
@@ -16,32 +16,34 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
[TypeSerializer]
|
||||
public sealed class Box2Serializer : ITypeSerializer<Box2, ValueDataNode>, ITypeCopyCreator<Box2>
|
||||
{
|
||||
private static void NextOrThrow(ref SpanSplitExtensions.Enumerator<char> enumerator, string value)
|
||||
private static void NextOrThrow(
|
||||
ref ReadOnlySpan<char> source,
|
||||
out ReadOnlySpan<char> splitValue,
|
||||
string errValue)
|
||||
{
|
||||
if (!enumerator.MoveNext())
|
||||
throw new InvalidMappingException($"Could not parse {nameof(Box2)}: '{value}'");
|
||||
if (!SpanSplitExtensions.SplitFindNext(ref source, ',', out splitValue))
|
||||
throw new InvalidMappingException($"Could not parse {nameof(Box2)}: '{errValue}'");
|
||||
}
|
||||
|
||||
public Box2 Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<Box2>? instanceProvider = null)
|
||||
{
|
||||
var nodeValue = node.Value;
|
||||
var args = nodeValue.AsSpan().Split(',').GetEnumerator();
|
||||
NextOrThrow(ref args, nodeValue);
|
||||
var nodeValue = node.Value.AsSpan();
|
||||
NextOrThrow(ref nodeValue, out var current, node.Value);
|
||||
|
||||
var l = Parse.Float(args.Current);
|
||||
NextOrThrow(ref args, nodeValue);
|
||||
var l = Parse.Float(current);
|
||||
NextOrThrow(ref nodeValue, out current, node.Value);
|
||||
|
||||
var b = Parse.Float(args.Current);
|
||||
NextOrThrow(ref args, nodeValue);
|
||||
var b = Parse.Float(current);
|
||||
NextOrThrow(ref nodeValue, out current, node.Value);
|
||||
|
||||
var r = Parse.Float(args.Current);
|
||||
NextOrThrow(ref args, nodeValue);
|
||||
var r = Parse.Float(current);
|
||||
NextOrThrow(ref nodeValue, out current, node.Value);
|
||||
|
||||
var t = Parse.Float(args.Current);
|
||||
var t = Parse.Float(current);
|
||||
|
||||
return new Box2(l, b, r, t);
|
||||
}
|
||||
@@ -80,7 +82,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
|
||||
[MustUseReturnValue]
|
||||
public Box2 CreateCopy(ISerializationManager serializationManager, Box2 source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new(source.Left, source.Bottom, source.Right, source.Top);
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
{
|
||||
public Color Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<Color>? instanceProvider = null)
|
||||
{
|
||||
@@ -44,7 +44,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
|
||||
[MustUseReturnValue]
|
||||
public Color CreateCopy(ISerializationManager serializationManager, Color source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new(source.R, source.G, source.B, source.A);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
@@ -23,15 +22,16 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
public ComponentRegistry Read(ISerializationManager serializationManager,
|
||||
SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<ComponentRegistry>? instanceProvider = null)
|
||||
{
|
||||
var factory = dependencies.Resolve<IComponentFactory>();
|
||||
var components = instanceProvider != null ? instanceProvider() : new ComponentRegistry();
|
||||
|
||||
foreach (var componentMapping in node.Sequence.Cast<MappingDataNode>())
|
||||
foreach (var sequenceEntry in node.Sequence)
|
||||
{
|
||||
var componentMapping = (MappingDataNode)sequenceEntry;
|
||||
string compType = ((ValueDataNode) componentMapping.Get("type")).Value;
|
||||
// See if type exists to detect errors.
|
||||
switch (factory.GetComponentAvailability(compType))
|
||||
@@ -48,7 +48,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
}
|
||||
|
||||
// Has this type already been added?
|
||||
if (components.Keys.Contains(compType))
|
||||
if (components.ContainsKey(compType))
|
||||
{
|
||||
Logger.ErrorS(SerializationManager.LogCategory, $"Component of type '{compType}' defined twice in prototype!");
|
||||
continue;
|
||||
@@ -58,7 +58,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
copy.Remove("type");
|
||||
|
||||
var type = factory.GetRegistration(compType).Type;
|
||||
var read = (IComponent)serializationManager.Read(type, copy, skipHook: skipHook)!;
|
||||
var read = (IComponent)serializationManager.Read(type, copy, hookCtx)!;
|
||||
|
||||
components[compType] = new ComponentRegistryEntry(read, copy);
|
||||
}
|
||||
@@ -92,8 +92,9 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
var components = new ComponentRegistry();
|
||||
var list = new List<ValidationNode>();
|
||||
|
||||
foreach (var componentMapping in node.Sequence.Cast<MappingDataNode>())
|
||||
foreach (var sequenceEntry in node.Sequence)
|
||||
{
|
||||
var componentMapping = (MappingDataNode)sequenceEntry;
|
||||
string compType = ((ValueDataNode) componentMapping.Get("type")).Value;
|
||||
// See if type exists to detect errors.
|
||||
switch (factory.GetComponentAvailability(compType))
|
||||
@@ -111,7 +112,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
}
|
||||
|
||||
// Has this type already been added?
|
||||
if (components.Keys.Contains(compType))
|
||||
if (components.ContainsKey(compType))
|
||||
{
|
||||
list.Add(new ErrorNode(componentMapping, "Duplicate Component."));
|
||||
continue;
|
||||
@@ -170,7 +171,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, ComponentRegistry source, ref ComponentRegistry target,
|
||||
bool skipHook, ISerializationContext? context = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
target.Clear();
|
||||
target.EnsureCapacity(source.Count);
|
||||
@@ -192,16 +193,29 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
|
||||
foreach (var (reg, mapping) in parentDict)
|
||||
{
|
||||
if (newCompRegDict.TryFirstOrNull(childReg => reg.References.Any(x => childReg.Key.References.Contains(x)), out var entry))
|
||||
foreach (var (childReg, idx) in newCompRegDict)
|
||||
{
|
||||
newCompReg[entry.Value.Value] = serializationManager.PushCompositionWithGenericNode(reg.Type,
|
||||
new[] { parent[mapping] }, newCompReg[entry.Value.Value], context);
|
||||
}
|
||||
else
|
||||
{
|
||||
newCompReg.Add(parent[mapping]);
|
||||
newCompRegDict[reg] = newCompReg.Count-1;
|
||||
foreach (var x in reg.References)
|
||||
{
|
||||
if (childReg.References.Contains(x))
|
||||
{
|
||||
newCompReg[idx] = serializationManager.PushCompositionWithGenericNode(
|
||||
reg.Type,
|
||||
new[] { parent[mapping] },
|
||||
newCompReg[idx],
|
||||
context);
|
||||
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not found.
|
||||
|
||||
newCompReg.Add(parent[mapping]);
|
||||
newCompRegDict[reg] = newCompReg.Count-1;
|
||||
|
||||
found: ;
|
||||
}
|
||||
|
||||
return newCompReg;
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom
|
||||
}
|
||||
|
||||
public int Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<int>? instanceProvider = null)
|
||||
{
|
||||
var constType = serializationManager.GetConstantTypeFromTag(typeof(TTag));
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom
|
||||
}
|
||||
|
||||
public int Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<int>? instanceProvider = null)
|
||||
{
|
||||
var flagType = serializationManager.GetFlagTypeFromTag(typeof(TTag));
|
||||
@@ -76,7 +76,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom
|
||||
}
|
||||
|
||||
public int Read(ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<int>? instanceProvider = null)
|
||||
{
|
||||
var flagType = serializationManager.GetFlagTypeFromTag(typeof(TTag));
|
||||
@@ -91,7 +91,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom
|
||||
return flags;
|
||||
}
|
||||
|
||||
public int CreateCopy(ISerializationManager serializationManager, int source, bool skipHook,
|
||||
public int CreateCopy(ISerializationManager serializationManager, int source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return source;
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Pro
|
||||
}
|
||||
|
||||
public PrototypeFlags<T> Read(ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<PrototypeFlags<T>>? instanceProvider = null)
|
||||
{
|
||||
if(instanceProvider != null)
|
||||
@@ -75,7 +75,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Pro
|
||||
}
|
||||
|
||||
public PrototypeFlags<T> Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<PrototypeFlags<T>>? instanceProvider = null)
|
||||
{
|
||||
if(instanceProvider != null)
|
||||
@@ -85,12 +85,12 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Pro
|
||||
}
|
||||
|
||||
public PrototypeFlags<T> CreateCopy(ISerializationManager serializationManager, PrototypeFlags<T> source,
|
||||
bool skipHook, ISerializationContext? context = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
return new PrototypeFlags<T>(source);
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, PrototypeFlags<T> source, ref PrototypeFlags<T> target, bool skipHook,
|
||||
public void CopyTo(ISerializationManager serializationManager, PrototypeFlags<T> source, ref PrototypeFlags<T> target, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
target.Clear();
|
||||
|
||||
@@ -20,7 +20,7 @@ public sealed class TimeOffsetSerializer : ITypeSerializer<TimeSpan, ValueDataNo
|
||||
{
|
||||
public TimeSpan Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<TimeSpan>? instanceProvider = null)
|
||||
{
|
||||
|
||||
@@ -26,7 +26,7 @@ public sealed class EnumSerializer : ITypeSerializer<Enum, ValueDataNode>
|
||||
}
|
||||
|
||||
public Enum Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<Enum>? instanceProvider = null)
|
||||
{
|
||||
if (serializationManager.ReflectionManager.TryParseEnumReference(node.Value, out var @enum))
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
public sealed class FormattedMessageSerializer : ITypeSerializer<FormattedMessage, ValueDataNode>, ITypeCopyCreator<FormattedMessage>
|
||||
{
|
||||
public FormattedMessage Read(ISerializationManager serializationManager,
|
||||
ValueDataNode node, IDependencyCollection dependencies, bool skipHook,
|
||||
ValueDataNode node, IDependencyCollection dependencies, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<FormattedMessage>? instanceProvider = null)
|
||||
{
|
||||
@@ -40,7 +40,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
|
||||
[MustUseReturnValue]
|
||||
public FormattedMessage CreateCopy(ISerializationManager serializationManager, FormattedMessage source,
|
||||
bool skipHook, ISerializationContext? context = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
return new(source);
|
||||
}
|
||||
|
||||
@@ -20,14 +20,14 @@ public sealed class CustomHashSetSerializer<T, TCustomSerializer>
|
||||
HashSet<T> ITypeReader<HashSet<T>, SequenceDataNode>.Read(ISerializationManager serializationManager,
|
||||
SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context, ISerializationManager.InstantiationDelegate<HashSet<T>>? instanceProvider = null)
|
||||
{
|
||||
var set = instanceProvider != null ? instanceProvider() : new HashSet<T>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
var value = serializationManager.Read<T, ValueDataNode, TCustomSerializer>((ValueDataNode)dataNode, context, skipHook);
|
||||
var value = serializationManager.Read<T, ValueDataNode, TCustomSerializer>((ValueDataNode)dataNode, hookCtx, context);
|
||||
if (value == null)
|
||||
throw new InvalidOperationException($"{nameof(TCustomSerializer)} returned a null value when reading using a custom hashset serializer.");
|
||||
|
||||
|
||||
@@ -20,14 +20,14 @@ public sealed class CustomQueueSerializer<T, TCustomSerializer>
|
||||
Queue<T> ITypeReader<Queue<T>, SequenceDataNode>.Read(ISerializationManager serializationManager,
|
||||
SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context, ISerializationManager.InstantiationDelegate<Queue<T>>? instanceProvider = null)
|
||||
{
|
||||
var queue = instanceProvider != null ? instanceProvider() : new Queue<T>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
var value = serializationManager.Read<T, ValueDataNode, TCustomSerializer>((ValueDataNode)dataNode, context, skipHook);
|
||||
var value = serializationManager.Read<T, ValueDataNode, TCustomSerializer>((ValueDataNode)dataNode, hookCtx, context);
|
||||
if (value == null)
|
||||
throw new InvalidOperationException($"{nameof(TCustomSerializer)} returned a null value when reading using a custom hashset serializer.");
|
||||
|
||||
|
||||
@@ -40,15 +40,15 @@ public sealed class DictionarySerializer<TKey, TValue> :
|
||||
}
|
||||
|
||||
public Dictionary<TKey, TValue> Read(ISerializationManager serializationManager,
|
||||
MappingDataNode node, IDependencyCollection dependencies, bool skipHook, ISerializationContext? context,
|
||||
MappingDataNode node, IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context,
|
||||
ISerializationManager.InstantiationDelegate<Dictionary<TKey, TValue>>? instanceProvider)
|
||||
{
|
||||
var dict = instanceProvider != null ? instanceProvider() : new Dictionary<TKey, TValue>();
|
||||
|
||||
foreach (var (key, value) in node.Children)
|
||||
{
|
||||
dict.Add(serializationManager.Read<TKey>(key, context, skipHook),
|
||||
serializationManager.Read<TValue>(value, context, skipHook));
|
||||
dict.Add(serializationManager.Read<TKey>(key, hookCtx, context),
|
||||
serializationManager.Read<TValue>(value, hookCtx, context));
|
||||
}
|
||||
|
||||
return dict;
|
||||
@@ -115,7 +115,7 @@ public sealed class DictionarySerializer<TKey, TValue> :
|
||||
IReadOnlyDictionary<TKey, TValue> ITypeReader<IReadOnlyDictionary<TKey, TValue>, MappingDataNode>.Read(
|
||||
ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context,
|
||||
SerializationHookContext hookCtx, ISerializationContext? context,
|
||||
ISerializationManager.InstantiationDelegate<IReadOnlyDictionary<TKey, TValue>>? instanceProvider)
|
||||
{
|
||||
if (instanceProvider != null)
|
||||
@@ -128,8 +128,8 @@ public sealed class DictionarySerializer<TKey, TValue> :
|
||||
|
||||
foreach (var (key, value) in node.Children)
|
||||
{
|
||||
dict.Add(serializationManager.Read<TKey>(key, context, skipHook),
|
||||
serializationManager.Read<TValue>(value, context, skipHook));
|
||||
dict.Add(serializationManager.Read<TKey>(key, hookCtx, context),
|
||||
serializationManager.Read<TValue>(value, hookCtx, context));
|
||||
}
|
||||
|
||||
return dict;
|
||||
@@ -138,21 +138,21 @@ public sealed class DictionarySerializer<TKey, TValue> :
|
||||
SortedDictionary<TKey, TValue> ITypeReader<SortedDictionary<TKey, TValue>, MappingDataNode>.Read(
|
||||
ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context,
|
||||
SerializationHookContext hookCtx, ISerializationContext? context,
|
||||
ISerializationManager.InstantiationDelegate<SortedDictionary<TKey, TValue>>? instanceProvider)
|
||||
{
|
||||
var dict = instanceProvider != null ? instanceProvider() : new SortedDictionary<TKey, TValue>();
|
||||
|
||||
foreach (var (key, value) in node.Children)
|
||||
{
|
||||
dict.Add(serializationManager.Read<TKey>(key, context, skipHook),
|
||||
serializationManager.Read<TValue>(value, context, skipHook));
|
||||
dict.Add(serializationManager.Read<TKey>(key, hookCtx, context),
|
||||
serializationManager.Read<TValue>(value, hookCtx, context));
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, Dictionary<TKey, TValue> source, ref Dictionary<TKey, TValue> target, bool skipHook,
|
||||
public void CopyTo(ISerializationManager serializationManager, Dictionary<TKey, TValue> source, ref Dictionary<TKey, TValue> target, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
target.Clear();
|
||||
@@ -160,24 +160,24 @@ public sealed class DictionarySerializer<TKey, TValue> :
|
||||
foreach (var value in source)
|
||||
{
|
||||
target.Add(
|
||||
serializationManager.CreateCopy(value.Key, context, skipHook),
|
||||
serializationManager.CreateCopy(value.Value, context, skipHook));
|
||||
serializationManager.CreateCopy(value.Key, hookCtx, context),
|
||||
serializationManager.CreateCopy(value.Value, hookCtx, context));
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, SortedDictionary<TKey, TValue> source, ref SortedDictionary<TKey, TValue> target,
|
||||
bool skipHook, ISerializationContext? context = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
target.Clear();
|
||||
foreach (var value in source)
|
||||
{
|
||||
target.Add(
|
||||
serializationManager.CreateCopy(value.Key, context, skipHook),
|
||||
serializationManager.CreateCopy(value.Value, context, skipHook));
|
||||
serializationManager.CreateCopy(value.Key, hookCtx, context),
|
||||
serializationManager.CreateCopy(value.Value, hookCtx, context));
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<TKey, TValue> CreateCopy(ISerializationManager serializationManager, IReadOnlyDictionary<TKey, TValue> source, bool skipHook,
|
||||
public IReadOnlyDictionary<TKey, TValue> CreateCopy(ISerializationManager serializationManager, IReadOnlyDictionary<TKey, TValue> source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
var target = new Dictionary<TKey, TValue>();
|
||||
@@ -185,8 +185,8 @@ public sealed class DictionarySerializer<TKey, TValue> :
|
||||
foreach (var value in source)
|
||||
{
|
||||
target.Add(
|
||||
serializationManager.CreateCopy(value.Key, context, skipHook),
|
||||
serializationManager.CreateCopy(value.Value, context, skipHook));
|
||||
serializationManager.CreateCopy(value.Key, hookCtx, context),
|
||||
serializationManager.CreateCopy(value.Value, hookCtx, context));
|
||||
}
|
||||
|
||||
return target;
|
||||
|
||||
@@ -22,14 +22,14 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
HashSet<T> ITypeReader<HashSet<T>, SequenceDataNode>.Read(ISerializationManager serializationManager,
|
||||
SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context, ISerializationManager.InstantiationDelegate<HashSet<T>>? instanceProvider = null)
|
||||
{
|
||||
var set = instanceProvider != null ? instanceProvider() : new HashSet<T>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
set.Add(serializationManager.Read<T>(dataNode, context, skipHook));
|
||||
set.Add(serializationManager.Read<T>(dataNode, hookCtx, context));
|
||||
}
|
||||
|
||||
return set;
|
||||
@@ -85,7 +85,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
ISerializationManager serializationManager,
|
||||
SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context,
|
||||
ISerializationManager.InstantiationDelegate<ImmutableHashSet<T>>? instanceProvider = null)
|
||||
{
|
||||
@@ -95,13 +95,13 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
set.Add(serializationManager.Read<T>(dataNode, context, skipHook));
|
||||
set.Add(serializationManager.Read<T>(dataNode, hookCtx, context));
|
||||
}
|
||||
|
||||
return set.ToImmutable();
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, HashSet<T> source, ref HashSet<T> target, bool skipHook,
|
||||
public void CopyTo(ISerializationManager serializationManager, HashSet<T> source, ref HashSet<T> target, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
target.Clear();
|
||||
@@ -109,11 +109,11 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
|
||||
foreach (var val in source)
|
||||
{
|
||||
target.Add(serializationManager.CreateCopy(val, context, skipHook));
|
||||
target.Add(serializationManager.CreateCopy(val, hookCtx, context));
|
||||
}
|
||||
}
|
||||
|
||||
public ImmutableHashSet<T> CreateCopy(ISerializationManager serializationManager, ImmutableHashSet<T> source, bool skipHook,
|
||||
public ImmutableHashSet<T> CreateCopy(ISerializationManager serializationManager, ImmutableHashSet<T> source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
var target = new HashSet<T>();
|
||||
@@ -121,7 +121,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
|
||||
foreach (var val in source)
|
||||
{
|
||||
target.Add(serializationManager.CreateCopy(val, context, skipHook));
|
||||
target.Add(serializationManager.CreateCopy(val, hookCtx, context));
|
||||
}
|
||||
|
||||
return target.ToImmutableHashSet();
|
||||
|
||||
@@ -70,14 +70,14 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
List<T> ITypeReader<List<T>, SequenceDataNode>.Read(ISerializationManager serializationManager,
|
||||
SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context, ISerializationManager.InstantiationDelegate<List<T>>? instanceProvider = null)
|
||||
{
|
||||
var list = instanceProvider != null ? instanceProvider() : new List<T>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
list.Add(serializationManager.Read<T>(dataNode, context, skipHook));
|
||||
list.Add(serializationManager.Read<T>(dataNode, hookCtx, context));
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -124,7 +124,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
IReadOnlyList<T> ITypeReader<IReadOnlyList<T>, SequenceDataNode>.Read(
|
||||
ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context,
|
||||
SerializationHookContext hookCtx, ISerializationContext? context,
|
||||
ISerializationManager.InstantiationDelegate<IReadOnlyList<T>>? instanceProvider = null)
|
||||
{
|
||||
if(instanceProvider != null)
|
||||
@@ -134,7 +134,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
list.Add(serializationManager.Read<T>(dataNode, context, skipHook));
|
||||
list.Add(serializationManager.Read<T>(dataNode, hookCtx, context));
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -143,7 +143,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
IReadOnlyCollection<T> ITypeReader<IReadOnlyCollection<T>, SequenceDataNode>.Read(
|
||||
ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context,
|
||||
SerializationHookContext hookCtx, ISerializationContext? context,
|
||||
ISerializationManager.InstantiationDelegate<IReadOnlyCollection<T>>? instanceProvider = null)
|
||||
{
|
||||
if(instanceProvider != null)
|
||||
@@ -153,7 +153,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
list.Add(serializationManager.Read<T>(dataNode, context, skipHook));
|
||||
list.Add(serializationManager.Read<T>(dataNode, hookCtx, context));
|
||||
}
|
||||
|
||||
return list;
|
||||
@@ -162,7 +162,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
ImmutableList<T> ITypeReader<ImmutableList<T>, SequenceDataNode>.Read(
|
||||
ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context,
|
||||
SerializationHookContext hookCtx, ISerializationContext? context,
|
||||
ISerializationManager.InstantiationDelegate<ImmutableList<T>>? instanceProvider = null)
|
||||
{
|
||||
if(instanceProvider != null)
|
||||
@@ -172,13 +172,13 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
list.Add(serializationManager.Read<T>(dataNode, context, skipHook));
|
||||
list.Add(serializationManager.Read<T>(dataNode, hookCtx, context));
|
||||
}
|
||||
|
||||
return list.ToImmutable();
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, List<T> source, ref List<T> target, bool skipHook,
|
||||
public void CopyTo(ISerializationManager serializationManager, List<T> source, ref List<T> target, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
target.Clear();
|
||||
@@ -188,45 +188,45 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
for (var i = 0; i < sourceSpan.Length; i++)
|
||||
{
|
||||
ref var val = ref sourceSpan[i];
|
||||
target.Add(serializationManager.CreateCopy(val, context, skipHook));
|
||||
target.Add(serializationManager.CreateCopy(val, hookCtx, context));
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyList<T> CreateCopy(ISerializationManager serializationManager, IReadOnlyList<T> source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
var target = new List<T>(source.Count);
|
||||
|
||||
foreach (var val in source)
|
||||
{
|
||||
target.Add(serializationManager.CreateCopy(val, context, skipHook));
|
||||
target.Add(serializationManager.CreateCopy(val, hookCtx, context));
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
public IReadOnlyCollection<T> CreateCopy(ISerializationManager serializationManager, IReadOnlyCollection<T> source, bool skipHook,
|
||||
public IReadOnlyCollection<T> CreateCopy(ISerializationManager serializationManager, IReadOnlyCollection<T> source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
var target = new List<T>(source.Count);
|
||||
|
||||
foreach (var val in source)
|
||||
{
|
||||
target.Add(serializationManager.CreateCopy(val, context, skipHook));
|
||||
target.Add(serializationManager.CreateCopy(val, hookCtx, context));
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
public ImmutableList<T> CreateCopy(ISerializationManager serializationManager, ImmutableList<T> source, bool skipHook,
|
||||
public ImmutableList<T> CreateCopy(ISerializationManager serializationManager, ImmutableList<T> source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
var target = new List<T>(source.Count);
|
||||
|
||||
foreach (var val in source)
|
||||
{
|
||||
target.Add(serializationManager.CreateCopy(val, context, skipHook));
|
||||
target.Add(serializationManager.CreateCopy(val, hookCtx, context));
|
||||
}
|
||||
|
||||
return target.ToImmutableList();
|
||||
|
||||
@@ -15,14 +15,14 @@ public sealed class QueueSerializer<T> : ITypeSerializer<Queue<T>, SequenceDataN
|
||||
Queue<T> ITypeReader<Queue<T>, SequenceDataNode>.Read(ISerializationManager serializationManager,
|
||||
SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context, ISerializationManager.InstantiationDelegate<Queue<T>>? instanceProvider = null)
|
||||
{
|
||||
var queue = instanceProvider != null ? instanceProvider() : new Queue<T>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
queue.Enqueue(serializationManager.Read<T>(dataNode, context, skipHook));
|
||||
queue.Enqueue(serializationManager.Read<T>(dataNode, hookCtx, context));
|
||||
}
|
||||
|
||||
return queue;
|
||||
@@ -55,14 +55,14 @@ public sealed class QueueSerializer<T> : ITypeSerializer<Queue<T>, SequenceDataN
|
||||
return sequence;
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, Queue<T> source, ref Queue<T> target, bool skipHook, ISerializationContext? context = null)
|
||||
public void CopyTo(ISerializationManager serializationManager, Queue<T> source, ref Queue<T> target, SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
target.Clear();
|
||||
target.EnsureCapacity(source.Count);
|
||||
|
||||
foreach (var val in source)
|
||||
{
|
||||
target.Enqueue(serializationManager.CreateCopy(val, context, skipHook));
|
||||
target.Enqueue(serializationManager.CreateCopy(val, hookCtx, context));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,15 +16,15 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
{
|
||||
public (T1, T2) Read(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<(T1, T2)>? val = null)
|
||||
{
|
||||
if (node.Children.Count != 1)
|
||||
throw new InvalidMappingException("Less than or more than 1 mappings provided to ValueTupleSerializer");
|
||||
|
||||
var entry = node.Children.First();
|
||||
var v1 = serializationManager.Read<T1>(entry.Key, context, skipHook);
|
||||
var v2 = serializationManager.Read<T2>(entry.Value, context, skipHook);
|
||||
var v1 = serializationManager.Read<T1>(entry.Key, hookCtx, context);
|
||||
var v2 = serializationManager.Read<T2>(entry.Value, hookCtx, context);
|
||||
|
||||
return (v1, v2);
|
||||
}
|
||||
@@ -62,11 +62,11 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
}
|
||||
|
||||
public (T1, T2) CreateCopy(ISerializationManager serializationManager, (T1, T2) source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return (serializationManager.CreateCopy(source.Item1, context, skipHook),
|
||||
serializationManager.CreateCopy(source.Item2, context, skipHook));
|
||||
return (serializationManager.CreateCopy(source.Item1, hookCtx, context),
|
||||
serializationManager.CreateCopy(source.Item2, hookCtx, context));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
{
|
||||
public MapId Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<MapId>? instanceProvider = null)
|
||||
{
|
||||
@@ -43,7 +43,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
|
||||
[MustUseReturnValue]
|
||||
public MapId CreateCopy(ISerializationManager serializationManager, MapId source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new(source.Value);
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
}
|
||||
|
||||
public bool Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<bool>? instanceProvider = null)
|
||||
{
|
||||
return bool.Parse(node.Value);
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
}
|
||||
|
||||
public byte Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<byte>? instanceProvider = null)
|
||||
{
|
||||
return byte.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
}
|
||||
|
||||
public char Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<char>? instanceProvider = null)
|
||||
{
|
||||
return char.Parse(node.Value);
|
||||
@@ -33,5 +33,11 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
{
|
||||
return new ValueDataNode(value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
public char Copy(ISerializationManager serializationManager, char source, char target, bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
}
|
||||
|
||||
public decimal Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<decimal>? instanceProvider = null)
|
||||
{
|
||||
return Parse.Decimal(node.Value);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
}
|
||||
|
||||
public double Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<double>? instanceProvider = null)
|
||||
{
|
||||
return Parse.Double(node.Value);
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
}
|
||||
|
||||
public float Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<float>? instanceProvider = null)
|
||||
{
|
||||
return float.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
}
|
||||
|
||||
public int Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<int>? instanceProvider = null)
|
||||
{
|
||||
return Parse.Int32(node.Value);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
}
|
||||
|
||||
public long Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<long>? instanceProvider = null)
|
||||
{
|
||||
return Parse.Int64(node.Value);
|
||||
@@ -34,5 +34,11 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
{
|
||||
return new ValueDataNode(value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
public long Copy(ISerializationManager serializationManager, long source, long target, bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
}
|
||||
|
||||
public sbyte Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<sbyte>? instanceProvider = null)
|
||||
{
|
||||
return sbyte.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
}
|
||||
|
||||
public short Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<short>? instanceProvider = null)
|
||||
{
|
||||
return Parse.Int16(node.Value);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
}
|
||||
|
||||
public uint Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<uint>? instanceProvider = null)
|
||||
{
|
||||
return Parse.UInt32(node.Value);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
}
|
||||
|
||||
public ulong Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<ulong>? instanceProvider = null)
|
||||
{
|
||||
return Parse.UInt64(node.ToString());
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
}
|
||||
|
||||
public ushort Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<ushort>? instanceProvider = null)
|
||||
{
|
||||
return Parse.UInt16(node.Value);
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
{
|
||||
public Regex Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<Regex>? instanceProvider = null)
|
||||
{
|
||||
@@ -48,7 +48,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
|
||||
[MustUseReturnValue]
|
||||
public Regex CreateCopy(ISerializationManager serializationManager, Regex source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new(source.ToString(), source.Options, source.MatchTimeout);
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
{
|
||||
public ResourcePath Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<ResourcePath>? instanceProvider = null)
|
||||
{
|
||||
@@ -76,7 +76,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
|
||||
[MustUseReturnValue]
|
||||
public ResourcePath CreateCopy(ISerializationManager serializationManager, ResourcePath source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new(source.ToString());
|
||||
|
||||
@@ -28,26 +28,26 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
Texture ITypeReader<Texture, ValueDataNode>.Read(ISerializationManager serializationManager,
|
||||
ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context,
|
||||
SerializationHookContext hookCtx, ISerializationContext? context,
|
||||
ISerializationManager.InstantiationDelegate<Texture>? instanceProvider = null)
|
||||
{
|
||||
var path = serializationManager.Read<ResourcePath>(node, context, skipHook);
|
||||
var path = serializationManager.Read<ResourcePath>(node, hookCtx, context);
|
||||
return new Texture(path);
|
||||
}
|
||||
|
||||
SpriteSpecifier ITypeReader<SpriteSpecifier, ValueDataNode>.Read(ISerializationManager serializationManager,
|
||||
ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context,
|
||||
SerializationHookContext hookCtx, ISerializationContext? context,
|
||||
ISerializationManager.InstantiationDelegate<SpriteSpecifier>? instanceProvider = null)
|
||||
{
|
||||
return ((ITypeReader<Texture, ValueDataNode>)this).Read(serializationManager, node, dependencies, skipHook, context, (ISerializationManager.InstantiationDelegate<Texture>?)instanceProvider);
|
||||
return ((ITypeReader<Texture, ValueDataNode>)this).Read(serializationManager, node, dependencies, hookCtx, context, (ISerializationManager.InstantiationDelegate<Texture>?)instanceProvider);
|
||||
}
|
||||
|
||||
EntityPrototype ITypeReader<EntityPrototype, ValueDataNode>.Read(ISerializationManager serializationManager,
|
||||
ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context,
|
||||
SerializationHookContext hookCtx, ISerializationContext? context,
|
||||
ISerializationManager.InstantiationDelegate<EntityPrototype>? instanceProvider = null)
|
||||
{
|
||||
return new EntityPrototype(node.Value);
|
||||
@@ -56,7 +56,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
Rsi ITypeReader<Rsi, MappingDataNode>.Read(ISerializationManager serializationManager,
|
||||
MappingDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context,
|
||||
SerializationHookContext hookCtx, ISerializationContext? context,
|
||||
ISerializationManager.InstantiationDelegate<Rsi>? instanceProvider = null)
|
||||
{
|
||||
if (!node.TryGet("sprite", out var pathNode))
|
||||
@@ -69,20 +69,20 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
throw new InvalidMappingException("Expected state-node as a valuenode");
|
||||
}
|
||||
|
||||
var path = serializationManager.Read<ResourcePath>(pathNode, context, skipHook);
|
||||
var path = serializationManager.Read<ResourcePath>(pathNode, hookCtx, context);
|
||||
return new Rsi(path, valueDataNode.Value);
|
||||
}
|
||||
|
||||
SpriteSpecifier ITypeReader<SpriteSpecifier, MappingDataNode>.Read(ISerializationManager serializationManager,
|
||||
MappingDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context,
|
||||
SerializationHookContext hookCtx, ISerializationContext? context,
|
||||
ISerializationManager.InstantiationDelegate<SpriteSpecifier>? instanceProvider = null)
|
||||
{
|
||||
if (node.TryGet("entity", out var entityNode) && entityNode is ValueDataNode entityValueNode)
|
||||
return ((ITypeReader<EntityPrototype, ValueDataNode>)this).Read(serializationManager, entityValueNode, dependencies, skipHook, context, (ISerializationManager.InstantiationDelegate<EntityPrototype>?)instanceProvider);
|
||||
return ((ITypeReader<EntityPrototype, ValueDataNode>)this).Read(serializationManager, entityValueNode, dependencies, hookCtx, context, (ISerializationManager.InstantiationDelegate<EntityPrototype>?)instanceProvider);
|
||||
|
||||
return ((ITypeReader<Rsi, MappingDataNode>) this).Read(serializationManager, node, dependencies, skipHook, context, (ISerializationManager.InstantiationDelegate<Rsi>?)instanceProvider);
|
||||
return ((ITypeReader<Rsi, MappingDataNode>) this).Read(serializationManager, node, dependencies, hookCtx, context, (ISerializationManager.InstantiationDelegate<Rsi>?)instanceProvider);
|
||||
}
|
||||
|
||||
ValidationNode ITypeValidator<SpriteSpecifier, ValueDataNode>.Validate(ISerializationManager serializationManager,
|
||||
@@ -167,19 +167,19 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
return mapping;
|
||||
}
|
||||
|
||||
public Texture CreateCopy(ISerializationManager serializationManager, Texture source, bool skipHook,
|
||||
public Texture CreateCopy(ISerializationManager serializationManager, Texture source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new(source.TexturePath);
|
||||
}
|
||||
|
||||
public EntityPrototype CreateCopy(ISerializationManager serializationManager, EntityPrototype source,
|
||||
bool skipHook, ISerializationContext? context = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
return new(source.EntityPrototypeId);
|
||||
}
|
||||
|
||||
public Rsi CreateCopy(ISerializationManager serializationManager, Rsi source, bool skipHook,
|
||||
public Rsi CreateCopy(ISerializationManager serializationManager, Rsi source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new(source.RsiPath, source.RsiState);
|
||||
@@ -205,31 +205,31 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
}
|
||||
|
||||
public SpriteSpecifier CreateCopy(ISerializationManager serializationManager, SpriteSpecifier source,
|
||||
bool skipHook, ISerializationContext? context = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
return source switch
|
||||
{
|
||||
Rsi rsi
|
||||
=> CreateCopy(serializationManager, rsi, skipHook, context),
|
||||
=> CreateCopy(serializationManager, rsi, hookCtx, context),
|
||||
|
||||
Texture texture
|
||||
=> CreateCopy(serializationManager, texture, skipHook, context),
|
||||
=> CreateCopy(serializationManager, texture, hookCtx, context),
|
||||
|
||||
EntityPrototype entityPrototype
|
||||
=> CreateCopy(serializationManager, entityPrototype, skipHook, context),
|
||||
=> CreateCopy(serializationManager, entityPrototype, hookCtx, context),
|
||||
|
||||
_ => throw new InvalidOperationException("Invalid SpriteSpecifier specified!")
|
||||
};
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, Rsi source, ref Rsi target, bool skipHook,
|
||||
public void CopyTo(ISerializationManager serializationManager, Rsi source, ref Rsi target, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
target.RsiPath = source.RsiPath;
|
||||
target.RsiState = source.RsiState;
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, Texture source, ref Texture target, bool skipHook,
|
||||
public void CopyTo(ISerializationManager serializationManager, Texture source, ref Texture target, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
target.TexturePath = source.TexturePath;
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
{
|
||||
public string Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<string>? instanceProvider = null)
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
{
|
||||
public TimeSpan Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<TimeSpan>? instanceProvider = null)
|
||||
{
|
||||
@@ -42,7 +42,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
|
||||
[MustUseReturnValue]
|
||||
public TimeSpan CreateCopy(ISerializationManager serializationManager, TimeSpan source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return source;
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
}
|
||||
|
||||
public Type Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<Type>? instanceProvider = null)
|
||||
{
|
||||
if (Shortcuts.TryGetValue(node.Value, out var shortcutType))
|
||||
@@ -51,7 +51,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
return new ValueDataNode(value.FullName ?? value.Name);
|
||||
}
|
||||
|
||||
public Type CreateCopy(ISerializationManager serializationManager, Type source, bool skipHook,
|
||||
public Type CreateCopy(ISerializationManager serializationManager, Type source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return source;
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
{
|
||||
public UIBox2 Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<UIBox2>? instanceProvider = null)
|
||||
{
|
||||
@@ -67,7 +67,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
|
||||
[MustUseReturnValue]
|
||||
public UIBox2 CreateCopy(ISerializationManager serializationManager, UIBox2 source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new(source.Left, source.Top, source.Right, source.Bottom);
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
{
|
||||
public Vector2 Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<Vector2>? instanceProvider = null)
|
||||
{
|
||||
@@ -54,7 +54,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
}
|
||||
|
||||
public Vector2 CreateCopy(ISerializationManager serializationManager, Vector2 source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new(source.X, source.Y);
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
{
|
||||
public Vector2i Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<Vector2i>? instanceProvider = null)
|
||||
{
|
||||
@@ -54,7 +54,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
}
|
||||
|
||||
public Vector2i CreateCopy(ISerializationManager serializationManager, Vector2i source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new(source.X, source.Y);
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
{
|
||||
public Vector3 Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<Vector3>? instanceProvider = null)
|
||||
{
|
||||
@@ -57,7 +57,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
}
|
||||
|
||||
public Vector3 CreateCopy(ISerializationManager serializationManager, Vector3 source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new(source);
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
{
|
||||
public Vector4 Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<Vector4>? instanceProvider = null)
|
||||
{
|
||||
@@ -61,7 +61,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
}
|
||||
|
||||
public Vector4 CreateCopy(ISerializationManager serializationManager, Vector4 source,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new(source);
|
||||
|
||||
@@ -4,8 +4,11 @@ namespace Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
|
||||
public interface ITypeCopier<TType> : BaseSerializerInterfaces.ITypeInterface<TType>
|
||||
{
|
||||
void CopyTo(ISerializationManager serializationManager, TType source, ref TType target,
|
||||
bool skipHook,
|
||||
void CopyTo(
|
||||
ISerializationManager serializationManager,
|
||||
TType source,
|
||||
ref TType target,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null);
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,9 @@ namespace Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
public interface ITypeCopyCreator<TType> : BaseSerializerInterfaces.ITypeInterface<TType>
|
||||
{
|
||||
[MustUseReturnValue]
|
||||
TType CreateCopy(ISerializationManager serializationManager, TType source,
|
||||
bool skipHook,
|
||||
TType CreateCopy(
|
||||
ISerializationManager serializationManager,
|
||||
TType source,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Interfaces
|
||||
TType Read(ISerializationManager serializationManager,
|
||||
TNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null,
|
||||
ISerializationManager.InstantiationDelegate<TType>? instanceProvider = null);
|
||||
}
|
||||
|
||||
@@ -4,86 +4,33 @@ using JetBrains.Annotations;
|
||||
|
||||
namespace Robust.Shared.Utility;
|
||||
|
||||
// https://github.com/dotnet/runtime/issues/934
|
||||
// https://gist.github.com/LordJZ/92b7decebe52178a445a0b82f63e585a
|
||||
internal static class SpanSplitExtensions
|
||||
{
|
||||
public ref struct Enumerable<T> where T : IEquatable<T>
|
||||
public static bool SplitFindNext<T>(
|
||||
ref ReadOnlySpan<T> source,
|
||||
T splitOn,
|
||||
out ReadOnlySpan<T> splitValue)
|
||||
where T : IEquatable<T>
|
||||
{
|
||||
public Enumerable(ReadOnlySpan<T> span, T separator)
|
||||
if (source.IsEmpty)
|
||||
{
|
||||
Span = span;
|
||||
Separator = separator;
|
||||
splitValue = ReadOnlySpan<T>.Empty;
|
||||
return false;
|
||||
}
|
||||
|
||||
private ReadOnlySpan<T> Span { get; }
|
||||
private T Separator { get; }
|
||||
|
||||
public Enumerator<T> GetEnumerator() => new(Span, Separator);
|
||||
}
|
||||
|
||||
internal ref struct Enumerator<T> where T : IEquatable<T>
|
||||
{
|
||||
internal Enumerator(ReadOnlySpan<T> span, T separator)
|
||||
var idx = source.IndexOf(splitOn);
|
||||
if (idx == -1)
|
||||
{
|
||||
Span = span;
|
||||
Separator = separator;
|
||||
Current = default;
|
||||
|
||||
if (Span.IsEmpty)
|
||||
TrailingEmptyItem = true;
|
||||
// Take rest of remaining span.
|
||||
splitValue = source;
|
||||
source = ReadOnlySpan<T>.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
splitValue = source[..idx];
|
||||
source = source[(idx + 1)..];
|
||||
}
|
||||
|
||||
private ReadOnlySpan<T> Span { get; set; }
|
||||
private T Separator { get; }
|
||||
private static int SeparatorLength => 1;
|
||||
|
||||
private ReadOnlySpan<T> TrailingEmptyItemSentinel => Unsafe.As<T[]>(nameof(TrailingEmptyItemSentinel)).AsSpan();
|
||||
|
||||
private bool TrailingEmptyItem
|
||||
{
|
||||
get => Span == TrailingEmptyItemSentinel;
|
||||
set => Span = value ? TrailingEmptyItemSentinel : default;
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (TrailingEmptyItem)
|
||||
{
|
||||
TrailingEmptyItem = false;
|
||||
Current = default;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Span.IsEmpty)
|
||||
{
|
||||
Span = Current = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
var idx = Span.IndexOf(Separator);
|
||||
if (idx < 0)
|
||||
{
|
||||
Current = Span;
|
||||
Span = default;
|
||||
}
|
||||
else
|
||||
{
|
||||
Current = Span[..idx];
|
||||
Span = Span[(idx + SeparatorLength)..];
|
||||
if (Span.IsEmpty)
|
||||
TrailingEmptyItem = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ReadOnlySpan<T> Current { get; private set; }
|
||||
}
|
||||
|
||||
[Pure]
|
||||
internal static Enumerable<T> Split<T>(this ReadOnlySpan<T> span, T separator) where T : IEquatable<T>
|
||||
{
|
||||
return new Enumerable<T>(span, separator);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
24
Robust.Shared/Utility/WaitHandleHelpers.cs
Normal file
24
Robust.Shared/Utility/WaitHandleHelpers.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Robust.Shared.Utility;
|
||||
|
||||
internal static class WaitHandleHelpers
|
||||
{
|
||||
// https://learn.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/interop-with-other-asynchronous-patterns-and-types?redirectedfrom=MSDN#from-wait-handles-to-tap
|
||||
public static Task WaitOneAsync(WaitHandle handle)
|
||||
{
|
||||
var tcs = new TaskCompletionSource();
|
||||
var rwh = ThreadPool.RegisterWaitForSingleObject(
|
||||
handle,
|
||||
delegate { tcs.TrySetResult(); },
|
||||
null,
|
||||
-1,
|
||||
true);
|
||||
|
||||
var t = tcs.Task;
|
||||
t.ContinueWith(_ => rwh.Unregister(null));
|
||||
return t;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Network.Messages;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.UnitTesting
|
||||
@@ -48,6 +49,11 @@ namespace Robust.UnitTesting
|
||||
// Nada.
|
||||
}
|
||||
|
||||
public void AddStrings(DataNode dataNode)
|
||||
{
|
||||
// Nada.
|
||||
}
|
||||
|
||||
public void AddStrings(IEnumerable<string> strings)
|
||||
{
|
||||
// Nada.
|
||||
|
||||
@@ -62,7 +62,7 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
|
||||
|
||||
IoCManager.Resolve<ISerializationManager>().Initialize();
|
||||
var manager = IoCManager.Resolve<IPrototypeManager>();
|
||||
manager.RegisterType(typeof(EntityPrototype));
|
||||
manager.RegisterKind(typeof(EntityPrototype));
|
||||
manager.LoadFromStream(new StringReader(PROTOTYPES));
|
||||
manager.ResolveResults();
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ entities:
|
||||
resourceManager.MountString("/EnginePrototypes/TestMapEntity.yml", Prototype);
|
||||
|
||||
var protoMan = IoCManager.Resolve<IPrototypeManager>();
|
||||
protoMan.RegisterType(typeof(EntityPrototype));
|
||||
protoMan.RegisterKind(typeof(EntityPrototype));
|
||||
|
||||
protoMan.LoadDirectory(new ResourcePath("/EnginePrototypes"));
|
||||
protoMan.LoadDirectory(new ResourcePath("/Prototypes"));
|
||||
|
||||
@@ -308,7 +308,7 @@ namespace Robust.UnitTesting.Server
|
||||
container.Resolve<ISerializationManager>().Initialize();
|
||||
|
||||
var protoMan = container.Resolve<IPrototypeManager>();
|
||||
protoMan.RegisterType(typeof(EntityPrototype));
|
||||
protoMan.RegisterKind(typeof(EntityPrototype));
|
||||
_protoDelegate?.Invoke(protoMan);
|
||||
protoMan.ResolveResults();
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Robust.UnitTesting.Shared.Localization
|
||||
|
||||
var protoMan = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
protoMan.RegisterType(typeof(EntityPrototype));
|
||||
protoMan.RegisterKind(typeof(EntityPrototype));
|
||||
protoMan.LoadDirectory(new ResourcePath("/EnginePrototypes"));
|
||||
protoMan.ResolveResults();
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Robust.UnitTesting.Shared.Map
|
||||
{
|
||||
IoCManager.Resolve<ISerializationManager>().Initialize();
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
prototypeManager.RegisterType(typeof(EntityPrototype));
|
||||
prototypeManager.RegisterKind(typeof(EntityPrototype));
|
||||
prototypeManager.LoadFromStream(new StringReader(PROTOTYPES));
|
||||
prototypeManager.ResolveResults();
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Robust.UnitTesting.Shared.Prototypes
|
||||
|
||||
IoCManager.Resolve<ISerializationManager>().Initialize();
|
||||
_prototypes = (PrototypeManager) IoCManager.Resolve<IPrototypeManager>();
|
||||
_prototypes.RegisterType(typeof(EntityPrototype));
|
||||
_prototypes.RegisterKind(typeof(EntityPrototype));
|
||||
_prototypes.LoadString(InitialPrototypes);
|
||||
_prototypes.ResolveResults();
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Robust.UnitTesting.Shared.Prototypes
|
||||
|
||||
IoCManager.Resolve<ISerializationManager>().Initialize();
|
||||
manager = IoCManager.Resolve<IPrototypeManager>();
|
||||
manager.RegisterType(typeof(EntityPrototype));
|
||||
manager.RegisterKind(typeof(EntityPrototype));
|
||||
manager.LoadString(DOCUMENT);
|
||||
manager.ResolveResults();
|
||||
}
|
||||
@@ -126,7 +126,7 @@ namespace Robust.UnitTesting.Shared.Prototypes
|
||||
parent: {parent}";
|
||||
}
|
||||
|
||||
manager.RegisterType(typeof(CircleTestPrototype));
|
||||
manager.RegisterKind(typeof(CircleTestPrototype));
|
||||
|
||||
var directCircle = $@"{GenerateCircleTestPrototype("1", "2")}
|
||||
{GenerateCircleTestPrototype("2", "1")}";
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Robust.UnitTesting.Shared.Serialization
|
||||
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
prototypeManager.RegisterType(typeof(EntityPrototype));
|
||||
prototypeManager.RegisterKind(typeof(EntityPrototype));
|
||||
prototypeManager.LoadString(Prototypes);
|
||||
prototypeManager.ResolveResults();
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ public sealed partial class DataDefinitionTests
|
||||
}
|
||||
|
||||
public int Read(ISerializationManager serializationManager, ValueDataNode node, IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<int>? instanceProvider = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<int>? instanceProvider = null)
|
||||
{
|
||||
return SerializerReturnInt;
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public sealed partial class DataDefinitionTests
|
||||
}
|
||||
|
||||
public DataDummyStruct Read(ISerializationManager serializationManager, ValueDataNode node, IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<DataDummyStruct>? instanceProvider = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<DataDummyStruct>? instanceProvider = null)
|
||||
{
|
||||
return SerializerReturnStruct;
|
||||
}
|
||||
@@ -73,7 +73,7 @@ public sealed partial class DataDefinitionTests
|
||||
}
|
||||
|
||||
public DataDummyClass Read(ISerializationManager serializationManager, ValueDataNode node, IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<DataDummyClass>? instanceProvider = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<DataDummyClass>? instanceProvider = null)
|
||||
{
|
||||
return SerializerReturnClass;
|
||||
}
|
||||
@@ -84,37 +84,37 @@ public sealed partial class DataDefinitionTests
|
||||
return SerializerValueDataNode;
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, int source, ref int target, bool skipHook,
|
||||
public void CopyTo(ISerializationManager serializationManager, int source, ref int target, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
target = SerializerReturnInt;
|
||||
}
|
||||
|
||||
public int CreateCopy(ISerializationManager serializationManager, int source, bool skipHook,
|
||||
public int CreateCopy(ISerializationManager serializationManager, int source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return SerializerReturnInt;
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, DataDummyStruct source, ref DataDummyStruct target,
|
||||
bool skipHook, ISerializationContext? context = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
target = SerializerReturnStruct;
|
||||
}
|
||||
|
||||
public DataDummyStruct CreateCopy(ISerializationManager serializationManager, DataDummyStruct source, bool skipHook,
|
||||
public DataDummyStruct CreateCopy(ISerializationManager serializationManager, DataDummyStruct source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return SerializerReturnStruct;
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, DataDummyClass source, ref DataDummyClass target, bool skipHook,
|
||||
public void CopyTo(ISerializationManager serializationManager, DataDummyClass source, ref DataDummyClass target, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
target = SerializerReturnClass;
|
||||
}
|
||||
|
||||
public DataDummyClass CreateCopy(ISerializationManager serializationManager, DataDummyClass source, bool skipHook,
|
||||
public DataDummyClass CreateCopy(ISerializationManager serializationManager, DataDummyClass source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return SerializerReturnClass;
|
||||
@@ -148,7 +148,7 @@ public sealed partial class DataDefinitionTests
|
||||
}
|
||||
|
||||
public int Read(ISerializationManager serializationManager, SequenceDataNode node, IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<int>? instanceProvider = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<int>? instanceProvider = null)
|
||||
{
|
||||
return SerializerReturnInt;
|
||||
}
|
||||
@@ -161,7 +161,7 @@ public sealed partial class DataDefinitionTests
|
||||
|
||||
|
||||
public DataDummyStruct Read(ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<DataDummyStruct>? instanceProvider = null)
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<DataDummyStruct>? instanceProvider = null)
|
||||
{
|
||||
return SerializerReturnStruct;
|
||||
}
|
||||
@@ -173,7 +173,7 @@ public sealed partial class DataDefinitionTests
|
||||
}
|
||||
|
||||
public DataDummyClass Read(ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<DataDummyClass>? instanceProvider = null)
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<DataDummyClass>? instanceProvider = null)
|
||||
{
|
||||
return SerializerReturnClass;
|
||||
}
|
||||
@@ -184,37 +184,37 @@ public sealed partial class DataDefinitionTests
|
||||
return SerializerSequenceDataNode;
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, int source, ref int target, bool skipHook,
|
||||
public void CopyTo(ISerializationManager serializationManager, int source, ref int target, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
target = SerializerReturnInt;
|
||||
}
|
||||
|
||||
public int CreateCopy(ISerializationManager serializationManager, int source, bool skipHook,
|
||||
public int CreateCopy(ISerializationManager serializationManager, int source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return SerializerReturnInt;
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, DataDummyStruct source, ref DataDummyStruct target,
|
||||
bool skipHook, ISerializationContext? context = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
target = SerializerReturnStruct;
|
||||
}
|
||||
|
||||
public DataDummyStruct CreateCopy(ISerializationManager serializationManager, DataDummyStruct source, bool skipHook,
|
||||
public DataDummyStruct CreateCopy(ISerializationManager serializationManager, DataDummyStruct source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return SerializerReturnStruct;
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, DataDummyClass source, ref DataDummyClass target, bool skipHook,
|
||||
public void CopyTo(ISerializationManager serializationManager, DataDummyClass source, ref DataDummyClass target, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
target = SerializerReturnClass;
|
||||
}
|
||||
|
||||
public DataDummyClass CreateCopy(ISerializationManager serializationManager, DataDummyClass source, bool skipHook,
|
||||
public DataDummyClass CreateCopy(ISerializationManager serializationManager, DataDummyClass source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return SerializerReturnClass;
|
||||
@@ -248,7 +248,7 @@ public sealed partial class DataDefinitionTests
|
||||
}
|
||||
|
||||
public int Read(ISerializationManager serializationManager, MappingDataNode node, IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<int>? instanceProvider = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<int>? instanceProvider = null)
|
||||
{
|
||||
return SerializerReturnInt;
|
||||
}
|
||||
@@ -260,7 +260,7 @@ public sealed partial class DataDefinitionTests
|
||||
}
|
||||
|
||||
public DataDummyStruct Read(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<DataDummyStruct>? instanceProvider = null)
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<DataDummyStruct>? instanceProvider = null)
|
||||
{
|
||||
return SerializerReturnStruct;
|
||||
}
|
||||
@@ -272,7 +272,7 @@ public sealed partial class DataDefinitionTests
|
||||
}
|
||||
|
||||
public DataDummyClass Read(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<DataDummyClass>? instanceProvider = null)
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<DataDummyClass>? instanceProvider = null)
|
||||
{
|
||||
return SerializerReturnClass;
|
||||
}
|
||||
@@ -283,37 +283,37 @@ public sealed partial class DataDefinitionTests
|
||||
return SerializerMappingDataNode;
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, int source, ref int target, bool skipHook,
|
||||
public void CopyTo(ISerializationManager serializationManager, int source, ref int target, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
target = SerializerReturnInt;
|
||||
}
|
||||
|
||||
public int CreateCopy(ISerializationManager serializationManager, int source, bool skipHook,
|
||||
public int CreateCopy(ISerializationManager serializationManager, int source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return SerializerReturnInt;
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, DataDummyStruct source, ref DataDummyStruct target,
|
||||
bool skipHook, ISerializationContext? context = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
target = SerializerReturnStruct;
|
||||
}
|
||||
|
||||
public DataDummyStruct CreateCopy(ISerializationManager serializationManager, DataDummyStruct source, bool skipHook,
|
||||
public DataDummyStruct CreateCopy(ISerializationManager serializationManager, DataDummyStruct source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return SerializerReturnStruct;
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, DataDummyClass source, ref DataDummyClass target, bool skipHook,
|
||||
public void CopyTo(ISerializationManager serializationManager, DataDummyClass source, ref DataDummyClass target, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
target = SerializerReturnClass;
|
||||
}
|
||||
|
||||
public DataDummyClass CreateCopy(ISerializationManager serializationManager, DataDummyClass source, bool skipHook,
|
||||
public DataDummyClass CreateCopy(ISerializationManager serializationManager, DataDummyClass source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return SerializerReturnClass;
|
||||
|
||||
@@ -49,7 +49,7 @@ public sealed partial class ManagerTests : ISerializationContext
|
||||
}
|
||||
|
||||
public SerializerStruct Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<SerializerStruct>? instanceProvider = null)
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<SerializerStruct>? instanceProvider = null)
|
||||
{
|
||||
Assert.That(node, Is.EqualTo(SerializerRanDataNode));
|
||||
return SerializerStruct.SerializerReturn();
|
||||
@@ -62,13 +62,13 @@ public sealed partial class ManagerTests : ISerializationContext
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, SerializerStruct source, ref SerializerStruct target,
|
||||
bool skipHook, ISerializationContext? context = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
target.OneValue = source.OneValue;
|
||||
target.TwoValue = source.TwoValue;
|
||||
}
|
||||
|
||||
public SerializerStruct CreateCopy(ISerializationManager serializationManager, SerializerStruct source, bool skipHook,
|
||||
public SerializerStruct CreateCopy(ISerializationManager serializationManager, SerializerStruct source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new SerializerStruct(source.OneValue, source.TwoValue);
|
||||
@@ -84,7 +84,7 @@ public sealed partial class ManagerTests : ISerializationContext
|
||||
}
|
||||
|
||||
public SerializerStruct Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<SerializerStruct>? instanceProvider = null)
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<SerializerStruct>? instanceProvider = null)
|
||||
{
|
||||
Assert.That(node, Is.EqualTo(SerializerRanCustomDataNode));
|
||||
return SerializerStruct.SerializerCustomReturn();
|
||||
@@ -97,13 +97,13 @@ public sealed partial class ManagerTests : ISerializationContext
|
||||
}
|
||||
|
||||
public void CopyTo(ISerializationManager serializationManager, SerializerStruct source, ref SerializerStruct target,
|
||||
bool skipHook, ISerializationContext? context = null)
|
||||
SerializationHookContext hookCtx, ISerializationContext? context = null)
|
||||
{
|
||||
target.OneValue = source.OneValue;
|
||||
target.TwoValue = source.TwoValue;
|
||||
}
|
||||
|
||||
public SerializerStruct CreateCopy(ISerializationManager serializationManager, SerializerStruct source, bool skipHook,
|
||||
public SerializerStruct CreateCopy(ISerializationManager serializationManager, SerializerStruct source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new SerializerStruct(source.OneValue, source.TwoValue);
|
||||
@@ -132,7 +132,7 @@ public sealed partial class ManagerTests : ISerializationContext
|
||||
}
|
||||
|
||||
public SerializerClass Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<SerializerClass>? instanceProvider = null)
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<SerializerClass>? instanceProvider = null)
|
||||
{
|
||||
Assert.That(node, Is.EqualTo(SerializerRanDataNode));
|
||||
return SerializerClass.SerializerReturn();
|
||||
@@ -144,7 +144,7 @@ public sealed partial class ManagerTests : ISerializationContext
|
||||
return SerializerRanDataNode;
|
||||
}
|
||||
|
||||
public SerializerClass CreateCopy(ISerializationManager serializationManager, SerializerClass source, bool skipHook,
|
||||
public SerializerClass CreateCopy(ISerializationManager serializationManager, SerializerClass source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new SerializerClass(source.OneValue, source.TwoValue);
|
||||
@@ -160,7 +160,7 @@ public sealed partial class ManagerTests : ISerializationContext
|
||||
}
|
||||
|
||||
public SerializerClass Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<SerializerClass>? instanceProvider = null)
|
||||
IDependencyCollection dependencies, SerializationHookContext hookCtx, ISerializationContext? context = null, ISerializationManager.InstantiationDelegate<SerializerClass>? instanceProvider = null)
|
||||
{
|
||||
Assert.That(node, Is.EqualTo(SerializerRanCustomDataNode));
|
||||
return SerializerClass.SerializerCustomReturn();
|
||||
@@ -172,7 +172,7 @@ public sealed partial class ManagerTests : ISerializationContext
|
||||
return SerializerRanCustomDataNode;
|
||||
}
|
||||
|
||||
public SerializerClass CreateCopy(ISerializationManager serializationManager, SerializerClass source, bool skipHook,
|
||||
public SerializerClass CreateCopy(ISerializationManager serializationManager, SerializerClass source, SerializationHookContext hookCtx,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
return new SerializerClass(source.OneValue, source.TwoValue);
|
||||
|
||||
@@ -45,7 +45,7 @@ entitiesImmutableList:
|
||||
{
|
||||
var protoMan = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
protoMan.RegisterType(typeof(EntityPrototype));
|
||||
protoMan.RegisterKind(typeof(EntityPrototype));
|
||||
protoMan.LoadString(Prototypes);
|
||||
protoMan.ResolveResults();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user