mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 11:40:52 +01:00
Compare commits
12 Commits
reactjs-su
...
v0.9.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39afc98995 | ||
|
|
09586284dc | ||
|
|
a1ee4374b2 | ||
|
|
4de6f25f11 | ||
|
|
582d8a5587 | ||
|
|
ec53b04f99 | ||
|
|
950fc94408 | ||
|
|
58d12e6e09 | ||
|
|
94323005c4 | ||
|
|
4989842057 | ||
|
|
80172636a8 | ||
|
|
8491f7be24 |
@@ -1,4 +1,4 @@
|
||||
<Project>
|
||||
<!-- This file automatically reset by Tools/version.py -->
|
||||
<PropertyGroup><Version>0.8.86</Version></PropertyGroup>
|
||||
<PropertyGroup><Version>0.9.2.1</Version></PropertyGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Globalization;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -19,10 +18,10 @@ namespace Robust.Benchmarks.Serialization
|
||||
: new ErrorNode(node, $"Failed parsing int value: {node.Value}");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public int Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, int _ = default)
|
||||
{
|
||||
return new DeserializedValue<int>(int.Parse(node.Value, CultureInfo.InvariantCulture));
|
||||
return int.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, int value, bool alwaysWrite = false,
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Robust.Benchmarks.Serialization.Copy
|
||||
|
||||
var seedMapping = yamlStream.Documents[0].RootNode.ToDataNodeCast<SequenceDataNode>().Cast<MappingDataNode>(0);
|
||||
|
||||
Seed = SerializationManager.ReadValueOrThrow<SeedDataDefinition>(seedMapping);
|
||||
Seed = SerializationManager.Read<SeedDataDefinition>(seedMapping);
|
||||
}
|
||||
|
||||
private const string String = "ABC";
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Robust.Benchmarks.Serialization.Definitions
|
||||
Max: 10
|
||||
PotencyDivisor: 10";
|
||||
|
||||
[DataField("id", required: true)] public string ID { get; set; } = default!;
|
||||
[IdDataFieldAttribute] public string ID { get; set; } = default!;
|
||||
|
||||
#region Tracking
|
||||
[DataField("name")] public string Name { get; set; } = string.Empty;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Robust.Benchmarks.Serialization.Definitions;
|
||||
using Robust.Shared.Analyzers;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
@@ -42,32 +41,32 @@ namespace Robust.Benchmarks.Serialization.Read
|
||||
private ValueDataNode FlagThirtyOne { get; } = new("ThirtyOne");
|
||||
|
||||
[Benchmark]
|
||||
public string? ReadString()
|
||||
public string ReadString()
|
||||
{
|
||||
return SerializationManager.ReadValue<string>(StringNode);
|
||||
return SerializationManager.Read<string>(StringNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public int? ReadInteger()
|
||||
public int ReadInteger()
|
||||
{
|
||||
return SerializationManager.ReadValue<int>(IntNode);
|
||||
return SerializationManager.Read<int>(IntNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public DataDefinitionWithString? ReadDataDefinitionWithString()
|
||||
public DataDefinitionWithString ReadDataDefinitionWithString()
|
||||
{
|
||||
return SerializationManager.ReadValue<DataDefinitionWithString>(StringDataDefNode);
|
||||
return SerializationManager.Read<DataDefinitionWithString>(StringDataDefNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public SeedDataDefinition? ReadSeedDataDefinition()
|
||||
public SeedDataDefinition ReadSeedDataDefinition()
|
||||
{
|
||||
return SerializationManager.ReadValue<SeedDataDefinition>(SeedNode);
|
||||
return SerializationManager.Read<SeedDataDefinition>(SeedNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("flag")]
|
||||
public DeserializationResult ReadFlagZero()
|
||||
public object? ReadFlagZero()
|
||||
{
|
||||
return SerializationManager.ReadWithTypeSerializer(
|
||||
typeof(int),
|
||||
@@ -77,7 +76,7 @@ namespace Robust.Benchmarks.Serialization.Read
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("flag")]
|
||||
public DeserializationResult ReadThirtyOne()
|
||||
public object? ReadThirtyOne()
|
||||
{
|
||||
return SerializationManager.ReadWithTypeSerializer(
|
||||
typeof(int),
|
||||
@@ -87,7 +86,7 @@ namespace Robust.Benchmarks.Serialization.Read
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("customTypeSerializer")]
|
||||
public DeserializationResult ReadIntegerCustomSerializer()
|
||||
public object? ReadIntegerCustomSerializer()
|
||||
{
|
||||
return SerializationManager.ReadWithTypeSerializer(
|
||||
typeof(int),
|
||||
|
||||
@@ -46,84 +46,84 @@ namespace Robust.Benchmarks.Serialization
|
||||
[BenchmarkCategory("read")]
|
||||
public string[]? ReadEmptyString()
|
||||
{
|
||||
return SerializationManager.ReadValue<string[]>(EmptyNode);
|
||||
return SerializationManager.Read<string[]>(EmptyNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public string[]? ReadOneString()
|
||||
{
|
||||
return SerializationManager.ReadValue<string[]>(OneIntNode);
|
||||
return SerializationManager.Read<string[]>(OneIntNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public string[]? ReadTenStrings()
|
||||
{
|
||||
return SerializationManager.ReadValue<string[]>(TenIntsNode);
|
||||
return SerializationManager.Read<string[]>(TenIntsNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public int[]? ReadEmptyInt()
|
||||
{
|
||||
return SerializationManager.ReadValue<int[]>(EmptyNode);
|
||||
return SerializationManager.Read<int[]>(EmptyNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public int[]? ReadOneInt()
|
||||
{
|
||||
return SerializationManager.ReadValue<int[]>(OneIntNode);
|
||||
return SerializationManager.Read<int[]>(OneIntNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public int[]? ReadTenInts()
|
||||
{
|
||||
return SerializationManager.ReadValue<int[]>(TenIntsNode);
|
||||
return SerializationManager.Read<int[]>(TenIntsNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public DataDefinitionWithString[]? ReadEmptyStringDataDef()
|
||||
{
|
||||
return SerializationManager.ReadValue<DataDefinitionWithString[]>(EmptyNode);
|
||||
return SerializationManager.Read<DataDefinitionWithString[]>(EmptyNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public DataDefinitionWithString[]? ReadOneStringDataDef()
|
||||
{
|
||||
return SerializationManager.ReadValue<DataDefinitionWithString[]>(OneStringDefNode);
|
||||
return SerializationManager.Read<DataDefinitionWithString[]>(OneStringDefNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public DataDefinitionWithString[]? ReadTenStringDataDefs()
|
||||
{
|
||||
return SerializationManager.ReadValue<DataDefinitionWithString[]>(TenStringDefsNode);
|
||||
return SerializationManager.Read<DataDefinitionWithString[]>(TenStringDefsNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public SealedDataDefinitionWithString[]? ReadEmptySealedStringDataDef()
|
||||
{
|
||||
return SerializationManager.ReadValue<SealedDataDefinitionWithString[]>(EmptyNode);
|
||||
return SerializationManager.Read<SealedDataDefinitionWithString[]>(EmptyNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public SealedDataDefinitionWithString[]? ReadOneSealedStringDataDef()
|
||||
{
|
||||
return SerializationManager.ReadValue<SealedDataDefinitionWithString[]>(OneStringDefNode);
|
||||
return SerializationManager.Read<SealedDataDefinitionWithString[]>(OneStringDefNode);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
[BenchmarkCategory("read")]
|
||||
public SealedDataDefinitionWithString[]? ReadTenSealedStringDataDefs()
|
||||
{
|
||||
return SerializationManager.ReadValue<SealedDataDefinitionWithString[]>(TenStringDefsNode);
|
||||
return SerializationManager.Read<SealedDataDefinitionWithString[]>(TenStringDefsNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Robust.Benchmarks.Serialization.Write
|
||||
|
||||
var seedMapping = yamlStream.Documents[0].RootNode.ToDataNodeCast<SequenceDataNode>().Cast<MappingDataNode>(0);
|
||||
|
||||
Seed = SerializationManager.ReadValueOrThrow<SeedDataDefinition>(seedMapping);
|
||||
Seed = SerializationManager.Read<SeedDataDefinition>(seedMapping);
|
||||
}
|
||||
|
||||
private const string String = "ABC";
|
||||
|
||||
@@ -132,7 +132,7 @@ namespace Robust.Client
|
||||
_console.Initialize();
|
||||
_prototypeManager.Initialize();
|
||||
_prototypeManager.LoadDirectory(Options.PrototypeDirectory);
|
||||
_prototypeManager.Resync();
|
||||
_prototypeManager.ResolveResults();
|
||||
_entityManager.Initialize();
|
||||
_mapManager.Initialize();
|
||||
_gameStateManager.Initialize();
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Robust.Client.Graphics
|
||||
[Dependency] private readonly IResourceCache _resourceCache = default!;
|
||||
|
||||
[ViewVariables]
|
||||
[DataField("id", required: true)]
|
||||
[IdDataFieldAttribute]
|
||||
public string ID { get; } = default!;
|
||||
|
||||
private ShaderKind Kind;
|
||||
|
||||
@@ -497,7 +497,7 @@ namespace Robust.Client.Input
|
||||
|
||||
if (robustMapping.TryGet("binds", out var BaseKeyRegsNode))
|
||||
{
|
||||
var baseKeyRegs = serializationManager.ReadValueOrThrow<KeyBindingRegistration[]>(BaseKeyRegsNode);
|
||||
var baseKeyRegs = serializationManager.Read<KeyBindingRegistration[]>(BaseKeyRegsNode);
|
||||
|
||||
foreach (var reg in baseKeyRegs)
|
||||
{
|
||||
@@ -526,7 +526,7 @@ namespace Robust.Client.Input
|
||||
|
||||
if (userData && robustMapping.TryGet("leaveEmpty", out var node))
|
||||
{
|
||||
var leaveEmpty = serializationManager.ReadValueOrThrow<BoundKeyFunction[]>(node);
|
||||
var leaveEmpty = serializationManager.Read<BoundKeyFunction[]>(node);
|
||||
|
||||
if (leaveEmpty.Length > 0)
|
||||
{
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Reflection;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -16,26 +16,40 @@ namespace Robust.Client.Serialization
|
||||
[TypeSerializer]
|
||||
public sealed class AppearanceVisualizerSerializer : ITypeSerializer<AppearanceVisualizer, MappingDataNode>
|
||||
{
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, MappingDataNode node,
|
||||
public AppearanceVisualizer Read(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
ISerializationContext? context = null, AppearanceVisualizer? value = null)
|
||||
{
|
||||
Type? type = null;
|
||||
if (!node.TryGet("type", out var typeNode))
|
||||
throw new InvalidMappingException("No type specified for AppearanceVisualizer!");
|
||||
{
|
||||
if (value == null)
|
||||
throw new InvalidMappingException("No type specified for AppearanceVisualizer!");
|
||||
|
||||
if (typeNode is not ValueDataNode typeValueDataNode)
|
||||
throw new InvalidMappingException("Type node not a value node for AppearanceVisualizer!");
|
||||
type = value.GetType();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (typeNode is not ValueDataNode typeValueDataNode)
|
||||
throw new InvalidMappingException("Type node not a value node for AppearanceVisualizer!");
|
||||
|
||||
var type = IoCManager.Resolve<IReflectionManager>()
|
||||
.YamlTypeTagLookup(typeof(AppearanceVisualizer), typeValueDataNode.Value);
|
||||
if (type == null)
|
||||
throw new InvalidMappingException(
|
||||
$"Invalid type {typeValueDataNode.Value} specified for AppearanceVisualizer!");
|
||||
type = IoCManager.Resolve<IReflectionManager>()
|
||||
.YamlTypeTagLookup(typeof(AppearanceVisualizer), typeValueDataNode.Value);
|
||||
if (type == null)
|
||||
throw new InvalidMappingException(
|
||||
$"Invalid type {typeValueDataNode.Value} specified for AppearanceVisualizer!");
|
||||
|
||||
if(value != null && !type.IsInstanceOfType(value))
|
||||
{
|
||||
throw new InvalidMappingException(
|
||||
$"Specified Type does not match type of provided Value for AppearanceVisualizer! (TypeOfValue: {value.GetType()}, ProvidedValue: {type})");
|
||||
}
|
||||
}
|
||||
|
||||
var newNode = node.Copy();
|
||||
newNode.Remove("type");
|
||||
return serializationManager.Read(type, newNode, context, skipHook);
|
||||
return (AppearanceVisualizer) serializationManager.Read(type, newNode, context, skipHook, value)!;
|
||||
}
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, MappingDataNode node,
|
||||
|
||||
@@ -228,7 +228,7 @@ namespace Robust.Client.UserInterface.CustomControls
|
||||
|
||||
foreach (var prototype in prototypeManager.EnumeratePrototypes<EntityPrototype>())
|
||||
{
|
||||
if (prototype.Abstract)
|
||||
if (prototype.NoSpawn || prototype.Abstract)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -338,7 +338,7 @@ namespace Robust.Server
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
prototypeManager.Initialize();
|
||||
prototypeManager.LoadDirectory(Options.PrototypeDirectory);
|
||||
prototypeManager.Resync();
|
||||
prototypeManager.ResolveResults();
|
||||
|
||||
_consoleHost.Initialize();
|
||||
_entityManager.Startup();
|
||||
|
||||
@@ -11,7 +11,7 @@ public struct ChunkIndicesEnumerator
|
||||
private int _x;
|
||||
private int _y;
|
||||
|
||||
public ChunkIndicesEnumerator(Vector2 viewPos, float range, float chunkSize)
|
||||
public ChunkIndicesEnumerator(Vector2 viewPos, Vector2 range, float chunkSize)
|
||||
{
|
||||
_bottomLeft = ((viewPos - range) / chunkSize).Floored();
|
||||
// Also floor this as we get the whole chunk anyway.
|
||||
|
||||
@@ -43,7 +43,7 @@ internal sealed partial class PVSSystem : EntitySystem
|
||||
/// <summary>
|
||||
/// Size of the side of the view bounds square.
|
||||
/// </summary>
|
||||
private float _viewSize;
|
||||
private Vector2 _viewSize;
|
||||
|
||||
/// <summary>
|
||||
/// If PVS disabled then we'll track if we've dumped all entities on the player.
|
||||
@@ -118,7 +118,7 @@ internal sealed partial class PVSSystem : EntitySystem
|
||||
EntityManager.EntityDeleted += OnEntityDeleted;
|
||||
|
||||
_configManager.OnValueChanged(CVars.NetPVS, SetPvs, true);
|
||||
_configManager.OnValueChanged(CVars.NetMaxUpdateRange, OnViewsizeChanged, true);
|
||||
_configManager.OnValueChanged(CVars.NetDefaultUpdateRange, OnViewsizeChanged, true);
|
||||
|
||||
InitializeDirty();
|
||||
}
|
||||
@@ -144,14 +144,14 @@ internal sealed partial class PVSSystem : EntitySystem
|
||||
EntityManager.EntityDeleted -= OnEntityDeleted;
|
||||
|
||||
_configManager.UnsubValueChanged(CVars.NetPVS, SetPvs);
|
||||
_configManager.UnsubValueChanged(CVars.NetMaxUpdateRange, OnViewsizeChanged);
|
||||
_configManager.UnsubValueChanged(CVars.NetDefaultUpdateRange, OnViewsizeChanged);
|
||||
|
||||
ShutdownDirty();
|
||||
}
|
||||
|
||||
private void OnViewsizeChanged(float obj)
|
||||
private void OnViewsizeChanged(Vector2 obj)
|
||||
{
|
||||
_viewSize = obj * 2;
|
||||
_viewSize = obj;
|
||||
}
|
||||
|
||||
private void SetPvs(bool value)
|
||||
@@ -323,7 +323,6 @@ internal sealed partial class PVSSystem : EntitySystem
|
||||
{
|
||||
var playerChunks = new HashSet<int>[sessions.Length];
|
||||
var eyeQuery = EntityManager.GetEntityQuery<EyeComponent>();
|
||||
var transformQuery = EntityManager.GetEntityQuery<TransformComponent>();
|
||||
var viewerEntities = new EntityUid[sessions.Length][];
|
||||
|
||||
_chunkList.Clear();
|
||||
@@ -350,11 +349,17 @@ internal sealed partial class PVSSystem : EntitySystem
|
||||
|
||||
foreach (var eyeEuid in viewers)
|
||||
{
|
||||
var (viewPos, range, mapId) = CalcViewBounds(in eyeEuid, transformQuery);
|
||||
var xform = xformQuery.GetComponent(eyeEuid);
|
||||
var viewPos = xform.WorldPosition;
|
||||
var range = _viewSize;
|
||||
var mapId = xform.MapID;
|
||||
|
||||
uint visMask = EyeComponent.DefaultVisibilityMask;
|
||||
if (eyeQuery.TryGetComponent(eyeEuid, out var eyeComp))
|
||||
{
|
||||
visMask = eyeComp.VisibilityMask;
|
||||
range *= eyeComp.Zoom;
|
||||
}
|
||||
|
||||
// Get the nyoom dictionary for index lookups.
|
||||
if (!_mapIndices.TryGetValue(visMask, out var mapDict))
|
||||
@@ -399,7 +404,7 @@ internal sealed partial class PVSSystem : EntitySystem
|
||||
physicsQuery,
|
||||
true))
|
||||
{
|
||||
var localPos = transformQuery.GetComponent(mapGrid.GridEntityId).InvWorldMatrix.Transform(viewPos);
|
||||
var localPos = xformQuery.GetComponent(mapGrid.GridEntityId).InvWorldMatrix.Transform(viewPos);
|
||||
|
||||
var gridChunkEnumerator =
|
||||
new ChunkIndicesEnumerator(localPos, range, ChunkSize);
|
||||
@@ -963,13 +968,6 @@ internal sealed partial class PVSSystem : EntitySystem
|
||||
return viewerArray;
|
||||
}
|
||||
|
||||
// Read Safe
|
||||
private (Vector2 worldPos, float range, MapId mapId) CalcViewBounds(in EntityUid euid, EntityQuery<TransformComponent> transformQuery)
|
||||
{
|
||||
var xform = transformQuery.GetComponent(euid);
|
||||
return (xform.WorldPosition, _viewSize / 2f, xform.MapID);
|
||||
}
|
||||
|
||||
public sealed class SetPolicy<T> : PooledObjectPolicy<HashSet<T>>
|
||||
{
|
||||
public override HashSet<T> Create()
|
||||
|
||||
218
Robust.Server/Maps/GridSerializer.cs
Normal file
218
Robust.Server/Maps/GridSerializer.cs
Normal file
@@ -0,0 +1,218 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
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.Serialization.TypeSerializers.Interfaces;
|
||||
|
||||
namespace Robust.Server.Maps
|
||||
{
|
||||
[TypeSerializer]
|
||||
internal sealed class MapChunkSerializer : ITypeSerializer<MapChunk, MappingDataNode>
|
||||
{
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies, ISerializationContext? context = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public MapChunk Read(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, MapChunk? chunk = null)
|
||||
{
|
||||
var tileNode = (ValueDataNode)node["tiles"];
|
||||
var tileBytes = Convert.FromBase64String(tileNode.Value);
|
||||
|
||||
using var stream = new MemoryStream(tileBytes);
|
||||
using var reader = new BinaryReader(stream);
|
||||
|
||||
var mapManager = dependencies.Resolve<IMapManager>();
|
||||
mapManager.SuppressOnTileChanged = true;
|
||||
|
||||
if (chunk == null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Someone tried deserializing a gridchunk without passing a value.");
|
||||
}
|
||||
|
||||
if (context is not MapLoader.MapContext mapContext)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Someone tried serializing a gridchunk without passing {nameof(MapLoader.MapContext)} as context.");
|
||||
}
|
||||
|
||||
var tileMap = mapContext.TileMap;
|
||||
|
||||
if (tileMap == null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Someone tried deserializing a gridchunk before deserializing the tileMap.");
|
||||
}
|
||||
|
||||
chunk.SuppressCollisionRegeneration = true;
|
||||
|
||||
var tileDefinitionManager = dependencies.Resolve<ITileDefinitionManager>();
|
||||
|
||||
for (ushort y = 0; y < chunk.ChunkSize; y++)
|
||||
{
|
||||
for (ushort x = 0; x < chunk.ChunkSize; x++)
|
||||
{
|
||||
var id = reader.ReadUInt16();
|
||||
var flags = (TileRenderFlag)reader.ReadByte();
|
||||
var variant = reader.ReadByte();
|
||||
|
||||
var defName = tileMap[id];
|
||||
id = tileDefinitionManager[defName].TileId;
|
||||
|
||||
var tile = new Tile(id, flags, variant);
|
||||
chunk.SetTile(x, y, tile);
|
||||
}
|
||||
}
|
||||
|
||||
chunk.SuppressCollisionRegeneration = false;
|
||||
mapManager.SuppressOnTileChanged = false;
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, MapChunk value, bool alwaysWrite = false,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
var root = new MappingDataNode();
|
||||
var ind = new ValueDataNode($"{value.X},{value.Y}");
|
||||
root.Add("ind", ind);
|
||||
|
||||
var gridNode = new ValueDataNode();
|
||||
root.Add("tiles", gridNode);
|
||||
|
||||
gridNode.Value = SerializeTiles(value);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private static string SerializeTiles(MapChunk chunk)
|
||||
{
|
||||
// number of bytes written per tile, because sizeof(Tile) is useless.
|
||||
const int structSize = 4;
|
||||
|
||||
var nTiles = chunk.ChunkSize * chunk.ChunkSize * structSize;
|
||||
var barr = new byte[nTiles];
|
||||
|
||||
using (var stream = new MemoryStream(barr))
|
||||
using (var writer = new BinaryWriter(stream))
|
||||
{
|
||||
for (ushort y = 0; y < chunk.ChunkSize; y++)
|
||||
{
|
||||
for (ushort x = 0; x < chunk.ChunkSize; x++)
|
||||
{
|
||||
var tile = chunk.GetTile(x, y);
|
||||
writer.Write(tile.TypeId);
|
||||
writer.Write((byte)tile.Flags);
|
||||
writer.Write(tile.Variant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Convert.ToBase64String(barr);
|
||||
}
|
||||
|
||||
public MapChunk Copy(ISerializationManager serializationManager, MapChunk source, MapChunk target, bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
//todo paul make this be used
|
||||
[TypeSerializer]
|
||||
internal sealed class GridSerializer : ITypeSerializer<MapGrid, MappingDataNode>
|
||||
{
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies, ISerializationContext? context = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public MapGrid Read(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, MapGrid? grid = null)
|
||||
{
|
||||
var info = node.Get<MappingDataNode>("settings");
|
||||
var chunks = node.Get<SequenceDataNode>("chunks");
|
||||
ushort csz = 0;
|
||||
ushort tsz = 0;
|
||||
float sgsz = 0.0f;
|
||||
|
||||
foreach (var kvInfo in info.Cast<KeyValuePair<ValueDataNode, ValueDataNode>>())
|
||||
{
|
||||
var key = kvInfo.Key.Value;
|
||||
var val = kvInfo.Value.Value;
|
||||
if (key == "chunksize")
|
||||
csz = ushort.Parse(val);
|
||||
else if (key == "tilesize")
|
||||
tsz = ushort.Parse(val);
|
||||
else if (key == "snapsize")
|
||||
sgsz = float.Parse(val, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
//TODO: Pass in options
|
||||
if (context is not MapLoader.MapContext mapContext)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Someone tried serializing a mapgrid without passing {nameof(MapLoader.MapContext)} as context.");
|
||||
}
|
||||
|
||||
if (grid == null) throw new NotImplementedException();
|
||||
//todo paul grid ??= dependencies.Resolve<MapManager>().CreateUnboundGrid(mapContext.TargetMap);
|
||||
|
||||
foreach (var chunkNode in chunks.Cast<MappingDataNode>())
|
||||
{
|
||||
var (chunkOffsetX, chunkOffsetY) =
|
||||
serializationManager.Read<Vector2i>(chunkNode["ind"], context, skipHook);
|
||||
var chunk = grid.GetChunk(chunkOffsetX, chunkOffsetY);
|
||||
serializationManager.Read(typeof(MapChunkSerializer), chunkNode, context, skipHook, chunk);
|
||||
}
|
||||
|
||||
return grid;
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, MapGrid value, bool alwaysWrite = false,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
var gridn = new MappingDataNode();
|
||||
var info = new MappingDataNode();
|
||||
var chunkSeq = new SequenceDataNode();
|
||||
|
||||
gridn.Add("settings", info);
|
||||
gridn.Add("chunks", chunkSeq);
|
||||
|
||||
info.Add("chunksize", value.ChunkSize.ToString(CultureInfo.InvariantCulture));
|
||||
info.Add("tilesize", value.TileSize.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
var chunks = value.GetMapChunks();
|
||||
foreach (var chunk in chunks)
|
||||
{
|
||||
var chunkNode = serializationManager.WriteValue(chunk.Value);
|
||||
chunkSeq.Add(chunkNode);
|
||||
}
|
||||
|
||||
return gridn;
|
||||
}
|
||||
|
||||
public MapGrid Copy(ISerializationManager serializationManager, MapGrid source, MapGrid target, bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,14 +13,15 @@ using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Dynamics;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
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.Serialization.TypeSerializers.Interfaces;
|
||||
@@ -44,6 +45,7 @@ namespace Robust.Server.Maps
|
||||
[Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!;
|
||||
[Dependency] private readonly IServerEntityManagerInternal _serverEntityManager = default!;
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly ISerializationManager _serializationManager = default!;
|
||||
|
||||
public event Action<YamlStream, string>? LoadedMapData;
|
||||
|
||||
@@ -52,7 +54,7 @@ namespace Robust.Server.Maps
|
||||
{
|
||||
var grid = _mapManager.GetGrid(gridId);
|
||||
|
||||
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager, _prototypeManager);
|
||||
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager, _prototypeManager, _serializationManager);
|
||||
context.RegisterGrid(grid);
|
||||
var root = context.Serialize();
|
||||
var document = new YamlDocument(root);
|
||||
@@ -99,7 +101,7 @@ namespace Robust.Server.Maps
|
||||
}
|
||||
|
||||
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager,
|
||||
_prototypeManager, (YamlMappingNode) data.RootNode, mapId, options);
|
||||
_prototypeManager, _serializationManager, data.RootNode.ToDataNodeCast<MappingDataNode>(), mapId, options);
|
||||
context.Deserialize();
|
||||
grid = context.Grids[0];
|
||||
|
||||
@@ -139,7 +141,7 @@ namespace Robust.Server.Maps
|
||||
public void SaveMap(MapId mapId, string yamlPath)
|
||||
{
|
||||
Logger.InfoS("map", $"Saving map {mapId} to {yamlPath}");
|
||||
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager, _prototypeManager);
|
||||
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager, _prototypeManager, _serializationManager);
|
||||
foreach (var grid in _mapManager.GetAllMapGrids(mapId))
|
||||
{
|
||||
context.RegisterGrid(grid);
|
||||
@@ -206,7 +208,7 @@ namespace Robust.Server.Maps
|
||||
LoadedMapData?.Invoke(data.Stream, resPath.ToString());
|
||||
|
||||
var context = new MapContext(_mapManager, _tileDefinitionManager, _serverEntityManager,
|
||||
_prototypeManager, (YamlMappingNode) data.RootNode, mapId, options);
|
||||
_prototypeManager, _serializationManager, data.RootNode.ToDataNodeCast<MappingDataNode>(), mapId, options);
|
||||
context.Deserialize();
|
||||
|
||||
PostDeserialize(mapId, context);
|
||||
@@ -216,7 +218,7 @@ namespace Robust.Server.Maps
|
||||
/// <summary>
|
||||
/// Handles the primary bulk of state during the map serialization process.
|
||||
/// </summary>
|
||||
private sealed class MapContext : ISerializationContext, IEntityLoadContext,
|
||||
internal sealed class MapContext : ISerializationContext, IEntityLoadContext,
|
||||
ITypeSerializer<GridId, ValueDataNode>,
|
||||
ITypeSerializer<EntityUid, ValueDataNode>,
|
||||
ITypeReaderWriter<EntityUid, ValueDataNode>
|
||||
@@ -225,6 +227,7 @@ namespace Robust.Server.Maps
|
||||
private readonly ITileDefinitionManager _tileDefinitionManager;
|
||||
private readonly IServerEntityManagerInternal _serverEntityManager;
|
||||
private readonly IPrototypeManager _prototypeManager;
|
||||
private readonly ISerializationManager _serializationManager;
|
||||
|
||||
private readonly MapLoadOptions? _loadOptions;
|
||||
private readonly Dictionary<GridId, int> GridIDMap = new();
|
||||
@@ -235,19 +238,20 @@ namespace Robust.Server.Maps
|
||||
private readonly Dictionary<int, EntityUid> UidEntityMap = new();
|
||||
public readonly List<EntityUid> Entities = new();
|
||||
|
||||
private readonly List<(EntityUid, YamlMappingNode)> _entitiesToDeserialize
|
||||
private readonly List<(EntityUid, MappingDataNode)> _entitiesToDeserialize
|
||||
= new();
|
||||
|
||||
private bool IsBlueprintMode => GridIDMap.Count == 1;
|
||||
|
||||
private readonly YamlMappingNode RootNode;
|
||||
private readonly MapId TargetMap;
|
||||
private readonly MappingDataNode RootNode;
|
||||
public readonly MapId TargetMap;
|
||||
|
||||
private Dictionary<string, YamlMappingNode>? CurrentReadingEntityComponents;
|
||||
private Dictionary<string, MappingDataNode>? CurrentReadingEntityComponents;
|
||||
|
||||
private string? CurrentWritingComponent;
|
||||
private EntityUid? CurrentWritingEntity;
|
||||
|
||||
public IReadOnlyDictionary<ushort, string>? TileMap => _tileMap;
|
||||
private Dictionary<ushort, string>? _tileMap;
|
||||
|
||||
public Dictionary<(Type, Type), object> TypeReaders { get; }
|
||||
@@ -258,14 +262,16 @@ namespace Robust.Server.Maps
|
||||
public bool MapIsPostInit { get; private set; }
|
||||
|
||||
public MapContext(IMapManagerInternal maps, ITileDefinitionManager tileDefs,
|
||||
IServerEntityManagerInternal entities, IPrototypeManager prototypeManager)
|
||||
IServerEntityManagerInternal entities, IPrototypeManager prototypeManager,
|
||||
ISerializationManager serializationManager)
|
||||
{
|
||||
_mapManager = maps;
|
||||
_tileDefinitionManager = tileDefs;
|
||||
_serverEntityManager = entities;
|
||||
_prototypeManager = prototypeManager;
|
||||
_serializationManager = serializationManager;
|
||||
|
||||
RootNode = new YamlMappingNode();
|
||||
RootNode = new MappingDataNode();
|
||||
TypeWriters = new Dictionary<Type, object>()
|
||||
{
|
||||
{typeof(GridId), this},
|
||||
@@ -281,12 +287,14 @@ namespace Robust.Server.Maps
|
||||
public MapContext(IMapManagerInternal maps, ITileDefinitionManager tileDefs,
|
||||
IServerEntityManagerInternal entities,
|
||||
IPrototypeManager prototypeManager,
|
||||
YamlMappingNode node, MapId targetMapId, MapLoadOptions options)
|
||||
ISerializationManager serializationManager,
|
||||
MappingDataNode node, MapId targetMapId, MapLoadOptions options)
|
||||
{
|
||||
_mapManager = maps;
|
||||
_tileDefinitionManager = tileDefs;
|
||||
_serverEntityManager = entities;
|
||||
_loadOptions = options;
|
||||
_serializationManager = serializationManager;
|
||||
|
||||
RootNode = node;
|
||||
TargetMap = targetMapId;
|
||||
@@ -355,13 +363,13 @@ namespace Robust.Server.Maps
|
||||
private void VerifyEntitiesExist()
|
||||
{
|
||||
var fail = false;
|
||||
var entities = RootNode.GetNode<YamlSequenceNode>("entities");
|
||||
var entities = RootNode.Get<SequenceDataNode>("entities");
|
||||
var reportedError = new HashSet<string>();
|
||||
foreach (var entityDef in entities.Cast<YamlMappingNode>())
|
||||
foreach (var entityDef in entities.Cast<MappingDataNode>())
|
||||
{
|
||||
if (entityDef.TryGetNode("type", out var typeNode))
|
||||
if (entityDef.TryGet<ValueDataNode>("type", out var typeNode))
|
||||
{
|
||||
var type = typeNode.AsString();
|
||||
var type = typeNode.Value;
|
||||
if (!_prototypeManager.HasIndex<EntityPrototype>(type) && !reportedError.Contains(type))
|
||||
{
|
||||
Logger.Error("Missing prototype for map: {0}", type);
|
||||
@@ -384,7 +392,7 @@ namespace Robust.Server.Maps
|
||||
|
||||
foreach (var (entity, data) in _entitiesToDeserialize)
|
||||
{
|
||||
if (!data.TryGetNode("components", out YamlSequenceNode? componentList))
|
||||
if (!data.TryGet("components", out SequenceDataNode? componentList))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -399,7 +407,7 @@ namespace Robust.Server.Maps
|
||||
var castComp = (Component) component;
|
||||
var compName = compFactory.GetComponentName(castComp.GetType());
|
||||
|
||||
if (componentList.Any(p => p["type"].AsString() == compName))
|
||||
if (componentList.Cast<MappingDataNode>().Any(p => ((ValueDataNode)p["type"]).Value == compName))
|
||||
{
|
||||
if (prototype.Components.ContainsKey(compName))
|
||||
{
|
||||
@@ -487,7 +495,7 @@ namespace Robust.Server.Maps
|
||||
// Now we need to actually bind the MapGrids to their components so that you can resolve GridId -> EntityUid
|
||||
// After doing this, it should be 100% safe to use the MapManager API like normal.
|
||||
|
||||
var yamlGrids = RootNode.GetNode<YamlSequenceNode>("grids");
|
||||
var yamlGrids = RootNode.Get<SequenceDataNode>("grids");
|
||||
|
||||
// get ents that the grids will bind to
|
||||
var gridComps = new Dictionary<GridId, MapGridComponent>(_readGridIndices.Count);
|
||||
@@ -511,28 +519,30 @@ namespace Robust.Server.Maps
|
||||
{
|
||||
// Here is where the implicit index pairing magic happens from the yaml.
|
||||
var gridIndex = _readGridIndices[index];
|
||||
var yamlGrid = (YamlMappingNode)yamlGrids.Children[index];
|
||||
var yamlGrid = (MappingDataNode)yamlGrids[index];
|
||||
|
||||
// designed to throw if something is broken, every grid must map to an ent
|
||||
var gridComp = gridComps[gridIndex];
|
||||
|
||||
DebugTools.Assert(gridComp.GridIndex == gridIndex);
|
||||
|
||||
YamlMappingNode yamlGridInfo = (YamlMappingNode)yamlGrid["settings"];
|
||||
YamlSequenceNode yamlGridChunks = (YamlSequenceNode)yamlGrid["chunks"];
|
||||
MappingDataNode yamlGridInfo = (MappingDataNode)yamlGrid["settings"];
|
||||
SequenceDataNode yamlGridChunks = (SequenceDataNode)yamlGrid["chunks"];
|
||||
|
||||
var grid = AllocateMapGrid(gridComp, yamlGridInfo);
|
||||
|
||||
foreach (var chunkNode in yamlGridChunks.Cast<YamlMappingNode>())
|
||||
foreach (var chunkNode in yamlGridChunks.Cast<MappingDataNode>())
|
||||
{
|
||||
YamlGridSerializer.DeserializeChunk(_mapManager, grid, chunkNode, _tileMap!, _tileDefinitionManager);
|
||||
var (chunkOffsetX, chunkOffsetY) = _serializationManager.Read<Vector2i>(chunkNode["ind"]);
|
||||
var chunk = grid.GetChunk(chunkOffsetX, chunkOffsetY);
|
||||
_serializationManager.Read(chunkNode, this, value: chunk);
|
||||
}
|
||||
|
||||
Grids.Add(grid); // Grids are kept in index order
|
||||
}
|
||||
}
|
||||
|
||||
private static MapGrid AllocateMapGrid(MapGridComponent gridComp, YamlMappingNode yamlGridInfo)
|
||||
private static MapGrid AllocateMapGrid(MapGridComponent gridComp, MappingDataNode yamlGridInfo)
|
||||
{
|
||||
// sane defaults
|
||||
ushort csz = 16;
|
||||
@@ -540,8 +550,8 @@ namespace Robust.Server.Maps
|
||||
|
||||
foreach (var kvInfo in yamlGridInfo)
|
||||
{
|
||||
var key = kvInfo.Key.ToString();
|
||||
var val = kvInfo.Value.ToString();
|
||||
var key = ((ValueDataNode)kvInfo.Key).Value;
|
||||
var val = ((ValueDataNode)kvInfo.Value).Value;
|
||||
if (key == "chunksize")
|
||||
csz = ushort.Parse(val);
|
||||
else if (key == "tilesize")
|
||||
@@ -590,14 +600,14 @@ namespace Robust.Server.Maps
|
||||
|
||||
private void ReadMetaSection()
|
||||
{
|
||||
var meta = RootNode.GetNode<YamlMappingNode>("meta");
|
||||
var ver = meta.GetNode("format").AsInt();
|
||||
var meta = RootNode.Get<MappingDataNode>("meta");
|
||||
var ver = meta.Get<ValueDataNode>("format").AsInt();
|
||||
if (ver != MapFormatVersion)
|
||||
{
|
||||
throw new InvalidDataException("Cannot handle this map file version.");
|
||||
}
|
||||
|
||||
if (meta.TryGetNode("postmapinit", out var mapInitNode))
|
||||
if (meta.TryGet<ValueDataNode>("postmapinit", out var mapInitNode))
|
||||
{
|
||||
MapIsPostInit = mapInitNode.AsBool();
|
||||
}
|
||||
@@ -612,11 +622,11 @@ namespace Robust.Server.Maps
|
||||
// Load tile mapping so that we can map the stored tile IDs into the ones actually used at runtime.
|
||||
_tileMap = new Dictionary<ushort, string>();
|
||||
|
||||
var tileMap = RootNode.GetNode<YamlMappingNode>("tilemap");
|
||||
foreach (var (key, value) in tileMap)
|
||||
var tileMap = RootNode.Get<MappingDataNode>("tilemap");
|
||||
foreach (var (key, value) in tileMap.Children)
|
||||
{
|
||||
var tileId = (ushort) key.AsInt();
|
||||
var tileDefName = value.AsString();
|
||||
var tileId = (ushort) ((ValueDataNode)key).AsInt();
|
||||
var tileDefName = ((ValueDataNode)value).Value;
|
||||
_tileMap.Add(tileId, tileDefName);
|
||||
}
|
||||
}
|
||||
@@ -625,9 +635,9 @@ namespace Robust.Server.Maps
|
||||
{
|
||||
// sets up the mapping so the serializer can properly deserialize GridIds.
|
||||
|
||||
var yamlGrids = RootNode.GetNode<YamlSequenceNode>("grids");
|
||||
var yamlGrids = RootNode.Get<SequenceDataNode>("grids");
|
||||
|
||||
for (var i = 0; i < yamlGrids.Children.Count; i++)
|
||||
for (var i = 0; i < yamlGrids.Count; i++)
|
||||
{
|
||||
_readGridIndices.Add(_mapManager.GenerateGridId(null));
|
||||
}
|
||||
@@ -652,17 +662,17 @@ namespace Robust.Server.Maps
|
||||
|
||||
private void AllocEntities()
|
||||
{
|
||||
var entities = RootNode.GetNode<YamlSequenceNode>("entities");
|
||||
foreach (var entityDef in entities.Cast<YamlMappingNode>())
|
||||
var entities = RootNode.Get<SequenceDataNode>("entities");
|
||||
foreach (var entityDef in entities.Cast<MappingDataNode>())
|
||||
{
|
||||
string? type = null;
|
||||
if (entityDef.TryGetNode("type", out var typeNode))
|
||||
if (entityDef.TryGet<ValueDataNode>("type", out var typeNode))
|
||||
{
|
||||
type = typeNode.AsString();
|
||||
type = typeNode.Value;
|
||||
}
|
||||
|
||||
var uid = Entities.Count;
|
||||
if (entityDef.TryGetNode("uid", out var uidNode))
|
||||
if (entityDef.TryGet<ValueDataNode>("uid", out var uidNode))
|
||||
{
|
||||
uid = uidNode.AsInt();
|
||||
}
|
||||
@@ -684,15 +694,14 @@ namespace Robust.Server.Maps
|
||||
{
|
||||
foreach (var (entity, data) in _entitiesToDeserialize)
|
||||
{
|
||||
CurrentReadingEntityComponents = new Dictionary<string, YamlMappingNode>();
|
||||
if (data.TryGetNode("components", out YamlSequenceNode? componentList))
|
||||
CurrentReadingEntityComponents = new Dictionary<string, MappingDataNode>();
|
||||
if (data.TryGet("components", out SequenceDataNode? componentList))
|
||||
{
|
||||
foreach (var compData in componentList)
|
||||
foreach (var compData in componentList.Cast<MappingDataNode>())
|
||||
{
|
||||
var copy = new YamlMappingNode(((YamlMappingNode)compData).AsEnumerable());
|
||||
copy.Children.Remove(new YamlScalarNode("type"));
|
||||
//TODO Paul: maybe replace mapping with datanode
|
||||
CurrentReadingEntityComponents[compData["type"].AsString()] = copy;
|
||||
var datanode = compData.Copy();
|
||||
datanode.Remove("type");
|
||||
CurrentReadingEntityComponents[((ValueDataNode)compData["type"]).Value] = datanode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,12 +746,12 @@ namespace Robust.Server.Maps
|
||||
PopulateEntityList();
|
||||
WriteEntitySection();
|
||||
|
||||
return RootNode;
|
||||
return RootNode.ToYaml();
|
||||
}
|
||||
|
||||
private void WriteMetaSection()
|
||||
{
|
||||
var meta = new YamlMappingNode();
|
||||
var meta = new MappingDataNode();
|
||||
RootNode.Add("meta", meta);
|
||||
meta.Add("format", MapFormatVersion.ToString(CultureInfo.InvariantCulture));
|
||||
// TODO: Make these values configurable.
|
||||
@@ -764,7 +773,7 @@ namespace Robust.Server.Maps
|
||||
|
||||
private void WriteTileMapSection()
|
||||
{
|
||||
var tileMap = new YamlMappingNode();
|
||||
var tileMap = new MappingDataNode();
|
||||
RootNode.Add("tilemap", tileMap);
|
||||
foreach (var tileDefinition in _tileDefinitionManager)
|
||||
{
|
||||
@@ -774,12 +783,12 @@ namespace Robust.Server.Maps
|
||||
|
||||
private void WriteGridSection()
|
||||
{
|
||||
var grids = new YamlSequenceNode();
|
||||
var grids = new SequenceDataNode();
|
||||
RootNode.Add("grids", grids);
|
||||
|
||||
foreach (var grid in Grids)
|
||||
{
|
||||
var entry = YamlGridSerializer.SerializeGrid(grid);
|
||||
var entry = _serializationManager.WriteValue(grid, context: this);
|
||||
grids.Add(entry);
|
||||
}
|
||||
}
|
||||
@@ -843,14 +852,14 @@ namespace Robust.Server.Maps
|
||||
var serializationManager = IoCManager.Resolve<ISerializationManager>();
|
||||
var compFactory = IoCManager.Resolve<IComponentFactory>();
|
||||
var metaQuery = _serverEntityManager.GetEntityQuery<MetaDataComponent>();
|
||||
var entities = new YamlSequenceNode();
|
||||
var entities = new SequenceDataNode();
|
||||
RootNode.Add("entities", entities);
|
||||
|
||||
var prototypeCompCache = new Dictionary<string, Dictionary<string, MappingDataNode>>();
|
||||
foreach (var (saveId, entityUid) in UidEntityMap.OrderBy(e=>e.Key))
|
||||
{
|
||||
CurrentWritingEntity = entityUid;
|
||||
var mapping = new YamlMappingNode
|
||||
var mapping = new MappingDataNode
|
||||
{
|
||||
{"uid", saveId.ToString(CultureInfo.InvariantCulture)}
|
||||
};
|
||||
@@ -870,7 +879,7 @@ namespace Robust.Server.Maps
|
||||
}
|
||||
}
|
||||
|
||||
var components = new YamlSequenceNode();
|
||||
var components = new SequenceDataNode();
|
||||
|
||||
// See engine#636 for why the Distinct() call.
|
||||
foreach (var component in _serverEntityManager.GetComponents(entityUid))
|
||||
@@ -894,11 +903,11 @@ namespace Robust.Server.Maps
|
||||
{
|
||||
compMapping.Add("type", new ValueDataNode(compName));
|
||||
// Something actually got written!
|
||||
components.Add(compMapping.ToYamlNode());
|
||||
components.Add(compMapping);
|
||||
}
|
||||
}
|
||||
|
||||
if (components.Children.Count != 0)
|
||||
if (components.Count != 0)
|
||||
{
|
||||
mapping.Add("components", components);
|
||||
}
|
||||
@@ -908,8 +917,8 @@ namespace Robust.Server.Maps
|
||||
}
|
||||
|
||||
// Create custom object serializers that will correctly allow data to be overriden by the map file.
|
||||
IComponent IEntityLoadContext.GetComponentData(string componentName,
|
||||
IComponent? protoData)
|
||||
MappingDataNode IEntityLoadContext.GetComponentData(string componentName,
|
||||
MappingDataNode? protoData)
|
||||
{
|
||||
if (CurrentReadingEntityComponents == null)
|
||||
{
|
||||
@@ -919,20 +928,15 @@ namespace Robust.Server.Maps
|
||||
var serializationManager = IoCManager.Resolve<ISerializationManager>();
|
||||
var factory = IoCManager.Resolve<IComponentFactory>();
|
||||
|
||||
IComponent data = protoData != null
|
||||
? serializationManager.CreateCopy(protoData, this)!
|
||||
: (IComponent) Activator.CreateInstance(factory.GetRegistration(componentName).Type)!;
|
||||
|
||||
if (CurrentReadingEntityComponents.TryGetValue(componentName, out var mapping))
|
||||
{
|
||||
var mapData = (IDeserializedDefinition) serializationManager.Read(
|
||||
factory.GetRegistration(componentName).Type,
|
||||
mapping.ToDataNode(), this);
|
||||
var newData = serializationManager.PopulateDataDefinition(data, mapData);
|
||||
data = (IComponent) newData.RawValue!;
|
||||
if (protoData == null) return mapping.Copy();
|
||||
|
||||
return serializationManager.PushCompositionWithGenericNode(
|
||||
factory.GetRegistration(componentName).Type, new[] { protoData }, mapping, this);
|
||||
}
|
||||
|
||||
return data;
|
||||
return protoData ?? new MappingDataNode();
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetExtraComponentTypes()
|
||||
@@ -947,10 +951,10 @@ namespace Robust.Server.Maps
|
||||
: base(message) { }
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
public GridId Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
ISerializationContext? context = null, GridId _ = default)
|
||||
{
|
||||
// This is the code that deserializes the Grids index into the GridId. This has to happen between Grid allocation
|
||||
// and when grids are bound to their entities.
|
||||
@@ -966,7 +970,7 @@ namespace Robust.Server.Maps
|
||||
throw new MapLoadException($"Error in map file: found local grid ID '{val}' which does not exist.");
|
||||
}
|
||||
|
||||
return new DeserializedValue<GridId>(_readGridIndices[val]);
|
||||
return _readGridIndices[val];
|
||||
}
|
||||
|
||||
ValidationNode ITypeValidator<EntityUid, ValueDataNode>.Validate(ISerializationManager serializationManager,
|
||||
@@ -1032,15 +1036,15 @@ namespace Robust.Server.Maps
|
||||
}
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<EntityUid, ValueDataNode>.Read(ISerializationManager serializationManager,
|
||||
EntityUid ITypeReader<EntityUid, ValueDataNode>.Read(ISerializationManager serializationManager,
|
||||
ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context)
|
||||
ISerializationContext? context, EntityUid _)
|
||||
{
|
||||
if (node.Value == "null")
|
||||
{
|
||||
return new DeserializedValue<EntityUid>(EntityUid.Invalid);
|
||||
return EntityUid.Invalid;
|
||||
}
|
||||
|
||||
var val = int.Parse(node.Value);
|
||||
@@ -1048,11 +1052,11 @@ namespace Robust.Server.Maps
|
||||
if (val >= Entities.Count || !UidEntityMap.ContainsKey(val) || !Entities.TryFirstOrNull(e => e == UidEntityMap[val], out var entity))
|
||||
{
|
||||
Logger.ErrorS("map", "Error in map file: found local entity UID '{0}' which does not exist.", val);
|
||||
return null!;
|
||||
return EntityUid.Invalid;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DeserializedValue<EntityUid>(entity!.Value);
|
||||
return entity!.Value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.Server.Maps
|
||||
{
|
||||
internal static class YamlGridSerializer
|
||||
{
|
||||
public static YamlMappingNode SerializeGrid(IMapGrid mapGrid)
|
||||
{
|
||||
var grid = (IMapGridInternal) mapGrid;
|
||||
|
||||
var gridn = new YamlMappingNode();
|
||||
var info = new YamlMappingNode();
|
||||
var chunkSeq = new YamlSequenceNode();
|
||||
|
||||
gridn.Add("settings", info);
|
||||
gridn.Add("chunks", chunkSeq);
|
||||
|
||||
info.Add("chunksize", grid.ChunkSize.ToString(CultureInfo.InvariantCulture));
|
||||
info.Add("tilesize", grid.TileSize.ToString(CultureInfo.InvariantCulture));
|
||||
|
||||
var chunks = grid.GetMapChunks();
|
||||
foreach (var chunk in chunks)
|
||||
{
|
||||
var chunkNode = SerializeChunk(chunk.Value);
|
||||
chunkSeq.Add(chunkNode);
|
||||
}
|
||||
|
||||
return gridn;
|
||||
}
|
||||
|
||||
private static YamlNode SerializeChunk(MapChunk chunk)
|
||||
{
|
||||
var root = new YamlMappingNode();
|
||||
var value = new YamlScalarNode($"{chunk.X},{chunk.Y}");
|
||||
value.Style = ScalarStyle.DoubleQuoted;
|
||||
root.Add("ind", value);
|
||||
|
||||
var gridNode = new YamlScalarNode();
|
||||
root.Add("tiles", gridNode);
|
||||
|
||||
gridNode.Value = SerializeTiles(chunk);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
private static string SerializeTiles(MapChunk chunk)
|
||||
{
|
||||
// number of bytes written per tile, because sizeof(Tile) is useless.
|
||||
const int structSize = 4;
|
||||
|
||||
var nTiles = chunk.ChunkSize * chunk.ChunkSize * structSize;
|
||||
var barr = new byte[nTiles];
|
||||
|
||||
using (var stream = new MemoryStream(barr))
|
||||
using (var writer = new BinaryWriter(stream))
|
||||
{
|
||||
for (ushort y = 0; y < chunk.ChunkSize; y++)
|
||||
{
|
||||
for (ushort x = 0; x < chunk.ChunkSize; x++)
|
||||
{
|
||||
var tile = chunk.GetTile(x, y);
|
||||
writer.Write(tile.TypeId);
|
||||
writer.Write((byte)tile.Flags);
|
||||
writer.Write(tile.Variant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Convert.ToBase64String(barr);
|
||||
}
|
||||
|
||||
public static void DeserializeChunk(IMapManager mapMan, IMapGridInternal grid,
|
||||
YamlMappingNode chunkData,
|
||||
IReadOnlyDictionary<ushort, string> tileDefMapping,
|
||||
ITileDefinitionManager tileDefinitionManager)
|
||||
{
|
||||
var indNode = chunkData["ind"];
|
||||
var tileNode = chunkData["tiles"];
|
||||
|
||||
var (chunkOffsetX, chunkOffsetY) = indNode.AsVector2i();
|
||||
var tileBytes = Convert.FromBase64String(tileNode.ToString());
|
||||
|
||||
using var stream = new MemoryStream(tileBytes);
|
||||
using var reader = new BinaryReader(stream);
|
||||
|
||||
mapMan.SuppressOnTileChanged = true;
|
||||
|
||||
var chunk = grid.GetChunk(chunkOffsetX, chunkOffsetY);
|
||||
|
||||
chunk.SuppressCollisionRegeneration = true;
|
||||
|
||||
for (ushort y = 0; y < grid.ChunkSize; y++)
|
||||
{
|
||||
for (ushort x = 0; x < grid.ChunkSize; x++)
|
||||
{
|
||||
var id = reader.ReadUInt16();
|
||||
var flags = (TileRenderFlag)reader.ReadByte();
|
||||
var variant = reader.ReadByte();
|
||||
|
||||
var defName = tileDefMapping[id];
|
||||
id = tileDefinitionManager[defName].TileId;
|
||||
|
||||
var tile = new Tile(id, flags, variant);
|
||||
chunk.SetTile(x, y, tile);
|
||||
}
|
||||
}
|
||||
|
||||
chunk.SuppressCollisionRegeneration = false;
|
||||
mapMan.SuppressOnTileChanged = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Threading;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Physics;
|
||||
|
||||
@@ -121,8 +122,8 @@ namespace Robust.Shared
|
||||
/// View size to take for PVS calculations,
|
||||
/// as the size of the sides of a square centered on the view points of clients.
|
||||
/// </summary>
|
||||
public static readonly CVarDef<float> NetMaxUpdateRange =
|
||||
CVarDef.Create("net.maxupdaterange", 12.5f, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
|
||||
public static readonly CVarDef<Vector2> NetDefaultUpdateRange =
|
||||
CVarDef.Create("net.defaultupdaterange", new Vector2(12.5f, 12.5f), CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER);
|
||||
|
||||
/// <summary>
|
||||
/// The amount of new entities that can be sent to a client in a single game state, under PVS.
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
/// <summary>
|
||||
/// Increases the life stage from <see cref="ComponentLifeStage.PreAdd" /> to <see cref="ComponentLifeStage.Added" />,
|
||||
/// calling <see cref="OnAdd" />.
|
||||
/// after raising a <see cref="ComponentAdd"/> event.
|
||||
/// </summary>
|
||||
internal void LifeAddToEntity(IEntityManager entManager)
|
||||
{
|
||||
@@ -44,14 +44,7 @@ namespace Robust.Shared.GameObjects
|
||||
LifeStage = ComponentLifeStage.Adding;
|
||||
CreationTick = entManager.CurrentTick;
|
||||
entManager.EventBus.RaiseComponentEvent(this, CompAddInstance);
|
||||
OnAdd();
|
||||
|
||||
#if DEBUG
|
||||
if (LifeStage != ComponentLifeStage.Added)
|
||||
{
|
||||
DebugTools.Assert($"Component {this.GetType().Name} did not call base {nameof(OnAdd)} in derived method.");
|
||||
}
|
||||
#endif
|
||||
LifeStage = ComponentLifeStage.Added;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -166,14 +159,6 @@ namespace Robust.Shared.GameObjects
|
||||
private static readonly ComponentShutdown CompShutdownInstance = new();
|
||||
private static readonly ComponentRemove CompRemoveInstance = new();
|
||||
|
||||
/// <summary>
|
||||
/// Called when the component gets added to an entity.
|
||||
/// </summary>
|
||||
protected virtual void OnAdd()
|
||||
{
|
||||
LifeStage = ComponentLifeStage.Added;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when all of the entity's other components have been added and are available,
|
||||
/// But are not necessarily initialized yet. DO NOT depend on the values of other components to be correct.
|
||||
|
||||
@@ -87,6 +87,7 @@ namespace Robust.Shared.GameObjects
|
||||
/// </summary>
|
||||
internal LinkedList<Contact> Contacts = new();
|
||||
|
||||
[DataField("ignorePaused"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool IgnorePaused { get; set; }
|
||||
|
||||
internal SharedPhysicsMapComponent? PhysicsMap { get; set; }
|
||||
@@ -113,7 +114,8 @@ namespace Robust.Shared.GameObjects
|
||||
_angularVelocity = 0.0f;
|
||||
// SynchronizeFixtures(); TODO: When CCD
|
||||
}
|
||||
else
|
||||
// Even if it's dynamic if it can't collide then don't force it awake.
|
||||
else if (_canCollide)
|
||||
{
|
||||
SetAwake(true);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
using System;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
{
|
||||
// If you wanna use these, add it to some random prototype.
|
||||
@@ -11,24 +9,15 @@ namespace Robust.Shared.GameObjects
|
||||
/// <summary>
|
||||
/// Throws an exception in <see cref="OnAdd" />.
|
||||
/// </summary>
|
||||
public sealed class DebugExceptionOnAddComponent : Component
|
||||
{
|
||||
protected override void OnAdd() => throw new NotSupportedException();
|
||||
}
|
||||
public sealed class DebugExceptionOnAddComponent : Component { }
|
||||
|
||||
/// <summary>
|
||||
/// Throws an exception in <see cref="Initialize" />.
|
||||
/// </summary>
|
||||
public sealed class DebugExceptionInitializeComponent : Component
|
||||
{
|
||||
protected override void Initialize() => throw new NotSupportedException();
|
||||
}
|
||||
public sealed class DebugExceptionInitializeComponent : Component { }
|
||||
|
||||
/// <summary>
|
||||
/// Throws an exception in <see cref="Startup" />.
|
||||
/// </summary>
|
||||
public sealed class DebugExceptionStartupComponent : Component
|
||||
{
|
||||
protected override void Startup() => throw new NotSupportedException();
|
||||
}
|
||||
public sealed class DebugExceptionStartupComponent : Component { }
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
{
|
||||
[RegisterComponent]
|
||||
public sealed class IgnorePauseComponent : Component
|
||||
{
|
||||
protected override void OnAdd()
|
||||
{
|
||||
base.OnAdd();
|
||||
IoCManager.Resolve<IEntityManager>().GetComponent<MetaDataComponent>(Owner).EntityPaused = false;
|
||||
}
|
||||
|
||||
protected override void OnRemove()
|
||||
{
|
||||
base.OnRemove();
|
||||
var entMan = IoCManager.Resolve<IEntityManager>();
|
||||
if (IoCManager.Resolve<IMapManager>().IsMapPaused(entMan.GetComponent<TransformComponent>(Owner).MapID))
|
||||
{
|
||||
entMan.GetComponent<MetaDataComponent>(Owner).EntityPaused = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,12 +151,8 @@ namespace Robust.Shared.GameObjects
|
||||
if (_entityPaused == value)
|
||||
return;
|
||||
|
||||
var entMan = IoCManager.Resolve<IEntityManager>();
|
||||
if (value && entMan.HasComponent<IgnorePauseComponent>(Owner))
|
||||
return;
|
||||
|
||||
_entityPaused = value;
|
||||
entMan.EventBus.RaiseLocalEvent(Owner, new EntityPausedEvent(Owner, value));
|
||||
IoCManager.Resolve<IEntityManager>().EventBus.RaiseLocalEvent(Owner, new EntityPausedEvent(Owner, value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -417,7 +417,7 @@ namespace Robust.Shared.GameObjects
|
||||
var entity = AllocEntity(prototypeName, uid);
|
||||
try
|
||||
{
|
||||
EntityPrototype.LoadEntity(GetComponent<MetaDataComponent>(entity).EntityPrototype, entity, ComponentFactory, this, _serManager, null);
|
||||
EntityPrototype.LoadEntity(GetComponent<MetaDataComponent>(entity).EntityPrototype, entity, ComponentFactory, PrototypeManager, this, _serManager, null);
|
||||
return entity;
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -431,7 +431,7 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
private protected void LoadEntity(EntityUid entity, IEntityLoadContext? context)
|
||||
{
|
||||
EntityPrototype.LoadEntity(GetComponent<MetaDataComponent>(entity).EntityPrototype, entity, ComponentFactory, this, _serManager, context);
|
||||
EntityPrototype.LoadEntity(GetComponent<MetaDataComponent>(entity).EntityPrototype, entity, ComponentFactory, PrototypeManager, this, _serManager, context);
|
||||
}
|
||||
|
||||
private void InitializeAndStartEntity(EntityUid entity, MapId mapId)
|
||||
|
||||
@@ -410,7 +410,7 @@ public partial class EntitySystem
|
||||
|
||||
/// <inheritdoc cref="IEntityManager.TryGetComponent<T>(EntityUid?, out T)"/>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
protected bool TryComp<T>(EntityUid? uid, [NotNullWhen(true)] out T? comp)
|
||||
protected bool TryComp<T>([NotNullWhen(true)] EntityUid? uid, [NotNullWhen(true)] out T? comp)
|
||||
{
|
||||
if (!uid.HasValue)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Collections.Generic;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.Shared.GameObjects
|
||||
@@ -14,7 +15,7 @@ namespace Robust.Shared.GameObjects
|
||||
/// <summary>
|
||||
/// Gets the serializer used to ExposeData a specific component.
|
||||
/// </summary>
|
||||
IComponent GetComponentData(string componentName, IComponent? protoData);
|
||||
MappingDataNode GetComponentData(string componentName, MappingDataNode? protoData);
|
||||
|
||||
/// <summary>
|
||||
/// Gets extra component names that must also be instantiated on top of the ones defined in the prototype,
|
||||
|
||||
15
Robust.Shared/GameObjects/Systems/DebugExceptionSystem.cs
Normal file
15
Robust.Shared/GameObjects/Systems/DebugExceptionSystem.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace Robust.Shared.GameObjects;
|
||||
|
||||
public sealed class DebugExceptionSystem : EntitySystem
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<DebugExceptionOnAddComponent, ComponentAdd>((_, _, _) => throw new NotSupportedException());
|
||||
SubscribeLocalEvent<DebugExceptionInitializeComponent, ComponentInit>((_, _, _) => throw new NotSupportedException());
|
||||
SubscribeLocalEvent<DebugExceptionStartupComponent, ComponentStartup>((_, _, _) => throw new NotSupportedException());
|
||||
}
|
||||
}
|
||||
@@ -30,16 +30,15 @@ public abstract partial class SharedPhysicsSystem
|
||||
|
||||
if (component.CanCollide)
|
||||
{
|
||||
if (component.Awake)
|
||||
{
|
||||
EntityManager.EventBus.RaiseEvent(EventSource.Local, new PhysicsWakeMessage(component));
|
||||
}
|
||||
|
||||
if (!_containerSystem.IsEntityInContainer(uid))
|
||||
{
|
||||
// TODO: Probably a bad idea but ehh future sloth's problem; namely that we have to duplicate code between here and CanCollide.
|
||||
EntityManager.EventBus.RaiseLocalEvent(uid, new CollisionChangeMessage(component, uid, component._canCollide));
|
||||
}
|
||||
else
|
||||
{
|
||||
component._canCollide = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -58,8 +58,8 @@ namespace Robust.Shared.Localization
|
||||
|
||||
while (true)
|
||||
{
|
||||
var prototype = _prototype.Index<EntityPrototype>(prototypeId);
|
||||
var locId = prototype.CustomLocalizationID ?? $"ent-{prototypeId}";
|
||||
_prototype.TryIndex<EntityPrototype>(prototypeId, out var prototype);
|
||||
var locId = prototype?.CustomLocalizationID ?? $"ent-{prototypeId}";
|
||||
|
||||
if (TryGetMessage(locId, out var bundle, out var msg))
|
||||
{
|
||||
@@ -109,11 +109,11 @@ namespace Robust.Shared.Localization
|
||||
}
|
||||
}
|
||||
|
||||
name ??= prototype.SetName;
|
||||
desc ??= prototype.SetDesc;
|
||||
suffix ??= prototype.SetSuffix;
|
||||
name ??= prototype?.SetName;
|
||||
desc ??= prototype?.SetDesc;
|
||||
suffix ??= prototype?.SetSuffix;
|
||||
|
||||
if (prototype.LocProperties.Count != 0)
|
||||
if (prototype?.LocProperties != null && prototype.LocProperties.Count != 0)
|
||||
{
|
||||
foreach (var (attrib, value) in prototype.LocProperties)
|
||||
{
|
||||
@@ -125,7 +125,7 @@ namespace Robust.Shared.Localization
|
||||
}
|
||||
}
|
||||
|
||||
if (prototype.Parent == null)
|
||||
if (prototype?.Parent == null)
|
||||
break;
|
||||
|
||||
prototypeId = prototype.Parent;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using Lidgren.Network;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
@@ -66,6 +68,11 @@ namespace Robust.Shared.Network.Messages
|
||||
case CvarType.Double:
|
||||
value = buffer.ReadDouble();
|
||||
break;
|
||||
case CvarType.Vector2:
|
||||
var valX = buffer.ReadFloat();
|
||||
var valY = buffer.ReadFloat();
|
||||
value = new Vector2(valX, valY);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
@@ -116,6 +123,11 @@ namespace Robust.Shared.Network.Messages
|
||||
buffer.Write((byte)CvarType.Double);
|
||||
buffer.Write(val);
|
||||
break;
|
||||
case Vector2 val:
|
||||
buffer.Write((byte)CvarType.Vector2);
|
||||
buffer.Write(val.X);
|
||||
buffer.Write(val.Y);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
@@ -126,13 +138,13 @@ namespace Robust.Shared.Network.Messages
|
||||
{
|
||||
// ReSharper disable once UnusedMember.Local
|
||||
None,
|
||||
|
||||
Int,
|
||||
Long,
|
||||
Bool,
|
||||
String,
|
||||
Float,
|
||||
Double
|
||||
Double,
|
||||
Vector2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
@@ -98,11 +99,6 @@ namespace Robust.Shared.Physics.Dynamics
|
||||
/// </summary>
|
||||
private HashSet<PhysicsComponent> _islandSet = new();
|
||||
|
||||
private HashSet<PhysicsComponent> _queuedWake = new();
|
||||
private HashSet<PhysicsComponent> _queuedSleep = new();
|
||||
|
||||
private Queue<CollisionChangeMessage> _queuedCollisionMessages = new();
|
||||
|
||||
private List<PhysicsComponent> _islandBodies = new(64);
|
||||
private List<Contact> _islandContacts = new(32);
|
||||
private List<Joint> _islandJoints = new(8);
|
||||
@@ -127,10 +123,8 @@ namespace Robust.Shared.Physics.Dynamics
|
||||
if (Bodies.Contains(body)) return;
|
||||
|
||||
// TODO: Kinda dodgy with this and wake shit.
|
||||
// Look at my note under ProcessWakeQueue
|
||||
if (body.Awake && body.BodyType != BodyType.Static)
|
||||
{
|
||||
_queuedWake.Remove(body);
|
||||
AwakeBodies.Add(body);
|
||||
}
|
||||
|
||||
@@ -140,7 +134,20 @@ namespace Robust.Shared.Physics.Dynamics
|
||||
|
||||
public void AddAwakeBody(PhysicsComponent body)
|
||||
{
|
||||
_queuedWake.Add(body);
|
||||
if (body.BodyType == BodyType.Static)
|
||||
{
|
||||
Logger.ErrorS("physics", $"Tried to add static body {_entityManager.ToPrettyString(body.Owner)} as an awake body to map!");
|
||||
return;
|
||||
}
|
||||
|
||||
DebugTools.Assert(Bodies.Contains(body));
|
||||
if (!Bodies.Contains(body))
|
||||
{
|
||||
Logger.ErrorS("physics", $"Tried to add {_entityManager.ToPrettyString(body.Owner)} as an awake body to map when it's not contained on the map!");
|
||||
return;
|
||||
}
|
||||
|
||||
AwakeBodies.Add(body);
|
||||
}
|
||||
|
||||
public void RemoveBody(PhysicsComponent body)
|
||||
@@ -153,63 +160,11 @@ namespace Robust.Shared.Physics.Dynamics
|
||||
|
||||
public void RemoveSleepBody(PhysicsComponent body)
|
||||
{
|
||||
_queuedSleep.Add(body);
|
||||
AwakeBodies.Remove(body);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Queue
|
||||
private void ProcessChanges()
|
||||
{
|
||||
ProcessBodyChanges();
|
||||
ProcessWakeQueue();
|
||||
ProcessSleepQueue();
|
||||
}
|
||||
|
||||
private void ProcessBodyChanges()
|
||||
{
|
||||
while (_queuedCollisionMessages.Count > 0)
|
||||
{
|
||||
var message = _queuedCollisionMessages.Dequeue();
|
||||
|
||||
if (!message.Body.Deleted && message.Body.CanCollide)
|
||||
{
|
||||
AddBody(message.Body);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveBody(message.Body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessWakeQueue()
|
||||
{
|
||||
foreach (var body in _queuedWake)
|
||||
{
|
||||
// Sloth note: So FPE doesn't seem to handle static bodies being woken gracefully as they never sleep
|
||||
// (No static body's an island so can't increase their min sleep time).
|
||||
// AFAIK not adding it to woken bodies shouldn't matter for anything tm...
|
||||
if (!body.Awake || body.BodyType == BodyType.Static || !Bodies.Contains(body)) continue;
|
||||
AwakeBodies.Add(body);
|
||||
}
|
||||
|
||||
_queuedWake.Clear();
|
||||
}
|
||||
|
||||
private void ProcessSleepQueue()
|
||||
{
|
||||
foreach (var body in _queuedSleep)
|
||||
{
|
||||
if (body.Awake) continue;
|
||||
|
||||
AwakeBodies.Remove(body);
|
||||
}
|
||||
|
||||
_queuedSleep.Clear();
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Where the magic happens.
|
||||
/// </summary>
|
||||
@@ -217,10 +172,6 @@ namespace Robust.Shared.Physics.Dynamics
|
||||
/// <param name="prediction"></param>
|
||||
public void Step(float frameTime, bool prediction)
|
||||
{
|
||||
// The original doesn't call ProcessChanges quite so much but stuff like collision behaviors
|
||||
// can edit things during the solver so we'll just handle it as it comes up.
|
||||
ProcessChanges();
|
||||
|
||||
// Box2D does this at the end of a step and also here when there's a fixture update.
|
||||
// Given external stuff can move bodies we'll just do this here.
|
||||
// Unfortunately this NEEDS to be predicted to make pushing remotely fucking good.
|
||||
@@ -237,9 +188,6 @@ namespace Robust.Shared.Physics.Dynamics
|
||||
if (!prediction)
|
||||
ContactManager.PreSolve(frameTime);
|
||||
|
||||
// Remove all deleted entities etc.
|
||||
ProcessChanges();
|
||||
|
||||
// Integrate velocities, solve velocity constraints, and do integration.
|
||||
Solve(frameTime, dtRatio, invDt, prediction);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using Robust.Shared.Configuration;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Players;
|
||||
|
||||
@@ -78,7 +79,7 @@ namespace Robust.Shared.Player
|
||||
if (!cfgMan.GetCVar(CVars.NetPVS))
|
||||
return AddAllPlayers();
|
||||
|
||||
var pvsRange = cfgMan.GetCVar(CVars.NetMaxUpdateRange) * rangeMultiplier;
|
||||
var pvsRange = cfgMan.GetCVar(CVars.NetDefaultUpdateRange) * rangeMultiplier;
|
||||
|
||||
return AddInRange(origin, pvsRange, playerMan);
|
||||
}
|
||||
@@ -175,6 +176,13 @@ namespace Robust.Shared.Player
|
||||
(xform.WorldPosition - position.Position).Length < range, playerMan);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds all players in range of a position.
|
||||
/// </summary>
|
||||
public Filter AddInRange(MapCoordinates position, Vector2 range, ISharedPlayerManager? playerMan = null,
|
||||
IEntityManager? entMan = null)
|
||||
=> AddInRange(position, range.Length, playerMan, entMan);
|
||||
|
||||
/// <summary>
|
||||
/// Removes all players without the specified visibility flag.
|
||||
/// </summary>
|
||||
|
||||
@@ -10,6 +10,9 @@ using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
using Robust.Shared.ViewVariables;
|
||||
|
||||
@@ -39,7 +42,7 @@ namespace Robust.Shared.Prototypes
|
||||
/// The "in code name" of the object. Must be unique.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
[DataField("id")]
|
||||
[IdDataFieldAttribute]
|
||||
public string ID { get; private set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
@@ -98,8 +101,8 @@ namespace Robust.Shared.Prototypes
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
[NeverPushInheritance]
|
||||
[DataField("abstract")]
|
||||
public bool Abstract { get; private set; }
|
||||
[DataField("noSpawn")]
|
||||
public bool NoSpawn { get; private set; }
|
||||
|
||||
[DataField("placement")] private EntityPlacementProperties PlacementProperties = new();
|
||||
|
||||
@@ -138,9 +141,14 @@ namespace Robust.Shared.Prototypes
|
||||
/// The prototype we inherit from.
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
[DataField("parent", customTypeSerializer:typeof(PrototypeIdSerializer<EntityPrototype>))]
|
||||
[ParentDataFieldAttribute(typeof(PrototypeIdSerializer<EntityPrototype>))]
|
||||
public string? Parent { get; private set; }
|
||||
|
||||
[ViewVariables]
|
||||
[NeverPushInheritance]
|
||||
[AbstractDataField]
|
||||
public bool Abstract { get; }
|
||||
|
||||
/// <summary>
|
||||
/// A dictionary mapping the component type list to the YAML mapping containing their settings.
|
||||
/// </summary>
|
||||
@@ -233,6 +241,7 @@ namespace Robust.Shared.Prototypes
|
||||
EntityPrototype? prototype,
|
||||
EntityUid entity,
|
||||
IComponentFactory factory,
|
||||
IPrototypeManager prototypeManager,
|
||||
IEntityManager entityManager,
|
||||
ISerializationManager serManager,
|
||||
IEntityLoadContext? context) //yeah officer this method right here
|
||||
@@ -245,12 +254,22 @@ namespace Robust.Shared.Prototypes
|
||||
|
||||
if (prototype != null)
|
||||
{
|
||||
foreach (var (name, data) in prototype.Components)
|
||||
prototypeManager.TryGetMapping(typeof(EntityPrototype), prototype.ID, out var prototypeData);
|
||||
|
||||
foreach (var (name, _) in prototype.Components)
|
||||
{
|
||||
var fullData = data;
|
||||
MappingDataNode? fullData = null;
|
||||
if (prototypeData != null && prototypeData.TryGet<SequenceDataNode>("components", out var compList))
|
||||
{
|
||||
fullData = compList.Cast<MappingDataNode>().FirstOrDefault(x =>
|
||||
x.TryGet<ValueDataNode>("type", out var typeNode) && typeNode.Value == name);
|
||||
}
|
||||
|
||||
fullData ??= new MappingDataNode();
|
||||
|
||||
if (context != null)
|
||||
{
|
||||
fullData = context.GetComponentData(name, data);
|
||||
fullData = context.GetComponentData(name, fullData);
|
||||
}
|
||||
|
||||
EnsureCompExistsAndDeserialize(entity, factory, entityManager, serManager, name, fullData, context as ISerializationContext);
|
||||
@@ -281,7 +300,7 @@ namespace Robust.Shared.Prototypes
|
||||
IEntityManager entityManager,
|
||||
ISerializationManager serManager,
|
||||
string compName,
|
||||
IComponent data, ISerializationContext? context)
|
||||
MappingDataNode data, ISerializationContext? context)
|
||||
{
|
||||
var compType = factory.GetRegistration(compName).Type;
|
||||
|
||||
@@ -294,7 +313,7 @@ namespace Robust.Shared.Prototypes
|
||||
}
|
||||
|
||||
// TODO use this value to support struct components
|
||||
_ = serManager.Copy(data, component, context);
|
||||
serManager.Read(compType, data, context, value: component);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
using Robust.Shared.ViewVariables;
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using YamlDotNet.Core.Tokens;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.Shared.Prototypes
|
||||
@@ -25,4 +31,31 @@ namespace Robust.Shared.Prototypes
|
||||
|
||||
bool Abstract { get; }
|
||||
}
|
||||
|
||||
public sealed class IdDataFieldAttribute : DataFieldAttribute
|
||||
{
|
||||
public const string Name = "id";
|
||||
public IdDataFieldAttribute(int priority = 1, Type? customTypeSerializer = null) :
|
||||
base(Name, false, priority, true, false, customTypeSerializer)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class ParentDataFieldAttribute : DataFieldAttribute
|
||||
{
|
||||
public const string Name = "parent";
|
||||
public ParentDataFieldAttribute(Type prototypeIdSerializer, int priority = 1) :
|
||||
base(Name, false, priority, false, false, prototypeIdSerializer)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class AbstractDataFieldAttribute : DataFieldAttribute
|
||||
{
|
||||
public const string Name = "abstract";
|
||||
public AbstractDataFieldAttribute(int priority = 1) :
|
||||
base(Name, false, priority, false, false, null)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
using JetBrains.Annotations;
|
||||
using Prometheus;
|
||||
using Robust.Shared.Asynchronous;
|
||||
using Robust.Shared.ContentPack;
|
||||
using Robust.Shared.GameObjects;
|
||||
@@ -15,10 +16,10 @@ using Robust.Shared.Log;
|
||||
using Robust.Shared.Reflection;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
using Robust.Shared.Utility;
|
||||
using YamlDotNet.Core;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
@@ -79,6 +80,9 @@ namespace Robust.Shared.Prototypes
|
||||
bool TryIndex<T>(string id, [NotNullWhen(true)] out T? prototype) where T : class, IPrototype;
|
||||
bool TryIndex(Type type, string id, [NotNullWhen(true)] out IPrototype? prototype);
|
||||
|
||||
bool HasMapping<T>(string id);
|
||||
bool TryGetMapping(Type type, string id, [NotNullWhen(true)] out MappingDataNode? mappings);
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a prototype variant <param name="variant"/> exists.
|
||||
/// </summary>
|
||||
@@ -131,13 +135,13 @@ namespace Robust.Shared.Prototypes
|
||||
/// <summary>
|
||||
/// Load prototypes from files in a directory, recursively.
|
||||
/// </summary>
|
||||
List<IPrototype> LoadDirectory(ResourcePath path, bool overwrite = false);
|
||||
void LoadDirectory(ResourcePath path, bool overwrite = false, Dictionary<Type, HashSet<string>>? changed = null);
|
||||
|
||||
Dictionary<string, HashSet<ErrorNode>> ValidateDirectory(ResourcePath path);
|
||||
|
||||
List<IPrototype> LoadFromStream(TextReader stream, bool overwrite = false);
|
||||
void LoadFromStream(TextReader stream, bool overwrite = false, Dictionary<Type, HashSet<string>>? changed = null);
|
||||
|
||||
List<IPrototype> LoadString(string str, bool overwrite = false);
|
||||
void LoadString(string str, bool overwrite = false, Dictionary<Type, HashSet<string>>? changed = null);
|
||||
|
||||
void RemoveString(string prototypes);
|
||||
|
||||
@@ -149,7 +153,7 @@ namespace Robust.Shared.Prototypes
|
||||
/// <summary>
|
||||
/// Syncs all inter-prototype data. Call this when operations adding new prototypes are done.
|
||||
/// </summary>
|
||||
void Resync();
|
||||
void ResolveResults();
|
||||
|
||||
/// <summary>
|
||||
/// Registers a specific prototype name to be ignored.
|
||||
@@ -213,7 +217,7 @@ namespace Robust.Shared.Prototypes
|
||||
#region IPrototypeManager members
|
||||
|
||||
private readonly Dictionary<Type, Dictionary<string, IPrototype>> _prototypes = new();
|
||||
private readonly Dictionary<Type, Dictionary<string, DeserializationResult>> _prototypeResults = new();
|
||||
private readonly Dictionary<Type, Dictionary<string, MappingDataNode>> _prototypeResults = new();
|
||||
private readonly Dictionary<Type, PrototypeInheritanceTree> _inheritanceTrees = new();
|
||||
|
||||
private readonly HashSet<string> _ignoredPrototypeTypes = new();
|
||||
@@ -302,63 +306,62 @@ namespace Robust.Shared.Prototypes
|
||||
protected void ReloadPrototypes(IEnumerable<ResourcePath> filePaths)
|
||||
{
|
||||
#if !FULL_RELEASE
|
||||
var changed = filePaths.SelectMany(f => LoadFile(f.ToRootedPath(), true)).ToList();
|
||||
var changed = new Dictionary<Type, HashSet<string>>();
|
||||
foreach (var filePath in filePaths)
|
||||
{
|
||||
LoadFile(filePath.ToRootedPath(), true, changed);
|
||||
}
|
||||
ReloadPrototypes(changed);
|
||||
#endif
|
||||
}
|
||||
|
||||
internal void ReloadPrototypes(List<IPrototype> prototypes)
|
||||
internal void ReloadPrototypes(Dictionary<Type, HashSet<string>> prototypes)
|
||||
{
|
||||
#if !FULL_RELEASE
|
||||
prototypes.Sort((a, b) => SortPrototypesByPriority(a.GetType(), b.GetType()));
|
||||
var prototypeTypeOrder = prototypes.Keys.ToList();
|
||||
prototypeTypeOrder.Sort(SortPrototypesByPriority);
|
||||
|
||||
var pushed = new Dictionary<Type, HashSet<string>>();
|
||||
|
||||
foreach (var prototype in prototypes)
|
||||
foreach (var type in prototypeTypeOrder)
|
||||
{
|
||||
if (prototype is not IInheritingPrototype inheritingPrototype) continue;
|
||||
var type = prototype.GetType();
|
||||
if (!pushed.ContainsKey(type)) pushed[type] = new HashSet<string>();
|
||||
var baseNode = prototype.ID;
|
||||
|
||||
if (pushed[type].Contains(baseNode))
|
||||
if (!type.IsAssignableTo(typeof(IInheritingPrototype)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var tree = _inheritanceTrees[type];
|
||||
var currentNode = inheritingPrototype.Parent;
|
||||
|
||||
if (currentNode == null)
|
||||
{
|
||||
PushInheritance(type, baseNode, null, pushed[type]);
|
||||
continue;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
var parent = tree.GetParent(currentNode);
|
||||
|
||||
if (parent == null)
|
||||
foreach (var id in prototypes[type])
|
||||
{
|
||||
break;
|
||||
_prototypes[type][id] = (IPrototype) _serializationManager.Read(type, _prototypeResults[type][id])!;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var id in prototypes[type])
|
||||
{
|
||||
if (!pushed.ContainsKey(type))
|
||||
pushed[type] = new HashSet<string>();
|
||||
if (pushed[type].Contains(id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
baseNode = currentNode;
|
||||
currentNode = parent;
|
||||
var set = new HashSet<string>();
|
||||
set.Add(id);
|
||||
PushInheritance(type, id, _inheritanceTrees[type].GetParent(id), set);
|
||||
foreach (var changedId in set)
|
||||
{
|
||||
TryReadPrototype(type, changedId, _prototypeResults[type][changedId]);
|
||||
}
|
||||
pushed[type].UnionWith(set);
|
||||
}
|
||||
|
||||
PushInheritance(type, currentNode, baseNode, null, pushed[type]);
|
||||
}
|
||||
|
||||
//todo paul i hate it but i am not opening that can of worms in this refactor
|
||||
PrototypesReloaded?.Invoke(
|
||||
new PrototypesReloadedEventArgs(
|
||||
prototypes
|
||||
.GroupBy(p => p.GetType())
|
||||
.ToDictionary(
|
||||
g => g.Key,
|
||||
g => new PrototypesReloadedEventArgs.PrototypeChangeSet(
|
||||
g.ToDictionary(a => a.ID, a => a)))));
|
||||
g.Value.ToDictionary(a => a, a => _prototypes[g.Key][a])))));
|
||||
|
||||
// TODO filter by entity prototypes changed
|
||||
if (!pushed.ContainsKey(typeof(EntityPrototype))) return;
|
||||
@@ -379,90 +382,77 @@ namespace Robust.Shared.Prototypes
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Resync()
|
||||
/// <summary>
|
||||
/// Resolves the mappings stored in memory to actual prototypeinstances.
|
||||
/// </summary>
|
||||
public void ResolveResults()
|
||||
{
|
||||
var trees = _inheritanceTrees.Keys.ToList();
|
||||
trees.Sort(SortPrototypesByPriority);
|
||||
foreach (var type in trees)
|
||||
var types = _prototypeResults.Keys.ToList();
|
||||
types.Sort(SortPrototypesByPriority);
|
||||
foreach (var type in types)
|
||||
{
|
||||
var tree = _inheritanceTrees[type];
|
||||
foreach (var baseNode in tree.BaseNodes)
|
||||
{
|
||||
PushInheritance(type, baseNode, null, new HashSet<string>());
|
||||
}
|
||||
|
||||
// Go over all prototypes and double check that their parent actually exists.
|
||||
var typePrototypes = _prototypes[type];
|
||||
foreach (var (id, proto) in typePrototypes)
|
||||
{
|
||||
var iProto = (IInheritingPrototype) proto;
|
||||
|
||||
var parent = iProto.Parent;
|
||||
if (parent != null && !typePrototypes.ContainsKey(parent!))
|
||||
if(_inheritanceTrees.TryGetValue(type, out var tree)){
|
||||
foreach (var baseNode in tree.BaseNodes)
|
||||
{
|
||||
Logger.ErrorS("Serv3", $"{iProto.GetType().Name} '{id}' has invalid parent: {parent}");
|
||||
PushInheritance(type, baseNode);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var (id, mapping) in _prototypeResults[type])
|
||||
{
|
||||
TryReadPrototype(type, id, mapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void PushInheritance(Type type, string id, string child, DeserializationResult? baseResult,
|
||||
HashSet<string> changed)
|
||||
private void TryReadPrototype(Type type, string id, MappingDataNode mapping)
|
||||
{
|
||||
changed.Add(id);
|
||||
|
||||
var myRes = _prototypeResults[type][id];
|
||||
var newResult = baseResult != null ? myRes.PushInheritanceFrom(baseResult) : myRes;
|
||||
|
||||
PushInheritance(type, child, newResult, changed);
|
||||
|
||||
newResult.CallAfterDeserializationHook();
|
||||
var populatedRes =
|
||||
_serializationManager.PopulateDataDefinition(_prototypes[type][id], (IDeserializedDefinition) newResult);
|
||||
_prototypes[type][id] = (IPrototype) populatedRes.RawValue!;
|
||||
}
|
||||
|
||||
public void PushInheritance(Type type, string id, DeserializationResult? baseResult, HashSet<string> changed)
|
||||
{
|
||||
changed.Add(id);
|
||||
|
||||
var myRes = _prototypeResults[type][id];
|
||||
var newResult = baseResult != null ? myRes.PushInheritanceFrom(baseResult) : myRes;
|
||||
|
||||
foreach (var childID in _inheritanceTrees[type].Children(id))
|
||||
{
|
||||
PushInheritance(type, childID, newResult, changed);
|
||||
}
|
||||
|
||||
if (newResult.RawValue is not IInheritingPrototype inheritingPrototype)
|
||||
{
|
||||
Logger.ErrorS("Serv3", $"PushInheritance was called on non-inheriting prototype! ({type}, {id})");
|
||||
if(mapping.TryGet<ValueDataNode>(AbstractDataFieldAttribute.Name, out var abstractNode) && abstractNode.AsBool())
|
||||
return;
|
||||
try
|
||||
{
|
||||
_prototypes[type][id] = (IPrototype) _serializationManager.Read(type, mapping)!;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.ErrorS("PROTO", $"Reading {type}({id}) threw the following exception: {e}");
|
||||
}
|
||||
}
|
||||
|
||||
private void PushInheritance(Type type, string id, string? parent = null, HashSet<string>? changed = null)
|
||||
{
|
||||
if (parent != null)
|
||||
{
|
||||
PushInheritanceWithoutRecursion(type, id, parent, changed);
|
||||
}
|
||||
|
||||
if (!inheritingPrototype.Abstract)
|
||||
newResult.CallAfterDeserializationHook();
|
||||
var populatedRes =
|
||||
_serializationManager.PopulateDataDefinition(_prototypes[type][id], (IDeserializedDefinition) newResult);
|
||||
_prototypes[type][id] = (IPrototype) populatedRes.RawValue!;
|
||||
if(!_inheritanceTrees[type].HasId(id)) return;
|
||||
|
||||
foreach (var child in _inheritanceTrees[type].Children(id))
|
||||
{
|
||||
PushInheritance(type, child, id, changed);
|
||||
}
|
||||
}
|
||||
|
||||
private void PushInheritanceWithoutRecursion(Type type, string id, string parent,
|
||||
HashSet<string>? changed = null)
|
||||
{
|
||||
_prototypeResults[type][id] = _serializationManager.PushCompositionWithGenericNode(type,
|
||||
new[] { _prototypeResults[type][parent] }, _prototypeResults[type][id]);
|
||||
changed?.Add(id);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public List<IPrototype> LoadDirectory(ResourcePath path, bool overwrite = false)
|
||||
public void LoadDirectory(ResourcePath path, bool overwrite = false, Dictionary<Type, HashSet<string>>? changed = null)
|
||||
{
|
||||
var changedPrototypes = new List<IPrototype>();
|
||||
|
||||
_hasEverBeenReloaded = true;
|
||||
var streams = Resources.ContentFindFiles(path).ToList().AsParallel()
|
||||
.Where(filePath => filePath.Extension == "yml" && !filePath.Filename.StartsWith("."));
|
||||
|
||||
foreach (var resourcePath in streams)
|
||||
{
|
||||
var filePrototypes = LoadFile(resourcePath, overwrite);
|
||||
changedPrototypes.AddRange(filePrototypes);
|
||||
LoadFile(resourcePath, overwrite, changed);
|
||||
}
|
||||
|
||||
return changedPrototypes;
|
||||
}
|
||||
|
||||
public Dictionary<string, HashSet<ErrorNode>> ValidateDirectory(ResourcePath path)
|
||||
@@ -545,17 +535,15 @@ namespace Robust.Shared.Prototypes
|
||||
}
|
||||
}
|
||||
|
||||
public HashSet<IPrototype> LoadFile(ResourcePath file, bool overwrite = false)
|
||||
public void LoadFile(ResourcePath file, bool overwrite = false, Dictionary<Type, HashSet<string>>? changed = null)
|
||||
{
|
||||
var changedPrototypes = new HashSet<IPrototype>();
|
||||
|
||||
try
|
||||
{
|
||||
using var reader = ReadFile(file, !overwrite);
|
||||
|
||||
if (reader == null)
|
||||
{
|
||||
return changedPrototypes;
|
||||
return;
|
||||
}
|
||||
|
||||
var yamlStream = new YamlStream();
|
||||
@@ -567,8 +555,7 @@ namespace Robust.Shared.Prototypes
|
||||
{
|
||||
try
|
||||
{
|
||||
var documentPrototypes = LoadFromDocument(yamlStream.Documents[i], overwrite);
|
||||
changedPrototypes.UnionWith(documentPrototypes);
|
||||
LoadFromDocument(yamlStream.Documents[i], overwrite, changed);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -581,13 +568,10 @@ namespace Robust.Shared.Prototypes
|
||||
var sawmill = Logger.GetSawmill("eng");
|
||||
sawmill.Error("YamlException whilst loading prototypes from {0}: {1}", file, e.Message);
|
||||
}
|
||||
|
||||
return changedPrototypes;
|
||||
}
|
||||
|
||||
public List<IPrototype> LoadFromStream(TextReader stream, bool overwrite = false)
|
||||
public void LoadFromStream(TextReader stream, bool overwrite = false, Dictionary<Type, HashSet<string>>? changed = null)
|
||||
{
|
||||
var changedPrototypes = new List<IPrototype>();
|
||||
_hasEverBeenReloaded = true;
|
||||
var yaml = new YamlStream();
|
||||
yaml.Load(stream);
|
||||
@@ -596,8 +580,7 @@ namespace Robust.Shared.Prototypes
|
||||
{
|
||||
try
|
||||
{
|
||||
var documentPrototypes = LoadFromDocument(yaml.Documents[i], overwrite);
|
||||
changedPrototypes.AddRange(documentPrototypes);
|
||||
LoadFromDocument(yaml.Documents[i], overwrite, changed);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -606,13 +589,11 @@ namespace Robust.Shared.Prototypes
|
||||
}
|
||||
|
||||
LoadedData?.Invoke(yaml, "anonymous prototypes YAML stream");
|
||||
|
||||
return changedPrototypes;
|
||||
}
|
||||
|
||||
public List<IPrototype> LoadString(string str, bool overwrite = false)
|
||||
public void LoadString(string str, bool overwrite = false, Dictionary<Type, HashSet<string>>? changed = null)
|
||||
{
|
||||
return LoadFromStream(new StringReader(str), overwrite);
|
||||
LoadFromStream(new StringReader(str), overwrite, changed);
|
||||
}
|
||||
|
||||
public void RemoveString(string prototypes)
|
||||
@@ -653,14 +634,14 @@ namespace Robust.Shared.Prototypes
|
||||
}
|
||||
}
|
||||
|
||||
private HashSet<IPrototype> LoadFromDocument(YamlDocument document, bool overwrite = false)
|
||||
private void LoadFromDocument(YamlDocument document, bool overwrite = false, Dictionary<Type, HashSet<string>>? changed = null)
|
||||
{
|
||||
var changedPrototypes = new HashSet<IPrototype>();
|
||||
var rootNode = (YamlSequenceNode) document.RootNode;
|
||||
|
||||
foreach (YamlMappingNode node in rootNode.Cast<YamlMappingNode>())
|
||||
foreach (var node in rootNode.Cast<YamlMappingNode>())
|
||||
{
|
||||
var type = node.GetNode("type").AsString();
|
||||
var datanode = node.ToDataNodeCast<MappingDataNode>();
|
||||
var type = datanode.Get<ValueDataNode>("type").Value;
|
||||
if (!_prototypeTypes.ContainsKey(type))
|
||||
{
|
||||
if (_ignoredPrototypeTypes.Contains(type))
|
||||
@@ -672,30 +653,28 @@ namespace Robust.Shared.Prototypes
|
||||
}
|
||||
|
||||
var prototypeType = _prototypeTypes[type];
|
||||
var res = _serializationManager.Read(prototypeType, node.ToDataNode(), skipHook: true);
|
||||
var prototype = (IPrototype) res.RawValue!;
|
||||
|
||||
if (!overwrite && _prototypes[prototypeType].ContainsKey(prototype.ID))
|
||||
if (!datanode.TryGet<ValueDataNode>(IdDataFieldAttribute.Name, out var idNode))
|
||||
throw new PrototypeLoadException($"Prototype type {type} is missing an 'id' datafield.");
|
||||
|
||||
if (!overwrite && _prototypes[prototypeType].ContainsKey(idNode.Value))
|
||||
{
|
||||
throw new PrototypeLoadException($"Duplicate ID: '{prototype.ID}'");
|
||||
throw new PrototypeLoadException($"Duplicate ID: '{idNode.Value}'");
|
||||
}
|
||||
|
||||
_prototypeResults[prototypeType][prototype.ID] = res;
|
||||
if (prototype is IInheritingPrototype inheritingPrototype)
|
||||
_prototypeResults[prototypeType][idNode.Value] = datanode;
|
||||
if (prototypeType.IsAssignableTo(typeof(IInheritingPrototype)))
|
||||
{
|
||||
_inheritanceTrees[prototypeType].AddId(prototype.ID, inheritingPrototype.Parent, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
//we call it here since it wont get called when pushing inheritance
|
||||
res.CallAfterDeserializationHook();
|
||||
datanode.TryGet<ValueDataNode>(ParentDataFieldAttribute.Name, out var parentNode);
|
||||
_inheritanceTrees[prototypeType].AddId(idNode.Value, parentNode?.Value, true);
|
||||
}
|
||||
|
||||
_prototypes[prototypeType][prototype.ID] = prototype;
|
||||
changedPrototypes.Add(prototype);
|
||||
if (changed == null) continue;
|
||||
|
||||
if (!changed.TryGetValue(prototypeType, out var set))
|
||||
changed[prototypeType] = set = new HashSet<string>();
|
||||
set.Add(idNode.Value);
|
||||
}
|
||||
|
||||
return changedPrototypes;
|
||||
}
|
||||
|
||||
public bool HasIndex<T>(string id) where T : class, IPrototype
|
||||
@@ -725,6 +704,23 @@ namespace Robust.Shared.Prototypes
|
||||
return index.TryGetValue(id, out prototype);
|
||||
}
|
||||
|
||||
public bool HasMapping<T>(string id)
|
||||
{
|
||||
if (!_prototypeResults.TryGetValue(typeof(T), out var index))
|
||||
{
|
||||
throw new UnknownPrototypeException(id);
|
||||
}
|
||||
|
||||
return index.ContainsKey(id);
|
||||
}
|
||||
|
||||
public bool TryGetMapping(Type type, string id, [NotNullWhen(true)] out MappingDataNode? mappings)
|
||||
{
|
||||
var ret = _prototypeResults[type].TryGetValue(id, out var originalMappings);
|
||||
mappings = originalMappings?.Copy();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool HasVariant(string variant)
|
||||
{
|
||||
@@ -805,13 +801,66 @@ namespace Robust.Shared.Prototypes
|
||||
$"Duplicate prototype type ID: {attribute.Type}. Current: {_prototypeTypes[attribute.Type]}");
|
||||
}
|
||||
|
||||
var foundIdAttribute = false;
|
||||
var foundParentAttribute = false;
|
||||
var foundAbstractAttribute = false;
|
||||
foreach (var info in type.GetAllPropertiesAndFields())
|
||||
{
|
||||
var hasId = info.HasAttribute<IdDataFieldAttribute>();
|
||||
var hasParent = info.HasAttribute<ParentDataFieldAttribute>();
|
||||
if (hasId)
|
||||
{
|
||||
if (foundIdAttribute)
|
||||
throw new InvalidImplementationException(type,
|
||||
typeof(IPrototype),
|
||||
$"Found two {nameof(IdDataFieldAttribute)}");
|
||||
|
||||
foundIdAttribute = true;
|
||||
}
|
||||
|
||||
if (hasParent)
|
||||
{
|
||||
if (foundParentAttribute)
|
||||
throw new InvalidImplementationException(type,
|
||||
typeof(IInheritingPrototype),
|
||||
$"Found two {nameof(ParentDataFieldAttribute)}");
|
||||
|
||||
foundParentAttribute = true;
|
||||
}
|
||||
|
||||
if (hasId && hasParent)
|
||||
throw new InvalidImplementationException(type,
|
||||
typeof(IPrototype),
|
||||
$"Prototype {type} has the Id- & ParentDatafield on single member {info.Name}");
|
||||
|
||||
if (info.HasAttribute<AbstractDataFieldAttribute>())
|
||||
{
|
||||
if (foundAbstractAttribute)
|
||||
throw new InvalidImplementationException(type,
|
||||
typeof(IInheritingPrototype),
|
||||
$"Found two {nameof(AbstractDataFieldAttribute)}");
|
||||
|
||||
foundAbstractAttribute = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundIdAttribute)
|
||||
throw new InvalidImplementationException(type,
|
||||
typeof(IPrototype),
|
||||
$"Did not find any member annotated with the {nameof(IdDataFieldAttribute)}");
|
||||
|
||||
if (type.IsAssignableTo(typeof(IInheritingPrototype)) && (!foundParentAttribute || !foundAbstractAttribute))
|
||||
throw new InvalidImplementationException(type,
|
||||
typeof(IInheritingPrototype),
|
||||
$"Did not find any member annotated with the {nameof(ParentDataFieldAttribute)} and/or {nameof(AbstractDataFieldAttribute)}");
|
||||
|
||||
_prototypeTypes[attribute.Type] = type;
|
||||
_prototypePriorities[type] = attribute.LoadPriority;
|
||||
|
||||
if (typeof(IPrototype).IsAssignableFrom(type))
|
||||
{
|
||||
_prototypes[type] = new Dictionary<string, IPrototype>();
|
||||
_prototypeResults[type] = new Dictionary<string, DeserializationResult>();
|
||||
_prototypeResults[type] = new Dictionary<string, MappingDataNode>();
|
||||
if (typeof(IInheritingPrototype).IsAssignableFrom(type))
|
||||
_inheritanceTrees[type] = new PrototypeInheritanceTree();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ namespace Robust.Shared.Serialization.Manager.Attributes
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
[MeansImplicitAssignment]
|
||||
[MeansImplicitUse(ImplicitUseKindFlags.Assign)]
|
||||
public sealed class DataFieldAttribute : Attribute
|
||||
[Virtual]
|
||||
public class DataFieldAttribute : Attribute
|
||||
{
|
||||
public readonly string Tag;
|
||||
public readonly int Priority;
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
|
||||
namespace Robust.Shared.Serialization.Manager.Definition
|
||||
{
|
||||
public partial class DataDefinition
|
||||
{
|
||||
private delegate DeserializedFieldEntry[] DeserializeDelegate(
|
||||
private delegate object PopulateDelegateSignature(
|
||||
object target,
|
||||
MappingDataNode mappingDataNode,
|
||||
ISerializationManager serializationManager,
|
||||
ISerializationContext? context,
|
||||
bool skipHook);
|
||||
|
||||
private delegate DeserializationResult PopulateDelegateSignature(
|
||||
object target,
|
||||
DeserializedFieldEntry[] deserializationResults,
|
||||
bool skipHook,
|
||||
object?[] defaultValues);
|
||||
|
||||
private delegate MappingDataNode SerializeDelegateSignature(
|
||||
@@ -29,10 +25,6 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
ISerializationManager serializationManager,
|
||||
ISerializationContext? context);
|
||||
|
||||
private delegate DeserializationResult CreateDefinitionDelegate(
|
||||
object value,
|
||||
DeserializedFieldEntry[] mappings);
|
||||
|
||||
private delegate TValue AccessField<TTarget, TValue>(ref TTarget target);
|
||||
|
||||
private delegate void AssignField<TTarget, TValue>(ref TTarget target, TValue? value);
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
@@ -14,20 +13,22 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
{
|
||||
public partial class DataDefinition
|
||||
{
|
||||
private DeserializeDelegate EmitDeserializationDelegate()
|
||||
private PopulateDelegateSignature EmitPopulateDelegate()
|
||||
{
|
||||
DeserializedFieldEntry[] DeserializationDelegate(MappingDataNode mappingDataNode,
|
||||
ISerializationManager serializationManager, ISerializationContext? serializationContext, bool skipHook)
|
||||
object PopulateDelegate(
|
||||
object target,
|
||||
MappingDataNode mappingDataNode,
|
||||
ISerializationManager serializationManager,
|
||||
ISerializationContext? serializationContext,
|
||||
bool skipHook,
|
||||
object?[] defaultValues)
|
||||
{
|
||||
var mappedInfo = new DeserializedFieldEntry[BaseFieldDefinitions.Length];
|
||||
|
||||
for (var i = 0; i < BaseFieldDefinitions.Length; i++)
|
||||
{
|
||||
var fieldDefinition = BaseFieldDefinitions[i];
|
||||
|
||||
if (fieldDefinition.Attribute.ServerOnly && !IoCManager.Resolve<INetManager>().IsServer)
|
||||
{
|
||||
mappedInfo[i] = new DeserializedFieldEntry(false, fieldDefinition.InheritanceBehavior);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -35,13 +36,14 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
|
||||
if (!mapped)
|
||||
{
|
||||
mappedInfo[i] = new DeserializedFieldEntry(mapped, fieldDefinition.InheritanceBehavior);
|
||||
if (fieldDefinition.Attribute.Required)
|
||||
throw new InvalidOperationException($"Required field {fieldDefinition.Attribute.Tag} of type {target.GetType()} wasn't mapped.");
|
||||
continue;
|
||||
}
|
||||
|
||||
var type = fieldDefinition.FieldType;
|
||||
var node = mappingDataNode.Get(fieldDefinition.Attribute.Tag);
|
||||
DeserializationResult result;
|
||||
object? result;
|
||||
if (fieldDefinition.Attribute.CustomTypeSerializer != null)
|
||||
{
|
||||
var foundInterface = false;
|
||||
@@ -68,52 +70,17 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
result = serializationManager.Read(type, node, serializationContext, skipHook);
|
||||
}
|
||||
|
||||
var entry = new DeserializedFieldEntry(mapped, fieldDefinition.InheritanceBehavior, result);
|
||||
mappedInfo[i] = entry;
|
||||
}
|
||||
|
||||
return mappedInfo;
|
||||
}
|
||||
|
||||
return DeserializationDelegate;
|
||||
}
|
||||
|
||||
private PopulateDelegateSignature EmitPopulateDelegate()
|
||||
{
|
||||
// TODO Serialization: validate mappings array count
|
||||
var constructor =
|
||||
typeof(DeserializedDefinition<>).MakeGenericType(Type).GetConstructor(new[] {Type, typeof(DeserializedFieldEntry[])}) ??
|
||||
throw new NullReferenceException();
|
||||
|
||||
var valueParam = Expression.Parameter(typeof(object), "value");
|
||||
var valueParamCast = Expression.Convert(valueParam, Type);
|
||||
|
||||
var mappingParam = Expression.Parameter(typeof(DeserializedFieldEntry[]), "mapping");
|
||||
|
||||
var newExp = Expression.New(constructor, valueParamCast, mappingParam);
|
||||
var createDefinitionDelegate = Expression.Lambda<CreateDefinitionDelegate>(newExp, valueParam, mappingParam).Compile();
|
||||
|
||||
DeserializationResult PopulateDelegate(
|
||||
object target,
|
||||
DeserializedFieldEntry[] deserializedFields,
|
||||
object?[] defaultValues)
|
||||
{
|
||||
for (var i = 0; i < BaseFieldDefinitions.Length; i++)
|
||||
{
|
||||
var res = deserializedFields[i];
|
||||
if (!res.Mapped) continue;
|
||||
|
||||
var defValue = defaultValues[i];
|
||||
|
||||
if (Equals(res.Result?.RawValue, defValue))
|
||||
if (Equals(result, defValue))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FieldAssigners[i](ref target, res.Result?.RawValue);
|
||||
FieldAssigners[i](ref target, result);
|
||||
}
|
||||
|
||||
return createDefinitionDelegate(target, deserializedFields);
|
||||
return target;
|
||||
}
|
||||
|
||||
return PopulateDelegate;
|
||||
|
||||
@@ -5,7 +5,6 @@ using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -16,7 +15,6 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
{
|
||||
public sealed partial class DataDefinition
|
||||
{
|
||||
private readonly DeserializeDelegate _deserialize;
|
||||
private readonly PopulateDelegateSignature _populate;
|
||||
private readonly SerializeDelegateSignature _serialize;
|
||||
private readonly CopyDelegateSignature _copy;
|
||||
@@ -41,7 +39,6 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
BaseFieldDefinitions = fields.ToImmutableArray();
|
||||
DefaultValues = fieldDefs.Select(f => f.DefaultValue).ToArray();
|
||||
|
||||
_deserialize = EmitDeserializationDelegate();
|
||||
_populate = EmitPopulateDelegate();
|
||||
_serialize = EmitSerializeDelegate();
|
||||
_copy = EmitCopyDelegate();
|
||||
@@ -71,20 +68,14 @@ namespace Robust.Shared.Serialization.Manager.Definition
|
||||
|
||||
internal ImmutableArray<FieldDefinition> BaseFieldDefinitions { get; }
|
||||
|
||||
public DeserializationResult Populate(object target, DeserializedFieldEntry[] fields)
|
||||
{
|
||||
return _populate(target, fields, DefaultValues);
|
||||
}
|
||||
|
||||
public DeserializationResult Populate(
|
||||
public object Populate(
|
||||
object target,
|
||||
MappingDataNode mapping,
|
||||
ISerializationManager serialization,
|
||||
ISerializationContext? context,
|
||||
bool skipHook)
|
||||
{
|
||||
var fields = _deserialize(mapping, serialization, context, skipHook);
|
||||
return _populate(target, fields, DefaultValues);
|
||||
return _populate(target, mapping, serialization, context, skipHook, DefaultValues);
|
||||
}
|
||||
|
||||
public MappingDataNode Serialize(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Manager.Definition;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
@@ -25,7 +25,7 @@ namespace Robust.Shared.Serialization.Manager
|
||||
/// <param name="type">The type to check for.</param>
|
||||
/// <returns>True if it does, false otherwise.</returns>
|
||||
bool HasDataDefinition(Type type);
|
||||
|
||||
|
||||
#region Validation
|
||||
|
||||
/// <summary>
|
||||
@@ -59,52 +59,7 @@ namespace Robust.Shared.Serialization.Manager
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Creates a deserialization result from a generic type and its fields,
|
||||
/// populating the object.
|
||||
/// </summary>
|
||||
/// <param name="fields">The fields to use for deserialization.</param>
|
||||
/// <param name="skipHook">Whether or not to skip running <see cref="ISerializationHooks"/></param>
|
||||
/// <typeparam name="T">The type to populate.</typeparam>
|
||||
/// <returns>A result with the populated type.</returns>
|
||||
DeserializationResult CreateDataDefinition<T>(DeserializedFieldEntry[] fields, bool skipHook = false) where T : notnull, new();
|
||||
|
||||
#region Populate
|
||||
|
||||
/// <summary>
|
||||
/// Creates a deserialization result from a generic type and its definition,
|
||||
/// populating the object.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to populate.</param>
|
||||
/// <param name="definition">The data to use for deserialization.</param>
|
||||
/// <param name="skipHook">Whether or not to skip running <see cref="ISerializationHooks"/></param>
|
||||
/// <typeparam name="T">The type of <see cref="obj"/> to populate.</typeparam>
|
||||
/// <returns>A result with the populated object.</returns>
|
||||
DeserializationResult PopulateDataDefinition<T>(T obj, DeserializedDefinition<T> definition, bool skipHook = false) where T : notnull, new();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a deserialization result from an object and its definition,
|
||||
/// populating the object.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to populate.</param>
|
||||
/// <param name="definition">The data to use for deserialization.</param>
|
||||
/// <param name="skipHook">Whether or not to skip running <see cref="ISerializationHooks"/></param>
|
||||
/// <returns>A result with the populated object.</returns>
|
||||
DeserializationResult PopulateDataDefinition(object obj, IDeserializedDefinition definition, bool skipHook = false);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Read
|
||||
/// <summary>
|
||||
/// Deserializes a node into an object, populating it.
|
||||
/// </summary>
|
||||
/// <param name="type">The type of object to populate.</param>
|
||||
/// <param name="node">The node to deserialize.</param>
|
||||
/// <param name="context">The context to use, if any.</param>
|
||||
/// <param name="skipHook">Whether or not to skip running <see cref="ISerializationHooks"/></param>
|
||||
/// <returns>A result with the deserialized object.</returns>
|
||||
DeserializationResult Read(Type type, DataNode node, ISerializationContext? context = null, bool skipHook = false);
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a node into an object, populating it.
|
||||
/// </summary>
|
||||
@@ -112,20 +67,10 @@ namespace Robust.Shared.Serialization.Manager
|
||||
/// <param name="node">The node to deserialize.</param>
|
||||
/// <param name="context">The context to use, if any.</param>
|
||||
/// <param name="skipHook">Whether or not to skip running <see cref="ISerializationHooks"/></param>
|
||||
/// <param name="value">The value to read into. If none is supplied, a new object will be created.</param>
|
||||
/// <returns>The deserialized object or null.</returns>
|
||||
public object? ReadValue(Type type, DataNode node, ISerializationContext? context = null, bool skipHook = false);
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a node into an object of the given <see cref="type"/>,
|
||||
/// directly casting it to the given generic type <see cref="T"/>.
|
||||
/// </summary>
|
||||
/// <param name="type">The type of object to deserialize into.</param>
|
||||
/// <param name="node">The node to deserialize.</param>
|
||||
/// <param name="context">The context to use, if any.</param>
|
||||
/// <param name="skipHook">Whether or not to skip running <see cref="ISerializationHooks"/></param>
|
||||
/// <typeparam name="T">The generic type to cast the resulting object to.</typeparam>
|
||||
/// <returns>The deserialized casted object, or null.</returns>
|
||||
T? ReadValueCast<T>(Type type, DataNode node, ISerializationContext? context = null, bool skipHook = false);
|
||||
public object? Read(Type type, DataNode node, ISerializationContext? context = null, bool skipHook = false,
|
||||
object? value = null);
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a node into a populated object of the given generic type <see cref="T"/>
|
||||
@@ -133,12 +78,13 @@ namespace Robust.Shared.Serialization.Manager
|
||||
/// <param name="node">The node to deserialize.</param>
|
||||
/// <param name="context">The context to use, if any.</param>
|
||||
/// <param name="skipHook">Whether or not to skip running <see cref="ISerializationHooks"/></param>
|
||||
/// <param name="value">The value to read into. If none is supplied, a new object will be created.</param>
|
||||
/// <typeparam name="T">The type of object to create and populate.</typeparam>
|
||||
/// <returns>The deserialized object, or null.</returns>
|
||||
T? ReadValue<T>(DataNode node, ISerializationContext? context = null, bool skipHook = false);
|
||||
T Read<T>(DataNode node, ISerializationContext? context = null, bool skipHook = false, T? value = default);
|
||||
|
||||
DeserializationResult ReadWithTypeSerializer(Type value, Type serializer, DataNode node,
|
||||
ISerializationContext? context = null, bool skipHook = false);
|
||||
object? ReadWithTypeSerializer(Type type, Type serializer, DataNode node,
|
||||
ISerializationContext? context = null, bool skipHook = false, object? value = null);
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -253,5 +199,23 @@ namespace Robust.Shared.Serialization.Manager
|
||||
Type GetConstantTypeFromTag(Type tagType);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Composition
|
||||
|
||||
DataNode PushComposition(Type type, DataNode[] parents, DataNode child, ISerializationContext? context = null);
|
||||
|
||||
public TNode PushComposition<TType, TNode>(TNode[] parents, TNode child, ISerializationContext? context = null) where TNode : DataNode
|
||||
{
|
||||
// ReSharper disable once CoVariantArrayConversion
|
||||
return (TNode)PushComposition(typeof(TType), parents, child, context);
|
||||
}
|
||||
|
||||
public TNode PushCompositionWithGenericNode<TNode>(Type type, TNode[] parents, TNode child, ISerializationContext? context = null) where TNode : DataNode
|
||||
{
|
||||
// ReSharper disable once CoVariantArrayConversion
|
||||
return (TNode) PushComposition(type, parents, child, context);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
namespace Robust.Shared.Serialization.Manager.Result
|
||||
{
|
||||
public abstract class DeserializationResult
|
||||
{
|
||||
public abstract object? RawValue { get; }
|
||||
|
||||
public abstract DeserializationResult PushInheritanceFrom(DeserializationResult source);
|
||||
|
||||
public abstract DeserializationResult Copy();
|
||||
|
||||
public abstract void CallAfterDeserializationHook();
|
||||
|
||||
public T Cast<T>() where T : DeserializationResult
|
||||
{
|
||||
if (this is T value) return value;
|
||||
throw new InvalidDeserializedResultTypeException<T>(GetType());
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class DeserializationResult<T> : DeserializationResult
|
||||
{
|
||||
public abstract T? Value { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Robust.Shared.Serialization.Manager.Result
|
||||
{
|
||||
public sealed class DeserializedArray : DeserializationResult
|
||||
{
|
||||
public DeserializedArray(Array array, DeserializationResult[] mappings)
|
||||
{
|
||||
Value = array;
|
||||
Mappings = mappings;
|
||||
}
|
||||
|
||||
public Array Value { get; }
|
||||
|
||||
public DeserializationResult[] Mappings { get; }
|
||||
|
||||
public override object RawValue => Value;
|
||||
|
||||
public override DeserializationResult PushInheritanceFrom(DeserializationResult source)
|
||||
{
|
||||
var sourceCollection = source.Cast<DeserializedArray>();
|
||||
var values = (Array) Activator.CreateInstance(Value.GetType(), Value.Length)!;
|
||||
var results = new DeserializationResult[sourceCollection.Mappings.Length];
|
||||
|
||||
for (var i = 0; i < sourceCollection.Mappings.Length; i++)
|
||||
{
|
||||
var oldRes = sourceCollection.Mappings[i];
|
||||
var newRes = oldRes.Copy();
|
||||
|
||||
values.SetValue(newRes.RawValue, i);
|
||||
results[i] = newRes;
|
||||
}
|
||||
|
||||
for (var i = 0; i < Mappings.Length; i++)
|
||||
{
|
||||
var oldRes = Mappings[i];
|
||||
var newRes = oldRes.Copy();
|
||||
|
||||
values.SetValue(newRes.RawValue, i);
|
||||
results[i] = newRes;
|
||||
}
|
||||
|
||||
return new DeserializedArray(values, results);
|
||||
}
|
||||
|
||||
public override DeserializationResult Copy()
|
||||
{
|
||||
var values = (Array) Activator.CreateInstance(Value.GetType(), Value.Length)!;
|
||||
var results = new DeserializationResult[Mappings.Length];
|
||||
|
||||
for (var i = 0; i < Mappings.Length; i++)
|
||||
{
|
||||
var oldRes = Mappings[i];
|
||||
var newRes = oldRes.Copy();
|
||||
|
||||
values.SetValue(newRes.RawValue, i);
|
||||
results[i] = newRes;
|
||||
}
|
||||
|
||||
return new DeserializedArray(values, results);
|
||||
}
|
||||
|
||||
public override void CallAfterDeserializationHook()
|
||||
{
|
||||
foreach (var elem in Mappings)
|
||||
{
|
||||
elem.CallAfterDeserializationHook();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Robust.Shared.Serialization.Manager.Result
|
||||
{
|
||||
public sealed class DeserializedCollection<TCollection, TElement> : DeserializationResult<TCollection> where TCollection : IReadOnlyCollection<TElement>
|
||||
{
|
||||
public delegate TCollection Create(List<TElement> elements);
|
||||
|
||||
public DeserializedCollection(
|
||||
TCollection value,
|
||||
IEnumerable<DeserializationResult> mappings,
|
||||
Create createDelegate)
|
||||
{
|
||||
Value = value;
|
||||
Mappings = mappings;
|
||||
CreateDelegate = createDelegate;
|
||||
}
|
||||
|
||||
public override TCollection Value { get; }
|
||||
|
||||
public IEnumerable<DeserializationResult> Mappings { get; }
|
||||
|
||||
public override object RawValue => Value;
|
||||
|
||||
private Create CreateDelegate { get; }
|
||||
|
||||
public override DeserializationResult PushInheritanceFrom(DeserializationResult source)
|
||||
{
|
||||
var sourceCollection = source.Cast<DeserializedCollection<TCollection, TElement>>();
|
||||
var valueList = new List<TElement>();
|
||||
var resList = new List<DeserializationResult>();
|
||||
|
||||
foreach (var oldRes in sourceCollection.Mappings)
|
||||
{
|
||||
var newRes = oldRes.Copy().Cast<DeserializationResult<TElement>>();
|
||||
valueList.Add(newRes.Value!);
|
||||
resList.Add(newRes);
|
||||
}
|
||||
|
||||
foreach (var oldRes in Mappings)
|
||||
{
|
||||
var newRes = oldRes.Copy().Cast<DeserializationResult<TElement>>();
|
||||
valueList.Add(newRes.Value!);
|
||||
resList.Add(newRes);
|
||||
}
|
||||
|
||||
return new DeserializedCollection<TCollection, TElement>(CreateDelegate(valueList), resList, CreateDelegate);
|
||||
}
|
||||
|
||||
public override DeserializationResult Copy()
|
||||
{
|
||||
var valueList = new List<TElement>();
|
||||
var resList = new List<DeserializationResult>();
|
||||
|
||||
foreach (var oldRes in Mappings)
|
||||
{
|
||||
var newRes = oldRes.Copy();
|
||||
valueList.Add((TElement) newRes.RawValue!);
|
||||
resList.Add(newRes);
|
||||
}
|
||||
|
||||
return new DeserializedCollection<TCollection, TElement>(CreateDelegate(valueList), resList, CreateDelegate);
|
||||
}
|
||||
|
||||
public override void CallAfterDeserializationHook()
|
||||
{
|
||||
foreach (var val in Mappings)
|
||||
{
|
||||
val.CallAfterDeserializationHook();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Utility;
|
||||
using static Robust.Shared.Prototypes.EntityPrototype;
|
||||
|
||||
namespace Robust.Shared.Serialization.Manager.Result
|
||||
{
|
||||
public sealed class DeserializedComponentRegistry : DeserializationResult<ComponentRegistry>
|
||||
{
|
||||
public DeserializedComponentRegistry(
|
||||
ComponentRegistry value,
|
||||
IReadOnlyDictionary<DeserializationResult, DeserializationResult> mappings)
|
||||
{
|
||||
Value = value;
|
||||
Mappings = mappings;
|
||||
}
|
||||
|
||||
public override ComponentRegistry Value { get; }
|
||||
|
||||
public IReadOnlyDictionary<DeserializationResult, DeserializationResult> Mappings { get; }
|
||||
|
||||
public override object RawValue => Value;
|
||||
|
||||
public override DeserializationResult PushInheritanceFrom(DeserializationResult source)
|
||||
{
|
||||
var componentFactory = IoCManager.Resolve<IComponentFactory>();
|
||||
var sourceRes = source.Cast<DeserializedComponentRegistry>();
|
||||
var mappingDict = Mappings.ToDictionary(p => p.Key.Copy(), p => p.Value.Copy());
|
||||
|
||||
foreach (var (keyRes, valRes) in sourceRes.Mappings)
|
||||
{
|
||||
var newKeyRes = keyRes.Copy();
|
||||
var newValueRes = valRes.Copy();
|
||||
|
||||
if (mappingDict.Any(p =>
|
||||
{
|
||||
var k1 = (string) newKeyRes.RawValue!;
|
||||
var k2 = (string) p.Key.RawValue!;
|
||||
|
||||
if (k1 == k2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var registration1 = componentFactory.GetRegistration(k1!);
|
||||
var registration2 = componentFactory.GetRegistration(k2!);
|
||||
|
||||
foreach (var reference in registration1.References)
|
||||
{
|
||||
if (registration2.References.Contains(reference))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var res = newKeyRes;
|
||||
var oldEntry = mappingDict.FirstOrNull(p => Equals(p.Key.RawValue, res.RawValue));
|
||||
|
||||
if (oldEntry.HasValue)
|
||||
{
|
||||
newKeyRes = oldEntry.Value.Key.PushInheritanceFrom(newKeyRes);
|
||||
newValueRes = oldEntry.Value.Value.PushInheritanceFrom(newValueRes);
|
||||
mappingDict.Remove(oldEntry.Value.Key);
|
||||
}
|
||||
|
||||
mappingDict.Add(newKeyRes, newValueRes);
|
||||
}
|
||||
|
||||
var valueDict = new ComponentRegistry();
|
||||
foreach (var (key, val) in mappingDict)
|
||||
{
|
||||
valueDict.Add((string) key.RawValue!, (IComponent) val.RawValue!);
|
||||
}
|
||||
|
||||
return new DeserializedComponentRegistry(valueDict, mappingDict);
|
||||
}
|
||||
|
||||
public override DeserializationResult Copy()
|
||||
{
|
||||
var registry = new ComponentRegistry();
|
||||
var mappingDict = new Dictionary<DeserializationResult, DeserializationResult>();
|
||||
|
||||
foreach (var (keyRes, valRes) in Mappings)
|
||||
{
|
||||
var newKeyRes = keyRes.Copy();
|
||||
var newValueRes = valRes.Copy();
|
||||
|
||||
registry.Add((string) newKeyRes.RawValue!, (IComponent) newValueRes.RawValue!);
|
||||
mappingDict.Add(newKeyRes, newValueRes);
|
||||
}
|
||||
|
||||
return new DeserializedComponentRegistry(registry, mappingDict);
|
||||
}
|
||||
|
||||
public override void CallAfterDeserializationHook()
|
||||
{
|
||||
foreach (var (_, comp) in Mappings)
|
||||
{
|
||||
comp.CallAfterDeserializationHook();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
using System;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Robust.Shared.Serialization.Manager.Result
|
||||
{
|
||||
public sealed class DeserializedDefinition<T> : DeserializationResult<T>, IDeserializedDefinition where T : notnull, new()
|
||||
{
|
||||
public DeserializedDefinition(T value, DeserializedFieldEntry[] mapping)
|
||||
{
|
||||
Value = value;
|
||||
Mapping = mapping;
|
||||
}
|
||||
|
||||
public override T Value { get; }
|
||||
|
||||
public DeserializedFieldEntry[] Mapping { get; }
|
||||
|
||||
public override object RawValue => Value;
|
||||
|
||||
public override DeserializationResult PushInheritanceFrom(DeserializationResult source)
|
||||
{
|
||||
var dataDef = source.Cast<DeserializedDefinition<T>>();
|
||||
if (dataDef.Mapping.Length != Mapping.Length)
|
||||
throw new ArgumentException($"Mapping length mismatch in PushInheritanceFrom ({typeof(T)})");
|
||||
|
||||
var newMapping = new DeserializedFieldEntry[Mapping.Length];
|
||||
|
||||
for (var i = 0; i < dataDef.Mapping.Length; i++)
|
||||
{
|
||||
newMapping[i] = Mapping[i].PushInheritanceFrom(dataDef.Mapping[i]);
|
||||
}
|
||||
|
||||
return IoCManager.Resolve<ISerializationManager>().CreateDataDefinition<T>(newMapping, true);
|
||||
}
|
||||
|
||||
public override DeserializationResult Copy()
|
||||
{
|
||||
var newMapping = new DeserializedFieldEntry[Mapping.Length];
|
||||
|
||||
for (var i = 0; i < Mapping.Length; i++)
|
||||
{
|
||||
newMapping[i] = Mapping[i].Copy();
|
||||
}
|
||||
|
||||
return IoCManager.Resolve<ISerializationManager>().CreateDataDefinition<T>(newMapping, true);
|
||||
}
|
||||
|
||||
public override void CallAfterDeserializationHook()
|
||||
{
|
||||
foreach (var fieldEntry in Mapping)
|
||||
{
|
||||
fieldEntry.Result?.CallAfterDeserializationHook();
|
||||
}
|
||||
|
||||
if (Value is ISerializationHooks hooks)
|
||||
hooks.AfterDeserialization();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Robust.Shared.Serialization.Manager.Result
|
||||
{
|
||||
public sealed class DeserializedDictionary<TDict, TKey, TValue> :
|
||||
DeserializationResult<TDict>
|
||||
where TKey : notnull
|
||||
where TDict : IReadOnlyDictionary<TKey, TValue>
|
||||
{
|
||||
public delegate TDict Create(Dictionary<TKey, TValue> elements);
|
||||
|
||||
public DeserializedDictionary(
|
||||
TDict value,
|
||||
IReadOnlyDictionary<DeserializationResult, DeserializationResult> mappings,
|
||||
Create createDelegate)
|
||||
{
|
||||
Value = value;
|
||||
Mappings = mappings;
|
||||
CreateDelegate = createDelegate;
|
||||
}
|
||||
|
||||
public override TDict Value { get; }
|
||||
|
||||
public IReadOnlyDictionary<DeserializationResult, DeserializationResult> Mappings { get; }
|
||||
|
||||
public Create CreateDelegate { get; }
|
||||
|
||||
public override object RawValue => Value;
|
||||
|
||||
public override DeserializationResult PushInheritanceFrom(DeserializationResult source)
|
||||
{
|
||||
var sourceRes = source.Cast<DeserializedDictionary<TDict, TKey, TValue>>();
|
||||
var valueDict = new Dictionary<TKey, TValue>();
|
||||
var mappingDict = new Dictionary<DeserializationResult, DeserializationResult>();
|
||||
|
||||
foreach (var (keyRes, valRes) in sourceRes.Mappings)
|
||||
{
|
||||
var newKeyRes = keyRes.Copy();
|
||||
var newValueRes = valRes.Copy();
|
||||
|
||||
valueDict.Add((TKey)newKeyRes.RawValue!, (TValue)newValueRes.RawValue!);
|
||||
mappingDict.Add(newKeyRes, newValueRes);
|
||||
}
|
||||
|
||||
foreach (var (keyRes, valRes) in Mappings)
|
||||
{
|
||||
var newKeyRes = keyRes.Copy();
|
||||
var newValueRes = valRes.Copy();
|
||||
|
||||
valueDict.Add((TKey) newKeyRes.RawValue!, (TValue)newValueRes.RawValue!);
|
||||
mappingDict.Add(newKeyRes, newValueRes);
|
||||
}
|
||||
|
||||
return new DeserializedDictionary<TDict, TKey, TValue>(CreateDelegate(valueDict), mappingDict, CreateDelegate);
|
||||
}
|
||||
|
||||
public override DeserializationResult Copy()
|
||||
{
|
||||
var valueDict = new Dictionary<TKey, TValue>();
|
||||
var mappingDict = new Dictionary<DeserializationResult, DeserializationResult>();
|
||||
|
||||
foreach (var (keyRes, valRes) in Mappings)
|
||||
{
|
||||
var newKeyRes = keyRes.Copy();
|
||||
var newValueRes = valRes.Copy();
|
||||
|
||||
valueDict.Add((TKey)newKeyRes.RawValue!, (TValue)newValueRes.RawValue!);
|
||||
mappingDict.Add(newKeyRes, newValueRes);
|
||||
}
|
||||
|
||||
return new DeserializedDictionary<TDict, TKey, TValue>(CreateDelegate(valueDict), mappingDict, CreateDelegate);
|
||||
}
|
||||
|
||||
public override void CallAfterDeserializationHook()
|
||||
{
|
||||
foreach (var (key, val) in Mappings)
|
||||
{
|
||||
key.CallAfterDeserializationHook();
|
||||
val.CallAfterDeserializationHook();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
using Robust.Shared.Serialization.Manager.Definition;
|
||||
|
||||
namespace Robust.Shared.Serialization.Manager.Result
|
||||
{
|
||||
public sealed class DeserializedFieldEntry
|
||||
{
|
||||
public DeserializedFieldEntry(bool mapped, InheritanceBehavior inheritanceBehavior, DeserializationResult? result = null)
|
||||
{
|
||||
Mapped = mapped;
|
||||
Result = result;
|
||||
InheritanceBehavior = inheritanceBehavior;
|
||||
}
|
||||
|
||||
public bool Mapped { get; }
|
||||
|
||||
public InheritanceBehavior InheritanceBehavior { get; }
|
||||
|
||||
public DeserializationResult? Result { get; }
|
||||
|
||||
public DeserializedFieldEntry PushInheritanceFrom(DeserializedFieldEntry fieldEntry)
|
||||
{
|
||||
if (Mapped)
|
||||
{
|
||||
if (InheritanceBehavior == InheritanceBehavior.Always)
|
||||
{
|
||||
if (Result != null)
|
||||
{
|
||||
return fieldEntry.Result != null
|
||||
? new DeserializedFieldEntry(Mapped, InheritanceBehavior, Result.PushInheritanceFrom(fieldEntry.Result))
|
||||
: Copy();
|
||||
}
|
||||
else
|
||||
{
|
||||
return fieldEntry.Copy();
|
||||
}
|
||||
}
|
||||
|
||||
return Copy();
|
||||
}
|
||||
|
||||
return InheritanceBehavior == InheritanceBehavior.Never ? Copy() : fieldEntry.Copy();
|
||||
}
|
||||
|
||||
public DeserializedFieldEntry Copy()
|
||||
{
|
||||
return new(Mapped, InheritanceBehavior, Result?.Copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
namespace Robust.Shared.Serialization.Manager.Result
|
||||
{
|
||||
public sealed class DeserializedValue : DeserializationResult
|
||||
{
|
||||
public DeserializedValue(object? value)
|
||||
{
|
||||
RawValue = value;
|
||||
}
|
||||
|
||||
public override object? RawValue { get; }
|
||||
|
||||
public override DeserializationResult PushInheritanceFrom(DeserializationResult source)
|
||||
{
|
||||
return source.Copy().Cast<DeserializedValue>();
|
||||
}
|
||||
|
||||
public override DeserializationResult Copy()
|
||||
{
|
||||
return new DeserializedValue(RawValue);
|
||||
}
|
||||
|
||||
public override void CallAfterDeserializationHook()
|
||||
{
|
||||
if (RawValue is ISerializationHooks hooks)
|
||||
hooks.AfterDeserialization();
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class DeserializedValue<T> : DeserializationResult<T>
|
||||
{
|
||||
public DeserializedValue(T value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public override T Value { get; }
|
||||
|
||||
public override object? RawValue => Value;
|
||||
|
||||
public override DeserializationResult PushInheritanceFrom(DeserializationResult source)
|
||||
{
|
||||
return source.Copy().Cast<DeserializedValue<T>>();
|
||||
}
|
||||
|
||||
public override DeserializationResult Copy()
|
||||
{
|
||||
return new DeserializedValue<T>(Value);
|
||||
}
|
||||
|
||||
public override void CallAfterDeserializationHook()
|
||||
{
|
||||
if (Value is ISerializationHooks hooks)
|
||||
{
|
||||
hooks.AfterDeserialization();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace Robust.Shared.Serialization.Manager.Result
|
||||
{
|
||||
public interface IDeserializedDefinition
|
||||
{
|
||||
DeserializedFieldEntry[] Mapping { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Robust.Shared.Serialization.Manager.Result
|
||||
{
|
||||
[Virtual]
|
||||
public class InvalidDeserializedResultTypeException<TExpected> : Exception
|
||||
{
|
||||
public readonly Type ReceivedType;
|
||||
|
||||
public override string Message => $"Invalid Type {ReceivedType} received. Expected {typeof(TExpected)}";
|
||||
|
||||
public InvalidDeserializedResultTypeException(Type receivedType)
|
||||
{
|
||||
ReceivedType = receivedType;
|
||||
}
|
||||
|
||||
protected InvalidDeserializedResultTypeException([NotNull] SerializationInfo info, StreamingContext context, Type receivedType) : base(info, context)
|
||||
{
|
||||
ReceivedType = receivedType;
|
||||
}
|
||||
|
||||
public InvalidDeserializedResultTypeException([CanBeNull] string? message, Type receivedType) : base(message)
|
||||
{
|
||||
ReceivedType = receivedType;
|
||||
}
|
||||
|
||||
public InvalidDeserializedResultTypeException([CanBeNull] string? message, [CanBeNull] Exception? innerException, Type receivedType) : base(message, innerException)
|
||||
{
|
||||
ReceivedType = receivedType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using Robust.Shared.Serialization.Manager.Definition;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Robust.Shared.Serialization.Manager;
|
||||
|
||||
public partial class SerializationManager
|
||||
{
|
||||
private delegate DataNode PushCompositionDelegate(
|
||||
Type type,
|
||||
DataNode parent,
|
||||
DataNode child,
|
||||
ISerializationContext? context = null);
|
||||
|
||||
private readonly ConcurrentDictionary<(Type value, Type node), PushCompositionDelegate> _compositionPushers = new();
|
||||
|
||||
public DataNode PushComposition(Type type, DataNode[] parents, DataNode child, ISerializationContext? context = null)
|
||||
{
|
||||
DebugTools.Assert(parents.All(x => x.GetType() == child.GetType()));
|
||||
|
||||
var pusher = GetOrCreatePushCompositionDelegate(type, child);
|
||||
|
||||
var node = child;
|
||||
for (int i = 0; i < parents.Length; i++)
|
||||
{
|
||||
node = pusher(type, parents[i], node, context);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
private PushCompositionDelegate GetOrCreatePushCompositionDelegate(Type type, DataNode node)
|
||||
{
|
||||
return _compositionPushers.GetOrAdd((type, node.GetType()), static (tuple, vfArgument) =>
|
||||
{
|
||||
var (value, nodeType) = tuple;
|
||||
var (node, instance) = vfArgument;
|
||||
|
||||
var instanceConst = Expression.Constant(instance);
|
||||
var dependencyCollectionConst = Expression.Constant(instance.DependencyCollection);
|
||||
|
||||
var typeParam = Expression.Parameter(typeof(Type), "type");
|
||||
var parentParam = Expression.Parameter(typeof(DataNode), "parent");
|
||||
var childParam = Expression.Parameter(typeof(DataNode), "child");
|
||||
//todo paul serializers in the context should also override default serializers for array etc
|
||||
var contextParam = Expression.Parameter(typeof(ISerializationContext), "context");
|
||||
|
||||
Expression expression;
|
||||
|
||||
if (instance.TryGetTypeInheritanceHandler(value, nodeType, out var handler))
|
||||
{
|
||||
var readerType = typeof(ITypeInheritanceHandler<,>).MakeGenericType(value, nodeType);
|
||||
var readerConst = Expression.Constant(handler, readerType);
|
||||
|
||||
expression = Expression.Call(
|
||||
readerConst,
|
||||
"PushInheritance",
|
||||
Type.EmptyTypes,
|
||||
instanceConst,
|
||||
Expression.Convert(childParam, nodeType),
|
||||
Expression.Convert(parentParam, nodeType),
|
||||
dependencyCollectionConst,
|
||||
contextParam);
|
||||
}
|
||||
else if (nodeType == typeof(MappingDataNode) && instance.TryGetDefinition(value, out var dataDefinition))
|
||||
{
|
||||
var definitionConst = Expression.Constant(dataDefinition, typeof(DataDefinition));
|
||||
|
||||
expression = Expression.Call(
|
||||
instanceConst,
|
||||
nameof(PushInheritanceDefinition),
|
||||
Type.EmptyTypes,
|
||||
Expression.Convert(childParam, nodeType),
|
||||
Expression.Convert(parentParam, nodeType),
|
||||
definitionConst,
|
||||
contextParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
expression = node switch
|
||||
{
|
||||
SequenceDataNode => Expression.Call(
|
||||
instanceConst,
|
||||
nameof(PushInheritanceSequence),
|
||||
Type.EmptyTypes,
|
||||
Expression.Convert(childParam, nodeType),
|
||||
Expression.Convert(parentParam, nodeType)),
|
||||
MappingDataNode => Expression.Call(
|
||||
instanceConst,
|
||||
nameof(PushInheritanceMapping),
|
||||
Type.EmptyTypes,
|
||||
Expression.Convert(childParam, nodeType),
|
||||
Expression.Convert(parentParam, nodeType)),
|
||||
_ => childParam
|
||||
};
|
||||
}
|
||||
|
||||
return Expression.Lambda<PushCompositionDelegate>(
|
||||
expression,
|
||||
typeParam,
|
||||
parentParam,
|
||||
childParam,
|
||||
contextParam).Compile();
|
||||
}, (node, this));
|
||||
}
|
||||
|
||||
private SequenceDataNode PushInheritanceSequence(SequenceDataNode child, SequenceDataNode _)
|
||||
{
|
||||
return child; //todo implement different inheritancebehaviours for yamlfield
|
||||
}
|
||||
|
||||
private MappingDataNode PushInheritanceMapping(MappingDataNode child, MappingDataNode _)
|
||||
{
|
||||
return child; //todo implement different inheritancebehaviours for yamlfield
|
||||
}
|
||||
|
||||
private MappingDataNode PushInheritanceDefinition(MappingDataNode child, MappingDataNode parent,
|
||||
DataDefinition definition, ISerializationContext? context = null)
|
||||
{
|
||||
var newMapping = child.Copy();
|
||||
foreach (var field in definition.BaseFieldDefinitions)
|
||||
{
|
||||
if (field.InheritanceBehavior == InheritanceBehavior.Never) continue;
|
||||
|
||||
var key = new ValueDataNode(field.Attribute.Tag);
|
||||
if (parent.TryGetValue(key, out var parentValue))
|
||||
{
|
||||
if (newMapping.TryGetValue(key, out var childValue))
|
||||
{
|
||||
if (field.InheritanceBehavior == InheritanceBehavior.Always)
|
||||
{
|
||||
newMapping[key] = PushComposition(field.FieldType, new[] { parentValue }, childValue, context);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newMapping.Add(key, parentValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newMapping;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Interfaces;
|
||||
@@ -12,10 +11,11 @@ namespace Robust.Shared.Serialization.Manager
|
||||
{
|
||||
public partial class SerializationManager
|
||||
{
|
||||
private delegate DeserializationResult ReadSerializerDelegate(
|
||||
private delegate object? ReadSerializerDelegate(
|
||||
DataNode node,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false);
|
||||
bool skipHook = false,
|
||||
object? value = null);
|
||||
|
||||
private delegate DataNode WriteSerializerDelegate(
|
||||
object value,
|
||||
@@ -47,6 +47,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 valueParam = Expression.Parameter(typeof(object), "value");
|
||||
|
||||
var call = Expression.Call(
|
||||
instanceParam,
|
||||
@@ -54,13 +55,15 @@ namespace Robust.Shared.Serialization.Manager
|
||||
new[] {tuple.value, tuple.node, tuple.serializer},
|
||||
Expression.Convert(nodeParam, tuple.node),
|
||||
contextParam,
|
||||
skipHookParam);
|
||||
skipHookParam,
|
||||
valueParam);
|
||||
|
||||
return Expression.Lambda<ReadSerializerDelegate>(
|
||||
call,
|
||||
Expression.Convert(call, typeof(object)),
|
||||
nodeParam,
|
||||
contextParam,
|
||||
skipHookParam).Compile();
|
||||
skipHookParam,
|
||||
valueParam).Compile();
|
||||
}, this);
|
||||
}
|
||||
|
||||
@@ -126,25 +129,27 @@ namespace Robust.Shared.Serialization.Manager
|
||||
}, (common, source, target, serializer));
|
||||
}
|
||||
|
||||
private DeserializationResult ReadWithSerializerRaw(
|
||||
Type value,
|
||||
private object? ReadWithSerializerRaw(
|
||||
Type type,
|
||||
DataNode node,
|
||||
Type serializer,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
bool skipHook = false,
|
||||
object? value = null)
|
||||
{
|
||||
return GetOrCreateReadSerializerDelegate(value, node.GetType(), serializer)(node, context, skipHook);
|
||||
return GetOrCreateReadSerializerDelegate(type, node.GetType(), serializer)(node, context, skipHook, value);
|
||||
}
|
||||
|
||||
private DeserializationResult ReadWithSerializer<T, TNode, TSerializer>(
|
||||
private T ReadWithSerializer<T, TNode, TSerializer>(
|
||||
TNode node,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
bool skipHook = false,
|
||||
object? value = default)
|
||||
where TSerializer : ITypeReader<T, TNode>
|
||||
where TNode : DataNode
|
||||
{
|
||||
var serializer = (ITypeReader<T, TNode>) GetTypeSerializer(typeof(TSerializer));
|
||||
return serializer.Read(this, node, DependencyCollection, skipHook, context);
|
||||
return serializer.Read(this, node, DependencyCollection, skipHook, context, value == null ? default : (T)value);
|
||||
}
|
||||
|
||||
private DataNode WriteWithSerializerRaw(
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Robust.Shared.Serialization.Manager.Definition;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
@@ -14,14 +14,37 @@ namespace Robust.Shared.Serialization.Manager
|
||||
{
|
||||
public partial class SerializationManager
|
||||
{
|
||||
private delegate DeserializationResult ReadDelegate(
|
||||
private delegate object? ReadDelegate(
|
||||
Type type,
|
||||
DataNode node,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false);
|
||||
bool skipHook = false,
|
||||
object? value = null);
|
||||
|
||||
private readonly ConcurrentDictionary<(Type value, Type node), ReadDelegate> _readers = new();
|
||||
|
||||
public T Read<T>(DataNode node, ISerializationContext? context = null, bool skipHook = false, T? value = default) //todo paul this default should be null
|
||||
{
|
||||
return (T)Read(typeof(T), node, context, skipHook, value)!;
|
||||
}
|
||||
|
||||
public object? Read(Type type, DataNode node, ISerializationContext? context = null, bool skipHook = false, object? value = null)
|
||||
{
|
||||
var val = GetOrCreateReader(type, node)(type, node, context, skipHook, value);
|
||||
ReadNullCheck(type, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void ReadNullCheck(Type type, object? val)
|
||||
{
|
||||
if (!type.IsNullable() && val == null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{nameof(Read)}-Call returned a null value for non-nullable type {type}");
|
||||
}
|
||||
}
|
||||
|
||||
private ReadDelegate GetOrCreateReader(Type value, DataNode node)
|
||||
{
|
||||
if (node.Tag?.StartsWith("!type:") ?? false)
|
||||
@@ -42,8 +65,10 @@ namespace Robust.Shared.Serialization.Manager
|
||||
|
||||
var typeParam = Expression.Parameter(typeof(Type), "type");
|
||||
var nodeParam = Expression.Parameter(typeof(DataNode), "node");
|
||||
//todo paul serializers in the context should also override default serializers for array etc
|
||||
var contextParam = Expression.Parameter(typeof(ISerializationContext), "context");
|
||||
var skipHookParam = Expression.Parameter(typeof(bool), "skipHook");
|
||||
var valueParam = Expression.Parameter(typeof(object), "value");
|
||||
|
||||
MethodCallExpression call;
|
||||
|
||||
@@ -53,12 +78,14 @@ namespace Robust.Shared.Serialization.Manager
|
||||
|
||||
switch (node)
|
||||
{
|
||||
case ValueDataNode when nullable:
|
||||
case ValueDataNode:
|
||||
call = Expression.Call(
|
||||
instanceConst,
|
||||
nameof(ReadArrayValue),
|
||||
new[] { elementType },
|
||||
Expression.Convert(nodeParam, typeof(ValueDataNode)));
|
||||
Expression.Convert(nodeParam, typeof(ValueDataNode)),
|
||||
contextParam,
|
||||
skipHookParam);
|
||||
break;
|
||||
case SequenceDataNode seqNode:
|
||||
var isSealed = elementType.IsPrimitive || elementType.IsEnum ||
|
||||
@@ -140,7 +167,7 @@ namespace Robust.Shared.Serialization.Manager
|
||||
nameof(ReadSelfSerialize),
|
||||
new[] { value },
|
||||
Expression.Convert(nodeParam, typeof(ValueDataNode)),
|
||||
instantiatorConst)
|
||||
instantiatorConst, valueParam)
|
||||
};
|
||||
}
|
||||
else if (instance.TryGetTypeReader(value, nodeType, out var reader))
|
||||
@@ -160,12 +187,13 @@ namespace Robust.Shared.Serialization.Manager
|
||||
skipHookParam),
|
||||
ValueDataNode when nullable && !value.IsValueType => Expression.Call(
|
||||
instanceConst,
|
||||
nameof(ReadWithTypeReaderNullable),
|
||||
nameof(ReadWithTypeReaderNullableClass),
|
||||
new[] { value },
|
||||
Expression.Convert(nodeParam, typeof(ValueDataNode)),
|
||||
readerConst,
|
||||
contextParam,
|
||||
skipHookParam),
|
||||
skipHookParam,
|
||||
valueParam),
|
||||
_ => Expression.Call(
|
||||
instanceConst,
|
||||
nameof(ReadWithTypeReader),
|
||||
@@ -173,7 +201,8 @@ namespace Robust.Shared.Serialization.Manager
|
||||
Expression.Convert(nodeParam, nodeType),
|
||||
readerConst,
|
||||
contextParam,
|
||||
skipHookParam)
|
||||
skipHookParam,
|
||||
valueParam)
|
||||
};
|
||||
}
|
||||
else if (value.IsInterface || value.IsAbstract)
|
||||
@@ -203,7 +232,8 @@ namespace Robust.Shared.Serialization.Manager
|
||||
populateConst,
|
||||
hooksConst,
|
||||
contextParam,
|
||||
skipHookParam),
|
||||
skipHookParam,
|
||||
valueParam),
|
||||
ValueDataNode => Expression.Call(
|
||||
instanceConst,
|
||||
nameof(ReadGenericValue),
|
||||
@@ -214,7 +244,8 @@ namespace Robust.Shared.Serialization.Manager
|
||||
populateConst,
|
||||
hooksConst,
|
||||
contextParam,
|
||||
skipHookParam),
|
||||
skipHookParam,
|
||||
valueParam),
|
||||
MappingDataNode => Expression.Call(
|
||||
instanceConst,
|
||||
nameof(ReadGenericMapping),
|
||||
@@ -225,53 +256,54 @@ namespace Robust.Shared.Serialization.Manager
|
||||
populateConst,
|
||||
hooksConst,
|
||||
contextParam,
|
||||
skipHookParam),
|
||||
skipHookParam,
|
||||
valueParam),
|
||||
SequenceDataNode => throw new ArgumentException($"No mapping node provided for type {value} at line: {node.Start.Line}"),
|
||||
_ => throw new ArgumentException($"Unknown node type {nodeType} provided. Expected mapping node at line: {node.Start.Line}")
|
||||
};
|
||||
}
|
||||
|
||||
return Expression.Lambda<ReadDelegate>(
|
||||
call,
|
||||
Expression.Convert(call, typeof(object)),
|
||||
typeParam,
|
||||
nodeParam,
|
||||
contextParam,
|
||||
skipHookParam).Compile();
|
||||
skipHookParam,
|
||||
valueParam).Compile();
|
||||
}, (node, this));
|
||||
}
|
||||
|
||||
private DeserializationResult ReadArrayValue<T>(ValueDataNode value)
|
||||
private T[]? ReadArrayValue<T>(
|
||||
ValueDataNode value,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
{
|
||||
if (value.Value == "null")
|
||||
{
|
||||
return new DeserializedValue<T[]?>(null);
|
||||
return null;
|
||||
}
|
||||
|
||||
throw new InvalidNodeTypeException("Cannot read an array from a value data node that is not null.");
|
||||
var array = new T[1];
|
||||
array[0] = Read<T>(value, context, skipHook);
|
||||
return array;
|
||||
}
|
||||
|
||||
private DeserializationResult ReadArraySequence<T>(
|
||||
private T[] ReadArraySequence<T>(
|
||||
SequenceDataNode node,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
{
|
||||
var type = typeof(T);
|
||||
var array = new T[node.Sequence.Count];
|
||||
var results = new DeserializationResult[node.Sequence.Count];
|
||||
|
||||
for (var i = 0; i < node.Sequence.Count; i++)
|
||||
{
|
||||
var subNode = node.Sequence[i];
|
||||
var result = Read(type, subNode, context, skipHook);
|
||||
|
||||
results[i] = result;
|
||||
array[i] = (T) result.RawValue!;
|
||||
array[i] = Read<T>(node.Sequence[i], context, skipHook);
|
||||
}
|
||||
|
||||
return new DeserializedArray(array, results);
|
||||
return array;
|
||||
}
|
||||
|
||||
private DeserializationResult ReadArraySequenceSealed<T>(
|
||||
private T[] ReadArraySequenceSealed<T>(
|
||||
SequenceDataNode node,
|
||||
ReadDelegate elementReader,
|
||||
ISerializationContext? context = null,
|
||||
@@ -279,90 +311,87 @@ namespace Robust.Shared.Serialization.Manager
|
||||
{
|
||||
var type = typeof(T);
|
||||
var array = new T[node.Sequence.Count];
|
||||
var results = new DeserializationResult[node.Sequence.Count];
|
||||
|
||||
for (var i = 0; i < node.Sequence.Count; i++)
|
||||
{
|
||||
var subNode = node.Sequence[i];
|
||||
var result = elementReader(type, subNode, context, skipHook);
|
||||
|
||||
results[i] = result;
|
||||
array[i] = (T) result.RawValue!;
|
||||
ReadNullCheck(type, result);
|
||||
array[i] = (T) result!;
|
||||
}
|
||||
|
||||
return new DeserializedArray(array, results);
|
||||
return array;
|
||||
}
|
||||
|
||||
private DeserializationResult ReadEnumNullable<TEnum>(ValueDataNode node) where TEnum : struct
|
||||
private TEnum? ReadEnumNullable<TEnum>(ValueDataNode node) where TEnum : struct
|
||||
{
|
||||
if (node.Value == "null")
|
||||
{
|
||||
return new DeserializedValue<TEnum?>(null);
|
||||
return null;
|
||||
}
|
||||
|
||||
var value = Enum.Parse<TEnum>(node.Value, true);
|
||||
return new DeserializedValue<TEnum?>(value);
|
||||
return ReadEnumValue<TEnum>(node);
|
||||
}
|
||||
|
||||
private DeserializationResult ReadEnumValue<TEnum>(ValueDataNode node) where TEnum : struct
|
||||
private TEnum ReadEnumValue<TEnum>(ValueDataNode node) where TEnum : struct
|
||||
{
|
||||
var value = Enum.Parse<TEnum>(node.Value, true);
|
||||
return new DeserializedValue<TEnum>(value);
|
||||
return Enum.Parse<TEnum>(node.Value, true);
|
||||
}
|
||||
|
||||
private DeserializationResult ReadEnumSequence<TEnum>(SequenceDataNode node) where TEnum : struct
|
||||
private TEnum ReadEnumSequence<TEnum>(SequenceDataNode node) where TEnum : struct
|
||||
{
|
||||
var value = Enum.Parse<TEnum>(string.Join(", ", node.Sequence), true);
|
||||
return new DeserializedValue<TEnum>(value);
|
||||
return Enum.Parse<TEnum>(string.Join(", ", node.Sequence), true);
|
||||
}
|
||||
|
||||
private DeserializationResult ReadSelfSerialize<TValue>(
|
||||
private TValue? ReadSelfSerialize<TValue>(
|
||||
ValueDataNode node,
|
||||
InstantiationDelegate<object> instantiator)
|
||||
InstantiationDelegate<object> instantiator,
|
||||
object? rawValue = null)
|
||||
where TValue : ISelfSerialize
|
||||
{
|
||||
if (node.Value == "null")
|
||||
{
|
||||
return new DeserializedValue<TValue?>(default);
|
||||
return default; //todo paul this default should be null
|
||||
}
|
||||
|
||||
var value = (TValue) instantiator();
|
||||
var value = (TValue) (rawValue ?? instantiator());
|
||||
value.Deserialize(node.Value);
|
||||
|
||||
return new DeserializedValue<TValue?>(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
private DeserializationResult ReadSelfSerializeNullableStruct<TValue>(
|
||||
private TValue? ReadSelfSerializeNullableStruct<TValue>(
|
||||
ValueDataNode node,
|
||||
InstantiationDelegate<object> instantiator)
|
||||
where TValue : struct, ISelfSerialize
|
||||
{
|
||||
if (node.Value == "null")
|
||||
{
|
||||
return new DeserializedValue<TValue?>(null);
|
||||
return null;
|
||||
}
|
||||
|
||||
var value = (TValue) instantiator();
|
||||
value.Deserialize(node.Value);
|
||||
|
||||
return new DeserializedValue<TValue?>(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
private DeserializationResult ReadWithTypeReaderNullable<TValue>(
|
||||
private TValue? ReadWithTypeReaderNullableClass<TValue>(
|
||||
ValueDataNode node,
|
||||
ITypeReader<TValue, ValueDataNode> reader,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
bool skipHook = false,
|
||||
object? value = null)
|
||||
where TValue : class
|
||||
{
|
||||
if (node.Value == "null")
|
||||
{
|
||||
return new DeserializedValue<TValue?>(default);
|
||||
return null;
|
||||
}
|
||||
|
||||
return ReadWithTypeReader(node, reader, context, skipHook);
|
||||
return ReadWithTypeReader(node, reader, context, skipHook, value);
|
||||
}
|
||||
|
||||
private DeserializationResult ReadWithTypeReaderNullableStruct<TValue>(
|
||||
private TValue? ReadWithTypeReaderNullableStruct<TValue>(
|
||||
ValueDataNode node,
|
||||
ITypeReader<TValue, ValueDataNode> reader,
|
||||
ISerializationContext? context = null,
|
||||
@@ -371,17 +400,18 @@ namespace Robust.Shared.Serialization.Manager
|
||||
{
|
||||
if (node.Value == "null")
|
||||
{
|
||||
return new DeserializedValue<TValue?>(null);
|
||||
return null;
|
||||
}
|
||||
|
||||
return ReadWithTypeReader(node, reader, context, skipHook);
|
||||
}
|
||||
|
||||
private DeserializationResult ReadWithTypeReader<TValue, TNode>(
|
||||
private TValue ReadWithTypeReader<TValue, TNode>(
|
||||
TNode node,
|
||||
ITypeReader<TValue, TNode> reader,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
bool skipHook = false,
|
||||
object? value = null)
|
||||
where TNode : DataNode
|
||||
{
|
||||
if (context != null &&
|
||||
@@ -390,34 +420,36 @@ namespace Robust.Shared.Serialization.Manager
|
||||
reader = (ITypeReader<TValue, TNode>) readerUnCast;
|
||||
}
|
||||
|
||||
return reader.Read(this, node, DependencyCollection, skipHook, context);
|
||||
return reader.Read(this, node, DependencyCollection, skipHook, context, value == null ? default : (TValue) value);
|
||||
}
|
||||
|
||||
private DeserializationResult ReadGenericNullable<TValue>(
|
||||
private TValue? ReadGenericNullable<TValue>(
|
||||
ValueDataNode node,
|
||||
InstantiationDelegate<object> instantiator,
|
||||
DataDefinition? definition,
|
||||
bool populate,
|
||||
bool hooks,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
bool skipHook = false,
|
||||
object? value = null)
|
||||
{
|
||||
if (node.Value == "null")
|
||||
{
|
||||
return new DeserializedValue<TValue?>(default);
|
||||
return default; //todo paul this default should be null
|
||||
}
|
||||
|
||||
return ReadGenericValue<TValue?>(node, instantiator, definition, populate, hooks, context, skipHook);
|
||||
return ReadGenericValue<TValue>(node, instantiator, definition, populate, hooks, context, skipHook, value);
|
||||
}
|
||||
|
||||
private DeserializationResult ReadGenericValue<TValue>(
|
||||
private TValue ReadGenericValue<TValue>(
|
||||
ValueDataNode node,
|
||||
InstantiationDelegate<object> instantiator,
|
||||
DataDefinition? definition,
|
||||
bool populate,
|
||||
bool hooks,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
bool skipHook = false,
|
||||
object? instance = null)
|
||||
{
|
||||
var type = typeof(TValue);
|
||||
|
||||
@@ -425,7 +457,7 @@ namespace Robust.Shared.Serialization.Manager
|
||||
context.TypeReaders.TryGetValue((typeof(TValue), typeof(ValueDataNode)), out var readerUnCast))
|
||||
{
|
||||
var reader = (ITypeReader<TValue, ValueDataNode>) readerUnCast;
|
||||
return reader.Read(this, node, DependencyCollection, skipHook, context);
|
||||
return reader.Read(this, node, DependencyCollection, skipHook, context, instance == null ? default : (TValue)instance);
|
||||
}
|
||||
|
||||
if (definition == null)
|
||||
@@ -433,7 +465,7 @@ namespace Robust.Shared.Serialization.Manager
|
||||
throw new ArgumentException($"No data definition found for type {type} with node type {node.GetType()} when reading");
|
||||
}
|
||||
|
||||
var instance = instantiator();
|
||||
instance ??= instantiator();
|
||||
|
||||
if (populate)
|
||||
{
|
||||
@@ -445,36 +477,32 @@ namespace Robust.Shared.Serialization.Manager
|
||||
throw new ArgumentException($"No mapping node provided for type {type} at line: {node.Start.Line}");
|
||||
}
|
||||
|
||||
// If we get an empty ValueDataNode we just use an empty mapping
|
||||
var mapping = new MappingDataNode();
|
||||
|
||||
var result = definition.Populate(instance, mapping, this, context, skipHook);
|
||||
|
||||
if (!skipHook && hooks)
|
||||
{
|
||||
((ISerializationHooks) result.RawValue!).AfterDeserialization();
|
||||
((ISerializationHooks) instance).AfterDeserialization();
|
||||
}
|
||||
|
||||
return result;
|
||||
return (TValue) instance;
|
||||
}
|
||||
|
||||
private DeserializationResult ReadGenericMapping<TValue>(
|
||||
private TValue ReadGenericMapping<TValue>(
|
||||
MappingDataNode node,
|
||||
InstantiationDelegate<object> instantiator,
|
||||
DataDefinition? definition,
|
||||
bool populate,
|
||||
bool hooks,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
bool skipHook = false,
|
||||
object? instance = null)
|
||||
{
|
||||
var type = typeof(TValue);
|
||||
var instance = instantiator();
|
||||
instance ??= instantiator();
|
||||
|
||||
if (context != null &&
|
||||
context.TypeReaders.TryGetValue((type, typeof(MappingDataNode)), out var readerUnCast))
|
||||
{
|
||||
var reader = (ITypeReader<TValue, MappingDataNode>) readerUnCast;
|
||||
return reader.Read(this, node, DependencyCollection, skipHook, context);
|
||||
return reader.Read(this, node, DependencyCollection, skipHook, context, (TValue?) instance);
|
||||
}
|
||||
|
||||
if (definition == null)
|
||||
@@ -487,47 +515,20 @@ namespace Robust.Shared.Serialization.Manager
|
||||
((IPopulateDefaultValues) instance).PopulateDefaultValues();
|
||||
}
|
||||
|
||||
var result = definition.Populate(instance, node, this, context, skipHook);
|
||||
var result = (TValue)definition.Populate(instance, node, this, context, skipHook)!;
|
||||
|
||||
if (!skipHook && hooks)
|
||||
{
|
||||
((ISerializationHooks) result.RawValue!).AfterDeserialization();
|
||||
((ISerializationHooks) result).AfterDeserialization();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public DeserializationResult Read(Type type, DataNode node, ISerializationContext? context = null, bool skipHook = false)
|
||||
public object? ReadWithTypeSerializer(Type type, Type serializer, DataNode node, ISerializationContext? context = null,
|
||||
bool skipHook = false, object? value = null)
|
||||
{
|
||||
return GetOrCreateReader(type, node)(type, node, context, skipHook);
|
||||
}
|
||||
|
||||
public object? ReadValue(Type type, DataNode node, ISerializationContext? context = null, bool skipHook = false)
|
||||
{
|
||||
return Read(type, node, context, skipHook).RawValue;
|
||||
}
|
||||
|
||||
public T? ReadValueCast<T>(Type type, DataNode node, ISerializationContext? context = null, bool skipHook = false)
|
||||
{
|
||||
var value = Read(type, node, context, skipHook);
|
||||
|
||||
if (value.RawValue == null)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
return (T?) value.RawValue;
|
||||
}
|
||||
|
||||
public T? ReadValue<T>(DataNode node, ISerializationContext? context = null, bool skipHook = false)
|
||||
{
|
||||
return ReadValueCast<T>(typeof(T), node, context, skipHook);
|
||||
}
|
||||
|
||||
public DeserializationResult ReadWithTypeSerializer(Type value, Type serializer, DataNode node, ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
{
|
||||
return ReadWithSerializerRaw(value, node, serializer, context, skipHook);
|
||||
return ReadWithSerializerRaw(type, node, serializer, context, skipHook, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Robust.Shared.Serialization.Manager;
|
||||
|
||||
public partial class SerializationManager
|
||||
{
|
||||
private readonly Dictionary<(Type Type, Type DataNodeType), object> _typeInheritanceHandlers = new();
|
||||
|
||||
private object? GetTypeInheritanceHandler(Type value, Type node)
|
||||
{
|
||||
if (_typeInheritanceHandlers.TryGetValue((value, node), out var handler))
|
||||
{
|
||||
return handler;
|
||||
}
|
||||
|
||||
if (TryGetGenericInheritanceHandler(value, node, out handler))
|
||||
{
|
||||
return handler;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool TryGetTypeInheritanceHandler(Type value, Type node, [NotNullWhen(true)] out object? handler)
|
||||
{
|
||||
return (handler = GetTypeInheritanceHandler(value, node)) != null;
|
||||
}
|
||||
|
||||
|
||||
private bool TryGetGenericInheritanceHandler(Type type, Type node, [NotNullWhen(true)] out object? handler)
|
||||
{
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
var typeDef = type.GetGenericTypeDefinition();
|
||||
|
||||
Type? serializerTypeDef = null;
|
||||
|
||||
foreach (var (key, val) in _genericInheritanceHandlerTypes)
|
||||
{
|
||||
if (typeDef.HasSameMetadataDefinitionAs(key.Type) && key.DataNodeType.IsAssignableFrom(node))
|
||||
{
|
||||
serializerTypeDef = val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (serializerTypeDef == null)
|
||||
{
|
||||
handler = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
var serializerType = serializerTypeDef.MakeGenericType(type.GetGenericArguments());
|
||||
|
||||
handler = RegisterSerializer(serializerType) ?? throw new NullReferenceException();
|
||||
return true;
|
||||
}
|
||||
|
||||
handler = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ namespace Robust.Shared.Serialization.Manager
|
||||
public partial class SerializationManager
|
||||
{
|
||||
private readonly Dictionary<(Type Type, Type DataNodeType), Type> _genericReaderTypes = new();
|
||||
private readonly Dictionary<(Type Type, Type DataNodeType), Type> _genericInheritanceHandlerTypes = new();
|
||||
private readonly Dictionary<Type, Type> _genericWriterTypes = new();
|
||||
private readonly Dictionary<Type, Type> _genericCopierTypes = new();
|
||||
private readonly Dictionary<(Type Type, Type DataNodeType), Type> _genericValidatorTypes = new();
|
||||
@@ -44,11 +45,14 @@ namespace Robust.Shared.Serialization.Manager
|
||||
.Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ITypeCopier<>)).ToArray();
|
||||
var validatorInterfaces = type.GetInterfaces()
|
||||
.Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ITypeValidator<,>)).ToArray();
|
||||
var inheritanceHandlerInterfaces = type.GetInterfaces()
|
||||
.Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ITypeInheritanceHandler<,>)).ToArray();
|
||||
|
||||
if (readerInterfaces.Length == 0 &&
|
||||
writerInterfaces.Length == 0 &&
|
||||
copierInterfaces.Length == 0 &&
|
||||
validatorInterfaces.Length == 0)
|
||||
validatorInterfaces.Length == 0 &&
|
||||
inheritanceHandlerInterfaces.Length == 0)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"Tried to register TypeReader/Writer/Copier that had none of the interfaces inherited.");
|
||||
@@ -84,6 +88,12 @@ namespace Robust.Shared.Serialization.Manager
|
||||
Logger.ErrorS(LogCategory, $"Tried registering generic reader for type {validatorInterface.GetGenericArguments()[0]} and node {validatorInterface.GetGenericArguments()[1]} twice");
|
||||
}
|
||||
|
||||
foreach (var inheritanceHandlerInterface in inheritanceHandlerInterfaces)
|
||||
{
|
||||
if (!_genericInheritanceHandlerTypes.TryAdd((inheritanceHandlerInterface.GetGenericArguments()[0], inheritanceHandlerInterface.GetGenericArguments()[1]), type))
|
||||
Logger.ErrorS(LogCategory, $"Tried registering generic reader for type {inheritanceHandlerInterface.GetGenericArguments()[0]} and node {inheritanceHandlerInterface.GetGenericArguments()[1]} twice");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
else
|
||||
@@ -114,6 +124,12 @@ namespace Robust.Shared.Serialization.Manager
|
||||
Logger.ErrorS(LogCategory, $"Tried registering reader for type {validatorInterface.GetGenericArguments()[0]} and node {validatorInterface.GetGenericArguments()[1]} twice");
|
||||
}
|
||||
|
||||
foreach (var inheritanceHandlerInterface in inheritanceHandlerInterfaces)
|
||||
{
|
||||
if (!_typeInheritanceHandlers.TryAdd((inheritanceHandlerInterface.GetGenericArguments()[0], inheritanceHandlerInterface.GetGenericArguments()[1]), serializer))
|
||||
Logger.ErrorS(LogCategory, $"Tried registering reader for type {inheritanceHandlerInterface.GetGenericArguments()[0]} and node {inheritanceHandlerInterface.GetGenericArguments()[1]} twice");
|
||||
}
|
||||
|
||||
return serializer;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ using Robust.Shared.Log;
|
||||
using Robust.Shared.Reflection;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Definition;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
@@ -304,39 +303,6 @@ namespace Robust.Shared.Serialization.Manager
|
||||
return ValidateNodeWith(typeof(TType), typeof(TSerializer), node, context);
|
||||
}
|
||||
|
||||
public DeserializationResult CreateDataDefinition<T>(DeserializedFieldEntry[] fields, bool skipHook = false)
|
||||
where T : notnull, new()
|
||||
{
|
||||
var obj = new T();
|
||||
return PopulateDataDefinition(obj, new DeserializedDefinition<T>(obj, fields), skipHook);
|
||||
}
|
||||
|
||||
public DeserializationResult PopulateDataDefinition<T>(T obj, DeserializedDefinition<T> definition, bool skipHook = false)
|
||||
where T : notnull, new()
|
||||
{
|
||||
return PopulateDataDefinition(obj, (IDeserializedDefinition) definition, skipHook);
|
||||
}
|
||||
|
||||
public DeserializationResult PopulateDataDefinition(object obj, IDeserializedDefinition definition, bool skipHook = false)
|
||||
{
|
||||
if (!TryGetDefinition(obj.GetType(), out var dataDefinition))
|
||||
throw new ArgumentException($"Provided Type is not a data definition ({obj.GetType()})");
|
||||
|
||||
if (obj is IPopulateDefaultValues populateDefaultValues)
|
||||
{
|
||||
populateDefaultValues.PopulateDefaultValues();
|
||||
}
|
||||
|
||||
var res = dataDefinition.Populate(obj, definition.Mapping);
|
||||
|
||||
if (!skipHook && res.RawValue is ISerializationHooks serializationHooksAfter)
|
||||
{
|
||||
serializationHooksAfter.AfterDeserialization();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
internal DataDefinition? GetDefinition(Type type)
|
||||
{
|
||||
return DataDefinitions.TryGetValue(type, out var dataDefinition)
|
||||
@@ -344,7 +310,7 @@ namespace Robust.Shared.Serialization.Manager
|
||||
: null;
|
||||
}
|
||||
|
||||
private bool TryGetDefinition(Type type, [NotNullWhen(true)] out DataDefinition? dataDefinition)
|
||||
internal bool TryGetDefinition(Type type, [NotNullWhen(true)] out DataDefinition? dataDefinition)
|
||||
{
|
||||
dataDefinition = GetDefinition(type);
|
||||
return dataDefinition != null;
|
||||
|
||||
@@ -1,116 +1 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
|
||||
namespace Robust.Shared.Serialization.Manager
|
||||
{
|
||||
public static class SerializationManagerReadExtensions
|
||||
{
|
||||
public static T ReadValueOrThrow<T>(
|
||||
this ISerializationManager manager,
|
||||
DataNode node,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
{
|
||||
return manager.ReadValue<T>(node, context, skipHook) ?? throw new NullReferenceException();
|
||||
}
|
||||
|
||||
public static T ReadValueOrThrow<T>(
|
||||
this ISerializationManager manager,
|
||||
Type type,
|
||||
DataNode node,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
{
|
||||
return manager.ReadValueCast<T>(type, node, context, skipHook) ?? throw new NullReferenceException();
|
||||
}
|
||||
|
||||
public static object ReadValueOrThrow(
|
||||
this ISerializationManager manager,
|
||||
Type type,
|
||||
DataNode node,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
{
|
||||
return manager.ReadValue(type, node, context, skipHook) ?? throw new NullReferenceException();
|
||||
}
|
||||
|
||||
public static (DeserializationResult result, object? value) ReadWithValue(
|
||||
this ISerializationManager manager,
|
||||
Type type, DataNode node,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
{
|
||||
var result = manager.Read(type, node, context, skipHook);
|
||||
return (result, result.RawValue);
|
||||
}
|
||||
|
||||
public static (DeserializationResult result, T? value) ReadWithValue<T>(
|
||||
this ISerializationManager manager,
|
||||
DataNode node,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
{
|
||||
var result = manager.Read(typeof(T), node, context, skipHook);
|
||||
|
||||
if (result.RawValue == null)
|
||||
{
|
||||
return (result, default);
|
||||
}
|
||||
|
||||
return (result, (T) result.RawValue);
|
||||
}
|
||||
|
||||
public static (DeserializationResult result, T? value) ReadWithValueCast<T>(
|
||||
this ISerializationManager manager,
|
||||
Type type,
|
||||
DataNode node,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
{
|
||||
var result = manager.Read(type, node, context, skipHook);
|
||||
|
||||
if (result.RawValue == null)
|
||||
{
|
||||
return (result, default);
|
||||
}
|
||||
|
||||
return (result, (T) result.RawValue);
|
||||
}
|
||||
|
||||
|
||||
public static (T value, DeserializationResult result) ReadWithValueOrThrow<T>(
|
||||
this ISerializationManager manager,
|
||||
DataNode node,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
{
|
||||
var result = manager.Read(typeof(T), node, context, skipHook);
|
||||
|
||||
if (result.RawValue == null)
|
||||
{
|
||||
throw new NullReferenceException();
|
||||
}
|
||||
|
||||
return ((T) result.RawValue, result);
|
||||
}
|
||||
|
||||
public static (T value, DeserializationResult result) ReadWithValueOrThrow<T>(
|
||||
this ISerializationManager manager,
|
||||
Type type,
|
||||
DataNode node,
|
||||
ISerializationContext? context = null,
|
||||
bool skipHook = false)
|
||||
{
|
||||
var result = manager.Read(type, node, context, skipHook);
|
||||
|
||||
if (result.RawValue == null)
|
||||
{
|
||||
throw new NullReferenceException();
|
||||
}
|
||||
|
||||
return ((T) result.RawValue, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,14 @@ namespace Robust.Shared.Serialization.Markdown
|
||||
End = end;
|
||||
}
|
||||
|
||||
public abstract bool IsEmpty { get; }
|
||||
|
||||
public abstract DataNode Copy();
|
||||
|
||||
public abstract DataNode? Except(DataNode node);
|
||||
|
||||
public abstract DataNode PushInheritance(DataNode parent);
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj is not DataNode other)
|
||||
@@ -45,9 +49,16 @@ namespace Robust.Shared.Serialization.Markdown
|
||||
|
||||
public abstract T? Except(T node);
|
||||
|
||||
public abstract T PushInheritance(T node);
|
||||
|
||||
public override DataNode? Except(DataNode node)
|
||||
{
|
||||
return node is not T tNode ? throw new InvalidNodeTypeException() : Except(tNode);
|
||||
}
|
||||
|
||||
public override DataNode PushInheritance(DataNode parent)
|
||||
{
|
||||
return parent is not T tNode ? throw new InvalidNodeTypeException() : PushInheritance(tNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
@@ -9,7 +10,7 @@ using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.Shared.Serialization.Markdown.Mapping
|
||||
{
|
||||
public sealed class MappingDataNode : DataNode<MappingDataNode>
|
||||
public sealed class MappingDataNode : DataNode<MappingDataNode>, IDictionary<DataNode, DataNode>
|
||||
{
|
||||
// To fetch nodes by key name with YAML, we NEED a YamlScalarNode.
|
||||
// We use a thread local one to avoid allocating one every fetch, since we just replace the inner value.
|
||||
@@ -51,6 +52,7 @@ namespace Robust.Shared.Serialization.Markdown.Mapping
|
||||
set => Add(new ValueDataNode(index), value);
|
||||
}
|
||||
|
||||
//todo paul i dont think this is thread-safe
|
||||
private static ValueDataNode GetFetchNode(string key)
|
||||
{
|
||||
var node = FetchNode.Value!;
|
||||
@@ -64,16 +66,41 @@ namespace Robust.Shared.Serialization.Markdown.Mapping
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool ContainsKey(DataNode key) => _children.ContainsKey(key);
|
||||
|
||||
bool IDictionary<DataNode, DataNode>.Remove(DataNode key) => _children.Remove(key);
|
||||
|
||||
public bool TryGetValue(DataNode key, [NotNullWhen(true)] out DataNode? value) => TryGet(key, out value);
|
||||
|
||||
public DataNode this[DataNode key]
|
||||
{
|
||||
get => _children[key];
|
||||
set => _children[key] = value;
|
||||
}
|
||||
|
||||
public ICollection<DataNode> Keys => _children.Keys;
|
||||
public ICollection<DataNode> Values => _children.Values;
|
||||
|
||||
public DataNode Get(DataNode key)
|
||||
{
|
||||
return _children[key];
|
||||
}
|
||||
|
||||
public T Get<T>(DataNode key) where T : DataNode
|
||||
{
|
||||
return (T) Get(key);
|
||||
}
|
||||
|
||||
public DataNode Get(string key)
|
||||
{
|
||||
return Get(GetFetchNode(key));
|
||||
}
|
||||
|
||||
public T Get<T>(string key) where T : DataNode
|
||||
{
|
||||
return Get<T>(GetFetchNode(key));
|
||||
}
|
||||
|
||||
public bool TryGet(DataNode key, [NotNullWhen(true)] out DataNode? node)
|
||||
{
|
||||
if (_children.TryGetValue(key, out node))
|
||||
@@ -85,11 +112,24 @@ namespace Robust.Shared.Serialization.Markdown.Mapping
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryGet<T>(DataNode key, [NotNullWhen(true)] out T? node) where T : DataNode
|
||||
{
|
||||
node = null;
|
||||
if (!TryGet(key, out var rawNode)) return false;
|
||||
node = (T) rawNode;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TryGet(string key, [NotNullWhen(true)] out DataNode? node)
|
||||
{
|
||||
return TryGet(GetFetchNode(key), out node);
|
||||
}
|
||||
|
||||
public bool TryGet<T>(string key, [NotNullWhen(true)] out T? node) where T : DataNode
|
||||
{
|
||||
return TryGet(GetFetchNode(key), out node);
|
||||
}
|
||||
|
||||
public bool Has(DataNode key)
|
||||
{
|
||||
return _children.ContainsKey(key);
|
||||
@@ -100,6 +140,8 @@ namespace Robust.Shared.Serialization.Markdown.Mapping
|
||||
return Has(GetFetchNode(key));
|
||||
}
|
||||
|
||||
void IDictionary<DataNode, DataNode>.Add(DataNode key, DataNode value) => _children.Add(key, value);
|
||||
|
||||
public MappingDataNode Remove(DataNode key)
|
||||
{
|
||||
_children.Remove(key);
|
||||
@@ -146,6 +188,8 @@ namespace Robust.Shared.Serialization.Markdown.Mapping
|
||||
return newMapping;
|
||||
}
|
||||
|
||||
public override bool IsEmpty => _children.Count == 0;
|
||||
|
||||
public override MappingDataNode Copy()
|
||||
{
|
||||
var newMapping = new MappingDataNode()
|
||||
@@ -192,6 +236,21 @@ namespace Robust.Shared.Serialization.Markdown.Mapping
|
||||
return mappingNode;
|
||||
}
|
||||
|
||||
public override MappingDataNode PushInheritance(MappingDataNode node)
|
||||
{
|
||||
var newNode = Copy();
|
||||
foreach (var (key, val) in node)
|
||||
{
|
||||
if(newNode.Has(key)) continue;
|
||||
|
||||
newNode[key.Copy()] = val.Copy();
|
||||
}
|
||||
|
||||
return newNode;
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<DataNode, DataNode>> GetEnumerator() => _children.GetEnumerator();
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var code = new HashCode();
|
||||
@@ -203,5 +262,26 @@ namespace Robust.Shared.Serialization.Markdown.Mapping
|
||||
|
||||
return code.ToHashCode();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public void Add(KeyValuePair<DataNode, DataNode> item) => _children.Add(item.Key, item.Value);
|
||||
|
||||
public void Clear() => _children.Clear();
|
||||
|
||||
public bool Contains(KeyValuePair<DataNode, DataNode> item) =>
|
||||
((IDictionary<DataNode, DataNode>) _children).Contains(item);
|
||||
|
||||
public void CopyTo(KeyValuePair<DataNode, DataNode>[] array, int arrayIndex) =>
|
||||
((IDictionary<DataNode, DataNode>) _children).CopyTo(array, arrayIndex);
|
||||
|
||||
public bool Remove(KeyValuePair<DataNode, DataNode> item) =>
|
||||
((IDictionary<DataNode, DataNode>) _children).Remove(item);
|
||||
|
||||
public int Count => _children.Count;
|
||||
public bool IsReadOnly => false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.Shared.Serialization.Markdown.Sequence
|
||||
{
|
||||
public sealed class SequenceDataNode : DataNode<SequenceDataNode>
|
||||
public sealed class SequenceDataNode : DataNode<SequenceDataNode>, IList<DataNode>
|
||||
{
|
||||
private readonly List<DataNode> _nodes = new();
|
||||
|
||||
@@ -65,23 +66,44 @@ namespace Robust.Shared.Serialization.Markdown.Sequence
|
||||
|
||||
public IReadOnlyList<DataNode> Sequence => _nodes;
|
||||
|
||||
public DataNode this[int index] => _nodes[index];
|
||||
public int IndexOf(DataNode item) => _nodes.IndexOf(item);
|
||||
|
||||
public void Insert(int index, DataNode item) => _nodes.Insert(index, item);
|
||||
|
||||
public void RemoveAt(int index) => _nodes.RemoveAt(index);
|
||||
|
||||
public DataNode this[int index]
|
||||
{
|
||||
get => _nodes[index];
|
||||
set => _nodes[index] = value;
|
||||
}
|
||||
|
||||
public void Add(DataNode node)
|
||||
{
|
||||
_nodes.Add(node);
|
||||
}
|
||||
|
||||
public void Remove(DataNode node)
|
||||
public void Clear() => _nodes.Clear();
|
||||
|
||||
public bool Contains(DataNode item) => _nodes.Contains(item);
|
||||
|
||||
public void CopyTo(DataNode[] array, int arrayIndex) => _nodes.CopyTo(array, arrayIndex);
|
||||
|
||||
public bool Remove(DataNode node)
|
||||
{
|
||||
_nodes.Remove(node);
|
||||
return _nodes.Remove(node);
|
||||
}
|
||||
|
||||
public int Count => _nodes.Count;
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public T Cast<T>(int index) where T : DataNode
|
||||
{
|
||||
return (T) this[index];
|
||||
}
|
||||
|
||||
public override bool IsEmpty => _nodes.Count == 0;
|
||||
|
||||
public override SequenceDataNode Copy()
|
||||
{
|
||||
var newSequence = new SequenceDataNode()
|
||||
@@ -99,6 +121,8 @@ namespace Robust.Shared.Serialization.Markdown.Sequence
|
||||
return newSequence;
|
||||
}
|
||||
|
||||
public IEnumerator<DataNode> GetEnumerator() => _nodes.GetEnumerator();
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var code = new HashCode();
|
||||
@@ -110,6 +134,11 @@ namespace Robust.Shared.Serialization.Markdown.Sequence
|
||||
return code.ToHashCode();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public override SequenceDataNode? Except(SequenceDataNode node)
|
||||
{
|
||||
var newList = new List<DataNode>();
|
||||
@@ -130,5 +159,16 @@ namespace Robust.Shared.Serialization.Markdown.Sequence
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override SequenceDataNode PushInheritance(SequenceDataNode node)
|
||||
{
|
||||
var newNode = Copy();
|
||||
foreach (var val in node)
|
||||
{
|
||||
newNode.Add(val.Copy());
|
||||
}
|
||||
|
||||
return newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
using System.Globalization;
|
||||
using JetBrains.Annotations;
|
||||
using YamlDotNet.RepresentationModel;
|
||||
|
||||
namespace Robust.Shared.Serialization.Markdown.Value
|
||||
{
|
||||
public sealed class ValueDataNode : DataNode<ValueDataNode>
|
||||
{
|
||||
public ValueDataNode() : this(string.Empty) {}
|
||||
|
||||
public ValueDataNode(string value) : base(NodeMark.Invalid, NodeMark.Invalid)
|
||||
{
|
||||
Value = value;
|
||||
@@ -17,6 +21,8 @@ namespace Robust.Shared.Serialization.Markdown.Value
|
||||
|
||||
public string Value { get; set; }
|
||||
|
||||
public override bool IsEmpty => Value == string.Empty;
|
||||
|
||||
public override ValueDataNode Copy()
|
||||
{
|
||||
return new(Value)
|
||||
@@ -32,6 +38,11 @@ namespace Robust.Shared.Serialization.Markdown.Value
|
||||
return node.Value == Value ? null : Copy();
|
||||
}
|
||||
|
||||
public override ValueDataNode PushInheritance(ValueDataNode node)
|
||||
{
|
||||
return Copy();
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is ValueDataNode node && node.Value == Value;
|
||||
@@ -46,5 +57,23 @@ namespace Robust.Shared.Serialization.Markdown.Value
|
||||
{
|
||||
return Value;
|
||||
}
|
||||
|
||||
[Pure]
|
||||
public int AsInt()
|
||||
{
|
||||
return int.Parse(Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
[Pure]
|
||||
public float AsFloat()
|
||||
{
|
||||
return float.Parse(Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
[Pure]
|
||||
public bool AsBool()
|
||||
{
|
||||
return bool.Parse(Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -15,10 +14,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
[TypeSerializer]
|
||||
public sealed class AngleSerializer : ITypeSerializer<Angle, ValueDataNode>
|
||||
{
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
public Angle Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
ISerializationContext? context = null, Angle value = default)
|
||||
{
|
||||
var nodeContents = node.Value;
|
||||
|
||||
@@ -27,7 +26,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
CultureInfo.InvariantCulture))
|
||||
: Angle.FromDegrees(double.Parse(nodeContents, CultureInfo.InvariantCulture));
|
||||
|
||||
return new DeserializedValue<Angle>(angle);
|
||||
return angle;
|
||||
}
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node,
|
||||
|
||||
@@ -4,7 +4,6 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -15,10 +14,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
[TypeSerializer]
|
||||
public sealed class Box2Serializer : ITypeSerializer<Box2, ValueDataNode>
|
||||
{
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
public Box2 Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
ISerializationContext? context = null, Box2 value = default)
|
||||
{
|
||||
var args = node.Value.Split(',');
|
||||
|
||||
@@ -32,7 +31,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
var r = float.Parse(args[2], CultureInfo.InvariantCulture);
|
||||
var t = float.Parse(args[3], CultureInfo.InvariantCulture);
|
||||
|
||||
return new DeserializedValue<Box2>(new Box2(l, b, r, t));
|
||||
return new Box2(l, b, r, t);
|
||||
}
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node,
|
||||
|
||||
@@ -3,7 +3,6 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -14,16 +13,16 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
[TypeSerializer]
|
||||
public sealed class ColorSerializer : ITypeSerializer<Color, ValueDataNode>
|
||||
{
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
public Color Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
ISerializationContext? context = null, Color value = default)
|
||||
{
|
||||
var deserializedColor = Color.TryFromName(node.Value, out var color)
|
||||
? color :
|
||||
Color.FromHex(node.Value);
|
||||
|
||||
return new DeserializedValue<Color>(deserializedColor);
|
||||
return deserializedColor;
|
||||
}
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node,
|
||||
|
||||
@@ -7,29 +7,28 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
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.Serialization.TypeSerializers.Interfaces;
|
||||
using Robust.Shared.Utility;
|
||||
using static Robust.Shared.Prototypes.EntityPrototype;
|
||||
|
||||
namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
{
|
||||
[TypeSerializer]
|
||||
public sealed class ComponentRegistrySerializer : ITypeSerializer<ComponentRegistry, SequenceDataNode>
|
||||
public sealed class ComponentRegistrySerializer : ITypeSerializer<ComponentRegistry, SequenceDataNode>, ITypeInheritanceHandler<ComponentRegistry, SequenceDataNode>
|
||||
{
|
||||
public DeserializationResult Read(ISerializationManager serializationManager,
|
||||
public ComponentRegistry Read(ISerializationManager serializationManager,
|
||||
SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
ISerializationContext? context = null, ComponentRegistry? components = null)
|
||||
{
|
||||
var factory = dependencies.Resolve<IComponentFactory>();
|
||||
var components = new ComponentRegistry();
|
||||
var mappings = new Dictionary<DeserializationResult, DeserializationResult>();
|
||||
components ??= new ComponentRegistry();
|
||||
|
||||
foreach (var componentMapping in node.Sequence.Cast<MappingDataNode>())
|
||||
{
|
||||
@@ -59,10 +58,9 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
copy.Remove("type");
|
||||
|
||||
var type = factory.GetRegistration(compType).Type;
|
||||
var read = serializationManager.ReadWithValueOrThrow<IComponent>(type, copy, skipHook: skipHook);
|
||||
var read = (IComponent)serializationManager.Read(type, copy, skipHook: skipHook)!;
|
||||
|
||||
components[compType] = read.value;
|
||||
mappings.Add(new DeserializedValue<string>(compType), read.result);
|
||||
components[compType] = read;
|
||||
}
|
||||
|
||||
var referenceTypes = new List<Type>();
|
||||
@@ -82,7 +80,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
}
|
||||
}
|
||||
|
||||
return new DeserializedComponentRegistry(components, mappings);
|
||||
return components;
|
||||
}
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager,
|
||||
@@ -179,5 +177,46 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
public SequenceDataNode PushInheritance(ISerializationManager serializationManager, SequenceDataNode child,
|
||||
SequenceDataNode parent,
|
||||
IDependencyCollection dependencies, ISerializationContext context)
|
||||
{
|
||||
var componentFactory = dependencies.Resolve<IComponentFactory>();
|
||||
var newCompReg = child.Copy();
|
||||
var newCompRegDict = ToTypeIndexedDictionary(newCompReg, componentFactory);
|
||||
var parentDict = ToTypeIndexedDictionary(parent, componentFactory);
|
||||
|
||||
foreach (var (reg, mapping) in parentDict)
|
||||
{
|
||||
if (newCompRegDict.TryFirstOrNull(childReg => reg.References.Any(x => childReg.Key.References.Contains(x)), out var entry))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return newCompReg;
|
||||
}
|
||||
|
||||
private Dictionary<IComponentRegistration, int> ToTypeIndexedDictionary(SequenceDataNode node, IComponentFactory componentFactory)
|
||||
{
|
||||
var dict = new Dictionary<IComponentRegistration, int>();
|
||||
for (var i = 0; i < node.Count; i++)
|
||||
{
|
||||
var mapping = (MappingDataNode)node[i];
|
||||
var type = mapping.Get<ValueDataNode>("type").Value;
|
||||
var availability = componentFactory.GetComponentAvailability(type);
|
||||
if(availability == ComponentAvailability.Ignore) continue;
|
||||
dict.Add(componentFactory.GetRegistration(type), i);
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -18,11 +17,11 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom
|
||||
return Enum.TryParse(constType, node.Value, out _) ? new ValidatedValueNode(node) : new ErrorNode(node, "Failed parsing constant.", false);
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public int Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, int value = default)
|
||||
{
|
||||
var constType = serializationManager.GetConstantTypeFromTag(typeof(TTag));
|
||||
return new DeserializedValue((int) Enum.Parse(constType, node.Value));
|
||||
return (int) Enum.Parse(constType, node.Value);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, int value, bool alwaysWrite = false,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -19,11 +18,11 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom
|
||||
return Enum.TryParse(flagType, node.Value, out _) ? new ValidatedValueNode(node) : new ErrorNode(node, "Failed parsing flag.", false);
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public int Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, int value = default)
|
||||
{
|
||||
var flagType = serializationManager.GetFlagTypeFromTag(typeof(TTag));
|
||||
return new DeserializedValue((int)Enum.Parse(flagType, node.Value));
|
||||
return (int)Enum.Parse(flagType, node.Value);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, int value, bool alwaysWrite = false,
|
||||
@@ -80,8 +79,8 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom
|
||||
return new ValidatedValueNode(node);
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public int Read(ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, int value = default)
|
||||
{
|
||||
var flagType = serializationManager.GetFlagTypeFromTag(typeof(TTag));
|
||||
var flags = 0;
|
||||
@@ -92,7 +91,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom
|
||||
flags |= (int) Enum.Parse(flagType, valueDataNode.Value);
|
||||
}
|
||||
|
||||
return new DeserializedValue(flags);
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -62,25 +61,28 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Pro
|
||||
return Validate(serializationManager, node, dependencies, context);
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<Dictionary<string, TValue>, MappingDataNode>.Read(
|
||||
Dictionary<string, TValue> ITypeReader<Dictionary<string, TValue>, MappingDataNode>.Read(
|
||||
ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context)
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context,
|
||||
Dictionary<string, TValue>? value)
|
||||
{
|
||||
return _dictionarySerializer.Read(serializationManager, node, dependencies, skipHook, context);
|
||||
return _dictionarySerializer.Read(serializationManager, node, dependencies, skipHook, context, value);
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<SortedDictionary<string, TValue>, MappingDataNode>.Read(
|
||||
SortedDictionary<string, TValue> ITypeReader<SortedDictionary<string, TValue>, MappingDataNode>.Read(
|
||||
ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context)
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context,
|
||||
SortedDictionary<string, TValue>? value)
|
||||
{
|
||||
return _dictionarySerializer.Read(serializationManager, node, dependencies, skipHook, context);
|
||||
return ((ITypeReader<SortedDictionary<string, TValue>, MappingDataNode>)_dictionarySerializer).Read(serializationManager, node, dependencies, skipHook, context, value);
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<IReadOnlyDictionary<string, TValue>, MappingDataNode>.Read(
|
||||
IReadOnlyDictionary<string, TValue> ITypeReader<IReadOnlyDictionary<string, TValue>, MappingDataNode>.Read(
|
||||
ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context)
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context,
|
||||
IReadOnlyDictionary<string, TValue>? value)
|
||||
{
|
||||
return _dictionarySerializer.Read(serializationManager, node, dependencies, skipHook, context);
|
||||
return ((ITypeReader<IReadOnlyDictionary<string, TValue>, MappingDataNode>)_dictionarySerializer).Read(serializationManager, node, dependencies, skipHook, context, value);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, Dictionary<string, TValue> value,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -22,27 +22,26 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Pro
|
||||
return ValidateInternal(serializationManager, node, dependencies, context);
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public ImmutableList<string> Read(ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
ImmutableList<string>? rawValue = null)
|
||||
{
|
||||
if(rawValue != null)
|
||||
Logger.Warning($"Provided value to a Read-call for a {nameof(ImmutableList<string>)}. Ignoring...");
|
||||
|
||||
var builder = ImmutableList.CreateBuilder<string>();
|
||||
var mappings = new List<DeserializationResult>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
var result = _prototypeSerializer.Read(
|
||||
builder.Add(_prototypeSerializer.Read(
|
||||
serializationManager,
|
||||
(ValueDataNode) dataNode,
|
||||
dependencies,
|
||||
skipHook,
|
||||
context);
|
||||
|
||||
builder.Add((string) result.RawValue!);
|
||||
mappings.Add(result);
|
||||
context));
|
||||
}
|
||||
|
||||
return new DeserializedCollection<ImmutableList<string>, string>(builder.ToImmutable(), mappings,
|
||||
ImmutableList.CreateRange);
|
||||
return builder.ToImmutable();
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, ImmutableList<string> value, bool alwaysWrite = false,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -24,31 +24,29 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Pro
|
||||
return ValidateInternal(serializationManager, node, dependencies, context);
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<IReadOnlyCollection<string>, SequenceDataNode>.Read(
|
||||
IReadOnlyCollection<string> ITypeReader<IReadOnlyCollection<string>, SequenceDataNode>.Read(
|
||||
ISerializationManager serializationManager,
|
||||
SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context)
|
||||
ISerializationContext? context, IReadOnlyCollection<string>? rawValue)
|
||||
{
|
||||
if(rawValue != null)
|
||||
Logger.Warning($"Provided value to a Read-call for a {nameof(IReadOnlyCollection<string>)}. Ignoring...");
|
||||
|
||||
var list = new List<string>();
|
||||
var mappings = new List<DeserializationResult>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
var result = _prototypeSerializer.Read(
|
||||
list.Add(_prototypeSerializer.Read(
|
||||
serializationManager,
|
||||
(ValueDataNode) dataNode,
|
||||
dependencies,
|
||||
skipHook,
|
||||
context);
|
||||
|
||||
list.Add((string) result.RawValue!);
|
||||
mappings.Add(result);
|
||||
context));
|
||||
}
|
||||
|
||||
return new DeserializedCollection<List<string>, string>(list, mappings,
|
||||
elements => new List<string>(elements));
|
||||
return list;
|
||||
}
|
||||
|
||||
DataNode ITypeWriter<IReadOnlyCollection<string>>.Write(
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -35,31 +35,29 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Pro
|
||||
return new List<string>(source);
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<IReadOnlyList<string>, SequenceDataNode>.Read(
|
||||
IReadOnlyList<string> ITypeReader<IReadOnlyList<string>, SequenceDataNode>.Read(
|
||||
ISerializationManager serializationManager,
|
||||
SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context)
|
||||
ISerializationContext? context, IReadOnlyList<string>? rawValue)
|
||||
{
|
||||
if(rawValue != null)
|
||||
Logger.Warning($"Provided value to a Read-call for a {nameof(IReadOnlyList<string>)}. Ignoring...");
|
||||
|
||||
var list = new List<string>();
|
||||
var mappings = new List<DeserializationResult>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
var result = _prototypeSerializer.Read(
|
||||
list.Add(_prototypeSerializer.Read(
|
||||
serializationManager,
|
||||
(ValueDataNode) dataNode,
|
||||
dependencies,
|
||||
skipHook,
|
||||
context);
|
||||
|
||||
list.Add((string) result.RawValue!);
|
||||
mappings.Add(result);
|
||||
context));
|
||||
}
|
||||
|
||||
return new DeserializedCollection<IReadOnlyList<string>, string>(list, mappings,
|
||||
elements => new List<string>(elements));
|
||||
return list;
|
||||
}
|
||||
|
||||
ValidationNode ITypeValidator<IReadOnlyList<string>, SequenceDataNode>.Validate(
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -62,31 +61,25 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Pro
|
||||
return ValidateInternal(serializationManager, node, dependencies, context);
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<List<string>, SequenceDataNode>.Read(
|
||||
ISerializationManager serializationManager,
|
||||
List<string> ITypeReader<List<string>, SequenceDataNode>.Read(ISerializationManager serializationManager,
|
||||
SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context)
|
||||
ISerializationContext? context, List<string>? list)
|
||||
{
|
||||
var list = new List<string>();
|
||||
var mappings = new List<DeserializationResult>();
|
||||
list ??= new List<string>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
var result = _prototypeSerializer.Read(
|
||||
list.Add(_prototypeSerializer.Read(
|
||||
serializationManager,
|
||||
(ValueDataNode) dataNode,
|
||||
dependencies,
|
||||
skipHook,
|
||||
context);
|
||||
|
||||
list.Add((string) result.RawValue!);
|
||||
mappings.Add(result);
|
||||
context));
|
||||
}
|
||||
|
||||
return new DeserializedCollection<List<string>, string>(list, mappings,
|
||||
elements => new List<string>(elements));
|
||||
return list;
|
||||
}
|
||||
|
||||
DataNode ITypeWriter<List<string>>.Write(
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -38,9 +38,13 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Pro
|
||||
return new ValidatedSequenceNode(list);
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public PrototypeFlags<T> Read(ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
PrototypeFlags<T>? rawValue = null)
|
||||
{
|
||||
if(rawValue != null)
|
||||
Logger.Warning($"Provided value to a Read-call for a {nameof(PrototypeFlags<T>)}. Ignoring...");
|
||||
|
||||
var flags = new List<string>(node.Sequence.Count);
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
@@ -51,7 +55,7 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Pro
|
||||
flags.Add(value.Value);
|
||||
}
|
||||
|
||||
return new DeserializedValue<PrototypeFlags<T>>(new PrototypeFlags<T>(flags));
|
||||
return new PrototypeFlags<T>(flags);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, PrototypeFlags<T> value, bool alwaysWrite = false,
|
||||
@@ -72,10 +76,14 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Pro
|
||||
return serializationManager.ValidateNodeWith<string, PrototypeIdSerializer<T>, ValueDataNode>(node, context);
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public PrototypeFlags<T> Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
PrototypeFlags<T>? rawValue = null)
|
||||
{
|
||||
return new DeserializedValue<PrototypeFlags<T>>(new PrototypeFlags<T>(node.Value));
|
||||
if(rawValue != null)
|
||||
Logger.Warning($"Provided value to a Read-call for a {nameof(PrototypeFlags<T>)}. Ignoring...");
|
||||
|
||||
return new PrototypeFlags<T>(node.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -14,15 +13,15 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Pro
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, ISerializationContext? context = null)
|
||||
{
|
||||
return dependencies.Resolve<IPrototypeManager>().HasIndex<TPrototype>(node.Value)
|
||||
return dependencies.Resolve<IPrototypeManager>().HasMapping<TPrototype>(node.Value)
|
||||
? new ValidatedValueNode(node)
|
||||
: new ErrorNode(node, $"PrototypeID {node.Value} for type {typeof(TPrototype)} not found");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public string Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, string? value = default)
|
||||
{
|
||||
return new DeserializedValue<string>(node.Value);
|
||||
return node.Value;
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, string value, bool alwaysWrite = false,
|
||||
|
||||
@@ -2,7 +2,6 @@ using System.Collections.Generic;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -33,26 +32,23 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Pro
|
||||
return new ValidatedSequenceNode(list);
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, SequenceDataNode node, IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public HashSet<string> Read(ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null,
|
||||
HashSet<string>? set = null)
|
||||
{
|
||||
var set = new HashSet<string>();
|
||||
var mappings = new List<DeserializationResult>();
|
||||
set ??= new HashSet<string>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
var result = _prototypeSerializer.Read(
|
||||
set.Add(_prototypeSerializer.Read(
|
||||
serializationManager,
|
||||
(ValueDataNode) dataNode,
|
||||
dependencies,
|
||||
skipHook,
|
||||
context);
|
||||
|
||||
set.Add((string) result.RawValue!);
|
||||
mappings.Add(result);
|
||||
context));
|
||||
}
|
||||
|
||||
return new DeserializedCollection<HashSet<string>, string>(set, mappings,
|
||||
elements => new HashSet<string>(elements));
|
||||
return set;
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, HashSet<string> value, bool alwaysWrite = false, ISerializationContext? context = null)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -14,11 +13,11 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
[TypeSerializer]
|
||||
public sealed class FormattedMessageSerializer : ITypeSerializer<FormattedMessage, ValueDataNode>
|
||||
{
|
||||
public DeserializationResult Read(ISerializationManager serializationManager,
|
||||
public FormattedMessage Read(ISerializationManager serializationManager,
|
||||
ValueDataNode node, IDependencyCollection dependencies, bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
ISerializationContext? context = null, FormattedMessage? value = default)
|
||||
{
|
||||
return new DeserializedValue<FormattedMessage>(FormattedMessage.FromMarkup(node.Value));
|
||||
return FormattedMessage.FromMarkup(node.Value);
|
||||
}
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node,
|
||||
|
||||
@@ -3,9 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -37,22 +37,19 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
return mappingNode;
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager,
|
||||
MappingDataNode node, IDependencyCollection dependencies, bool skipHook, ISerializationContext? context)
|
||||
public Dictionary<TKey, TValue> Read(ISerializationManager serializationManager,
|
||||
MappingDataNode node, IDependencyCollection dependencies, bool skipHook, ISerializationContext? context,
|
||||
Dictionary<TKey, TValue>? dict)
|
||||
{
|
||||
var dict = new Dictionary<TKey, TValue>();
|
||||
var mappedFields = new Dictionary<DeserializationResult, DeserializationResult>();
|
||||
dict ??= new Dictionary<TKey, TValue>();
|
||||
|
||||
foreach (var (key, value) in node.Children)
|
||||
{
|
||||
var (keyVal, keyResult) = serializationManager.ReadWithValueOrThrow<TKey>(key, context, skipHook);
|
||||
var (valueResult, valueVal) = serializationManager.ReadWithValueCast<TValue>(typeof(TValue), value, context, skipHook);
|
||||
|
||||
dict.Add(keyVal, valueVal!);
|
||||
mappedFields.Add(keyResult, valueResult);
|
||||
dict.Add(serializationManager.Read<TKey>(key, context, skipHook),
|
||||
serializationManager.Read<TValue>(value, context, skipHook));
|
||||
}
|
||||
|
||||
return new DeserializedDictionary<Dictionary<TKey, TValue>, TKey, TValue>(dict, mappedFields, dictInstance => dictInstance);
|
||||
return dict;
|
||||
}
|
||||
|
||||
ValidationNode ITypeValidator<SortedDictionary<TKey, TValue>, MappingDataNode>.Validate(
|
||||
@@ -108,46 +105,39 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
return InterfaceWrite(serializationManager, value.ToDictionary(k => k.Key, v => v.Value), alwaysWrite, context);
|
||||
}
|
||||
|
||||
DeserializationResult
|
||||
IReadOnlyDictionary<TKey, TValue>
|
||||
ITypeReader<IReadOnlyDictionary<TKey, TValue>, MappingDataNode>.Read(
|
||||
ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context)
|
||||
bool skipHook, ISerializationContext? context, IReadOnlyDictionary<TKey, TValue>? rawValue)
|
||||
{
|
||||
if(rawValue != null)
|
||||
Logger.Warning($"Provided value to a Read-call for a {nameof(IReadOnlyDictionary<TKey, TValue>)}. Ignoring...");
|
||||
|
||||
var dict = new Dictionary<TKey, TValue>();
|
||||
var mappedFields = new Dictionary<DeserializationResult, DeserializationResult>();
|
||||
|
||||
foreach (var (key, value) in node.Children)
|
||||
{
|
||||
var (keyVal, keyResult) = serializationManager.ReadWithValueOrThrow<TKey>(key, context, skipHook);
|
||||
var (valueResult, valueVal) = serializationManager.ReadWithValueCast<TValue>(typeof(TValue), value, context, skipHook);
|
||||
|
||||
dict.Add(keyVal, valueVal!);
|
||||
mappedFields.Add(keyResult, valueResult);
|
||||
dict.Add(serializationManager.Read<TKey>(key, context, skipHook), serializationManager.Read<TValue>(value, context, skipHook));
|
||||
}
|
||||
|
||||
return new DeserializedDictionary<IReadOnlyDictionary<TKey, TValue>, TKey, TValue>(dict, mappedFields, dictInstance => dictInstance);
|
||||
return dict;
|
||||
}
|
||||
|
||||
DeserializationResult
|
||||
SortedDictionary<TKey, TValue>
|
||||
ITypeReader<SortedDictionary<TKey, TValue>, MappingDataNode>.Read(
|
||||
ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context)
|
||||
bool skipHook, ISerializationContext? context, SortedDictionary<TKey, TValue>? dict)
|
||||
{
|
||||
var dict = new SortedDictionary<TKey, TValue>();
|
||||
var mappedFields = new Dictionary<DeserializationResult, DeserializationResult>();
|
||||
dict ??= new SortedDictionary<TKey, TValue>();
|
||||
|
||||
foreach (var (key, value) in node.Children)
|
||||
{
|
||||
var (keyVal, keyResult) = serializationManager.ReadWithValueOrThrow<TKey>(key, context, skipHook);
|
||||
var (valueResult, valueVal) = serializationManager.ReadWithValueCast<TValue>(typeof(TValue), value, context, skipHook);
|
||||
|
||||
dict.Add(keyVal, valueVal!);
|
||||
mappedFields.Add(keyResult, valueResult);
|
||||
dict.Add(serializationManager.Read<TKey>(key, context, skipHook), serializationManager.Read<TValue>(value, context, skipHook));
|
||||
}
|
||||
|
||||
return new DeserializedDictionary<SortedDictionary<TKey, TValue>, TKey, TValue>(dict, mappedFields, dictInstance => new SortedDictionary<TKey, TValue>(dictInstance));
|
||||
return dict;
|
||||
}
|
||||
|
||||
[MustUseReturnValue]
|
||||
|
||||
@@ -4,9 +4,9 @@ using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -19,24 +19,20 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
ITypeSerializer<HashSet<T>, SequenceDataNode>,
|
||||
ITypeSerializer<ImmutableHashSet<T>, SequenceDataNode>
|
||||
{
|
||||
DeserializationResult ITypeReader<HashSet<T>, SequenceDataNode>.Read(ISerializationManager serializationManager,
|
||||
HashSet<T> ITypeReader<HashSet<T>, SequenceDataNode>.Read(ISerializationManager serializationManager,
|
||||
SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context)
|
||||
ISerializationContext? context, HashSet<T>? set)
|
||||
{
|
||||
var set = new HashSet<T>();
|
||||
var mappings = new List<DeserializationResult>();
|
||||
set ??= new HashSet<T>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
var (value, result) = serializationManager.ReadWithValueOrThrow<T>(dataNode, context, skipHook);
|
||||
|
||||
set.Add(value);
|
||||
mappings.Add(result);
|
||||
set.Add(serializationManager.Read<T>(dataNode, context, skipHook));
|
||||
}
|
||||
|
||||
return new DeserializedCollection<HashSet<T>, T>(set, mappings, elements => new HashSet<T>(elements));
|
||||
return set;
|
||||
}
|
||||
|
||||
ValidationNode ITypeValidator<ImmutableHashSet<T>, SequenceDataNode>.Validate(
|
||||
@@ -83,25 +79,23 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
return sequence;
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<ImmutableHashSet<T>, SequenceDataNode>.Read(
|
||||
ImmutableHashSet<T> ITypeReader<ImmutableHashSet<T>, SequenceDataNode>.Read(
|
||||
ISerializationManager serializationManager,
|
||||
SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context)
|
||||
ISerializationContext? context, ImmutableHashSet<T>? rawValue)
|
||||
{
|
||||
if(rawValue != null)
|
||||
Logger.Warning($"Provided value to a Read-call for a {nameof(ImmutableHashSet<T>)}. Ignoring...");
|
||||
var set = ImmutableHashSet.CreateBuilder<T>();
|
||||
var mappings = new List<DeserializationResult>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
var (value, result) = serializationManager.ReadWithValueOrThrow<T>(dataNode, context, skipHook);
|
||||
|
||||
set.Add(value);
|
||||
mappings.Add(result);
|
||||
set.Add(serializationManager.Read<T>(dataNode, context, skipHook));
|
||||
}
|
||||
|
||||
return new DeserializedCollection<ImmutableHashSet<T>, T>(set.ToImmutable(), mappings, elements => ImmutableHashSet.Create(elements.ToArray()));
|
||||
return set.ToImmutable();
|
||||
}
|
||||
|
||||
[MustUseReturnValue]
|
||||
|
||||
@@ -2,9 +2,9 @@ using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Sequence;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -59,23 +59,20 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
return WriteInternal(serializationManager, value, alwaysWrite, context);
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<List<T>, SequenceDataNode>.Read(ISerializationManager serializationManager,
|
||||
List<T> ITypeReader<List<T>, SequenceDataNode>.Read(ISerializationManager serializationManager,
|
||||
SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context)
|
||||
ISerializationContext? context, List<T>? list)
|
||||
{
|
||||
var list = new List<T>();
|
||||
var results = new List<DeserializationResult>();
|
||||
list ??= new List<T>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
var (value, result) = serializationManager.ReadWithValueOrThrow<T>(typeof(T), dataNode, context, skipHook);
|
||||
list.Add(value);
|
||||
results.Add(result);
|
||||
list.Add(serializationManager.Read<T>(dataNode, context, skipHook));
|
||||
}
|
||||
|
||||
return new DeserializedCollection<List<T>, T>(list, results, elements => elements);
|
||||
return list;
|
||||
}
|
||||
|
||||
ValidationNode ITypeValidator<ImmutableList<T>, SequenceDataNode>.Validate(
|
||||
@@ -116,59 +113,58 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
return new ValidatedSequenceNode(list);
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<IReadOnlyList<T>, SequenceDataNode>.Read(
|
||||
IReadOnlyList<T> ITypeReader<IReadOnlyList<T>, SequenceDataNode>.Read(
|
||||
ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context)
|
||||
bool skipHook, ISerializationContext? context, IReadOnlyList<T>? rawValue)
|
||||
{
|
||||
if(rawValue != null)
|
||||
Logger.Warning($"Provided value to a Read-call for a {nameof(IReadOnlySet<T>)}. Ignoring...");
|
||||
|
||||
var list = new List<T>();
|
||||
var results = new List<DeserializationResult>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
var (value, result) = serializationManager.ReadWithValueOrThrow<T>(dataNode, context, skipHook);
|
||||
|
||||
list.Add(value);
|
||||
results.Add(result);
|
||||
list.Add(serializationManager.Read<T>(dataNode, context, skipHook));
|
||||
}
|
||||
|
||||
return new DeserializedCollection<IReadOnlyList<T>, T>(list, results, l => l);
|
||||
return list;
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<IReadOnlyCollection<T>, SequenceDataNode>.Read(
|
||||
IReadOnlyCollection<T> ITypeReader<IReadOnlyCollection<T>, SequenceDataNode>.Read(
|
||||
ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context)
|
||||
bool skipHook, ISerializationContext? context, IReadOnlyCollection<T>? rawValue)
|
||||
{
|
||||
if(rawValue != null)
|
||||
Logger.Warning($"Provided value to a Read-call for a {nameof(IReadOnlyCollection<T>)}. Ignoring...");
|
||||
|
||||
var list = new List<T>();
|
||||
var results = new List<DeserializationResult>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
var (value, result) = serializationManager.ReadWithValueOrThrow<T>(dataNode, context, skipHook);
|
||||
list.Add(value);
|
||||
results.Add(result);
|
||||
list.Add(serializationManager.Read<T>(dataNode, context, skipHook));
|
||||
}
|
||||
|
||||
return new DeserializedCollection<IReadOnlyCollection<T>, T>(list, results, l => l);
|
||||
return list;
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<ImmutableList<T>, SequenceDataNode>.Read(
|
||||
ImmutableList<T> ITypeReader<ImmutableList<T>, SequenceDataNode>.Read(
|
||||
ISerializationManager serializationManager, SequenceDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context)
|
||||
bool skipHook, ISerializationContext? context, ImmutableList<T>? rawValue)
|
||||
{
|
||||
if(rawValue != null)
|
||||
Logger.Warning($"Provided value to a Read-call for a {nameof(ImmutableList<T>)}. Ignoring...");
|
||||
|
||||
var list = ImmutableList.CreateBuilder<T>();
|
||||
var results = new List<DeserializationResult>();
|
||||
|
||||
foreach (var dataNode in node.Sequence)
|
||||
{
|
||||
var (value, result) = serializationManager.ReadWithValueOrThrow<T>(dataNode, context, skipHook);
|
||||
list.Add(value);
|
||||
results.Add(result);
|
||||
list.Add(serializationManager.Read<T>(dataNode, context, skipHook));
|
||||
}
|
||||
|
||||
return new DeserializedCollection<ImmutableList<T>,T>(list.ToImmutable(), results, elements => ImmutableList.Create(elements.ToArray()));
|
||||
return list.ToImmutable();
|
||||
}
|
||||
|
||||
[MustUseReturnValue]
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Linq;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -15,19 +14,19 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Generic
|
||||
[TypeSerializer]
|
||||
public sealed class ValueTupleSerializer<T1, T2> : ITypeSerializer<ValueTuple<T1, T2>, MappingDataNode>
|
||||
{
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, MappingDataNode node,
|
||||
public (T1, T2) Read(ISerializationManager serializationManager, MappingDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
ISerializationContext? context = null, (T1, T2) val = default)
|
||||
{
|
||||
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.ReadValueOrThrow<T1>(entry.Key, context, skipHook);
|
||||
var v2 = serializationManager.ReadValueOrThrow<T2>(entry.Value, context, skipHook);
|
||||
var v1 = serializationManager.Read<T1>(entry.Key, context, skipHook, val.Item1);
|
||||
var v2 = serializationManager.Read<T2>(entry.Value, context, skipHook, val.Item2);
|
||||
|
||||
return new DeserializedValue<ValueTuple<T1, T2>>(new ValueTuple<T1, T2>(v1, v2));
|
||||
return (v1, v2);
|
||||
}
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, MappingDataNode node,
|
||||
|
||||
@@ -4,7 +4,6 @@ using Robust.Shared.IoC;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -15,13 +14,13 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
[TypeSerializer]
|
||||
public sealed class MapIdSerializer : ITypeSerializer<MapId, ValueDataNode>
|
||||
{
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
public MapId Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
ISerializationContext? context = null, MapId value = default)
|
||||
{
|
||||
var val = int.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
return new DeserializedValue<MapId>(new MapId(val));
|
||||
return new MapId(val);
|
||||
}
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -21,10 +20,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
: new ErrorNode(node, $"Failed parsing boolean value: {node.Value}");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public bool Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, bool value = default)
|
||||
{
|
||||
return new DeserializedValue<bool>(bool.Parse(node.Value));
|
||||
return bool.Parse(node.Value);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, bool value, bool alwaysWrite = false,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -21,10 +20,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
: new ErrorNode(node, $"Failed parsing byte value: {node.Value}");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public byte Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, byte value = default)
|
||||
{
|
||||
return new DeserializedValue<byte>(byte.Parse(node.Value, CultureInfo.InvariantCulture));
|
||||
return byte.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, byte value, bool alwaysWrite = false,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -21,10 +20,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
: new ErrorNode(node, $"Failed parsing char value: {node.Value}");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public char Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, char value = default)
|
||||
{
|
||||
return new DeserializedValue<char>(char.Parse(node.Value));
|
||||
return char.Parse(node.Value);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, char value, bool alwaysWrite = false,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -21,10 +20,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
: new ErrorNode(node, $"Failed parsing decimal value: {node.Value}");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public decimal Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, decimal value = default)
|
||||
{
|
||||
return new DeserializedValue<decimal>(decimal.Parse(node.Value, CultureInfo.InvariantCulture));
|
||||
return decimal.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, decimal value, bool alwaysWrite = false,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -21,10 +20,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
: new ErrorNode(node, $"Failed parsing double value: {node.Value}");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public double Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, double value = default)
|
||||
{
|
||||
return new DeserializedValue<double>(double.Parse(node.Value, CultureInfo.InvariantCulture));
|
||||
return double.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, double value, bool alwaysWrite = false,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -21,10 +20,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
: new ErrorNode(node, $"Failed parsing float value: {node.Value}");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public float Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, float value = default)
|
||||
{
|
||||
return new DeserializedValue<float>(float.Parse(node.Value, CultureInfo.InvariantCulture));
|
||||
return float.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, float value, bool alwaysWrite = false,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -21,10 +20,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
: new ErrorNode(node, $"Failed parsing int value: {node.Value}");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public int Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, int value = default)
|
||||
{
|
||||
return new DeserializedValue<int>(int.Parse(node.Value, CultureInfo.InvariantCulture));
|
||||
return int.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, int value, bool alwaysWrite = false,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -21,10 +20,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
: new ErrorNode(node, $"Failed parsing long value: {node.Value}");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public long Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, long value = default)
|
||||
{
|
||||
return new DeserializedValue<long>(long.Parse(node.Value, CultureInfo.InvariantCulture));
|
||||
return long.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, long value, bool alwaysWrite = false,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -21,10 +20,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
: new ErrorNode(node, $"Failed parsing signed byte value: {node.Value}");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public sbyte Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, sbyte value = default)
|
||||
{
|
||||
return new DeserializedValue<sbyte>(sbyte.Parse(node.Value, CultureInfo.InvariantCulture));
|
||||
return sbyte.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, sbyte value, bool alwaysWrite = false,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -21,10 +20,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
: new ErrorNode(node, $"Failed parsing short value: {node.Value}");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public short Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, short value = default)
|
||||
{
|
||||
return new DeserializedValue<short>(short.Parse(node.Value, CultureInfo.InvariantCulture));
|
||||
return short.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, short value, bool alwaysWrite = false,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -21,10 +20,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
: new ErrorNode(node, $"Failed parsing unsigned int value: {node.Value}");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public uint Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, uint value = default)
|
||||
{
|
||||
return new DeserializedValue<uint>(uint.Parse(node.Value, CultureInfo.InvariantCulture));
|
||||
return uint.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, uint value, bool alwaysWrite = false,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -21,10 +20,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
: new ErrorNode(node, $"Failed parsing unsigned long value: {node.Value}");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public ulong Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, ulong value = default)
|
||||
{
|
||||
return new DeserializedValue<ulong>(ulong.Parse(node.ToString(), CultureInfo.InvariantCulture));
|
||||
return ulong.Parse(node.ToString(), CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, ulong value, bool alwaysWrite = false,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -21,10 +20,10 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations.Primitive
|
||||
: new ErrorNode(node, $"Failed parsing unsigned short value: {node.Value}");
|
||||
}
|
||||
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null)
|
||||
public ushort Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies, bool skipHook, ISerializationContext? context = null, ushort value = default)
|
||||
{
|
||||
return new DeserializedValue<ushort>(ushort.Parse(node.Value, CultureInfo.InvariantCulture));
|
||||
return ushort.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public DataNode Write(ISerializationManager serializationManager, ushort value, bool alwaysWrite = false,
|
||||
|
||||
@@ -4,7 +4,6 @@ using JetBrains.Annotations;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -15,12 +14,12 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
[TypeSerializer]
|
||||
public sealed class RegexSerializer : ITypeSerializer<Regex, ValueDataNode>
|
||||
{
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
public Regex Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
ISerializationContext? context = null, Regex? value = default)
|
||||
{
|
||||
return new DeserializedValue<Regex>(new Regex(node.Value, RegexOptions.Compiled));
|
||||
return new Regex(node.Value, RegexOptions.Compiled);
|
||||
}
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node,
|
||||
|
||||
@@ -6,7 +6,6 @@ using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -18,12 +17,12 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
[TypeSerializer]
|
||||
public sealed class ResourcePathSerializer : ITypeSerializer<ResourcePath, ValueDataNode>
|
||||
{
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
public ResourcePath Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
ISerializationContext? context = null, ResourcePath? value = default)
|
||||
{
|
||||
return new DeserializedValue<ResourcePath>(new ResourcePath(node.Value));
|
||||
return new ResourcePath(node.Value);
|
||||
}
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node,
|
||||
|
||||
@@ -3,7 +3,6 @@ using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Mapping;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
@@ -22,29 +21,29 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
ITypeSerializer<SpriteSpecifier, MappingDataNode>,
|
||||
ITypeSerializer<SpriteSpecifier, ValueDataNode>
|
||||
{
|
||||
DeserializationResult ITypeReader<Texture, ValueDataNode>.Read(ISerializationManager serializationManager,
|
||||
Texture ITypeReader<Texture, ValueDataNode>.Read(ISerializationManager serializationManager,
|
||||
ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context)
|
||||
bool skipHook, ISerializationContext? context, Texture? value)
|
||||
{
|
||||
var path = serializationManager.ReadValueOrThrow<ResourcePath>(node, context, skipHook);
|
||||
return new DeserializedValue<Texture>(new Texture(path));
|
||||
var path = serializationManager.Read<ResourcePath>(node, context, skipHook);
|
||||
return new Texture(path);
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<SpriteSpecifier, ValueDataNode>.Read(
|
||||
ISerializationManager serializationManager, ValueDataNode node,
|
||||
SpriteSpecifier ITypeReader<SpriteSpecifier, ValueDataNode>.Read(ISerializationManager serializationManager,
|
||||
ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context)
|
||||
bool skipHook, ISerializationContext? context, SpriteSpecifier? value)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ((ITypeReader<EntityPrototype, ValueDataNode>)this).Read(serializationManager, node, dependencies, skipHook, context);
|
||||
return ((ITypeReader<EntityPrototype, ValueDataNode>)this).Read(serializationManager, node, dependencies, skipHook, context, (EntityPrototype?) value);
|
||||
}
|
||||
catch { /* ignored */ }
|
||||
|
||||
try
|
||||
{
|
||||
return ((ITypeReader<Texture, ValueDataNode>) this).Read(serializationManager, node, dependencies, skipHook, context);
|
||||
return ((ITypeReader<Texture, ValueDataNode>) this).Read(serializationManager, node, dependencies, skipHook, context, (Texture?)value);
|
||||
}
|
||||
catch { /* ignored */ }
|
||||
|
||||
@@ -52,21 +51,21 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
"SpriteSpecifier was neither a Texture nor an EntityPrototype but got provided a ValueDataNode");
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<EntityPrototype, ValueDataNode>.Read(
|
||||
ISerializationManager serializationManager, ValueDataNode node,
|
||||
EntityPrototype ITypeReader<EntityPrototype, ValueDataNode>.Read(ISerializationManager serializationManager,
|
||||
ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context)
|
||||
bool skipHook, ISerializationContext? context, EntityPrototype? value)
|
||||
{
|
||||
if (!IoCManager.Resolve<Prototypes.IPrototypeManager>().HasIndex<Prototypes.EntityPrototype>(node.Value))
|
||||
throw new InvalidMappingException("Invalid Entity Prototype");
|
||||
|
||||
return new DeserializedValue<EntityPrototype>(new EntityPrototype(node.Value));
|
||||
return new EntityPrototype(node.Value);
|
||||
}
|
||||
|
||||
DeserializationResult ITypeReader<Rsi, MappingDataNode>.Read(ISerializationManager serializationManager,
|
||||
Rsi ITypeReader<Rsi, MappingDataNode>.Read(ISerializationManager serializationManager,
|
||||
MappingDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context)
|
||||
bool skipHook, ISerializationContext? context, Rsi? value)
|
||||
{
|
||||
if (!node.TryGet("sprite", out var pathNode))
|
||||
{
|
||||
@@ -78,17 +77,17 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
throw new InvalidMappingException("Expected state-node as a valuenode");
|
||||
}
|
||||
|
||||
var path = serializationManager.ReadValueOrThrow<ResourcePath>(pathNode, context, skipHook);
|
||||
return new DeserializedValue<Rsi>(new Rsi(path, valueDataNode.Value));
|
||||
var path = serializationManager.Read<ResourcePath>(pathNode, context, skipHook);
|
||||
return new Rsi(path, valueDataNode.Value);
|
||||
}
|
||||
|
||||
|
||||
DeserializationResult ITypeReader<SpriteSpecifier, MappingDataNode>.Read(
|
||||
ISerializationManager serializationManager, MappingDataNode node,
|
||||
SpriteSpecifier ITypeReader<SpriteSpecifier, MappingDataNode>.Read(ISerializationManager serializationManager,
|
||||
MappingDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook, ISerializationContext? context)
|
||||
bool skipHook, ISerializationContext? context, SpriteSpecifier? value)
|
||||
{
|
||||
return ((ITypeReader<Rsi, MappingDataNode>) this).Read(serializationManager, node, dependencies, skipHook, context);
|
||||
return ((ITypeReader<Rsi, MappingDataNode>) this).Read(serializationManager, node, dependencies, skipHook, context, (Rsi?) value);
|
||||
}
|
||||
|
||||
ValidationNode ITypeValidator<SpriteSpecifier, ValueDataNode>.Validate(ISerializationManager serializationManager,
|
||||
|
||||
@@ -2,7 +2,6 @@ using JetBrains.Annotations;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -13,12 +12,12 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
[TypeSerializer]
|
||||
public sealed class StringSerializer : ITypeSerializer<string, ValueDataNode>
|
||||
{
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
public string Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
ISerializationContext? context = null, string? value = default)
|
||||
{
|
||||
return new DeserializedValue<string>(node.Value);
|
||||
return node.Value;
|
||||
}
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node,
|
||||
|
||||
@@ -4,7 +4,6 @@ using JetBrains.Annotations;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Serialization.Manager.Attributes;
|
||||
using Robust.Shared.Serialization.Manager.Result;
|
||||
using Robust.Shared.Serialization.Markdown;
|
||||
using Robust.Shared.Serialization.Markdown.Validation;
|
||||
using Robust.Shared.Serialization.Markdown.Value;
|
||||
@@ -15,13 +14,13 @@ namespace Robust.Shared.Serialization.TypeSerializers.Implementations
|
||||
[TypeSerializer]
|
||||
public sealed class TimespanSerializer : ITypeSerializer<TimeSpan, ValueDataNode>
|
||||
{
|
||||
public DeserializationResult Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
public TimeSpan Read(ISerializationManager serializationManager, ValueDataNode node,
|
||||
IDependencyCollection dependencies,
|
||||
bool skipHook,
|
||||
ISerializationContext? context = null)
|
||||
ISerializationContext? context = null, TimeSpan value = default)
|
||||
{
|
||||
var seconds = double.Parse(node.Value, CultureInfo.InvariantCulture);
|
||||
return new DeserializedValue<TimeSpan>(TimeSpan.FromSeconds(seconds));
|
||||
return TimeSpan.FromSeconds(seconds);
|
||||
}
|
||||
|
||||
public ValidationNode Validate(ISerializationManager serializationManager, ValueDataNode node,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user