From 131203d578fc648a08c67c8de3cff4da0d948410 Mon Sep 17 00:00:00 2001 From: Syntriax Date: Thu, 1 May 2025 17:51:21 +0300 Subject: [PATCH] refactor: Yaml serialization moved from Core to own project --- .gitmodules | 4 +- Engine.Core/Engine.Core.csproj | 4 - .../IgnoreSerializationAttribute.cs | 0 .../{ => Attributes}/SerializeAllAttribute.cs | 0 .../{ => Attributes}/SerializeAttribute.cs | 0 Engine.Core/Serialization/EntityReference.cs | 32 ------- Engine.Core/Serialization/EntityRegistry.cs | 39 +++++++++ Engine.Core/Serialization/ISerializer.cs | 12 +++ Engine.Core/Serialization/SerializedClass.cs | 10 +-- Engine.Core/Serialization/Serializer.cs | 74 ----------------- .../Abstract/IEngineTypeYamlSerializer.cs | 8 -- Engine.Core/Serialization/Utils.cs | 14 ++-- .../Abstract/IEngineTypeYamlConverter.cs | 11 +++ .../BehaviourControllerConverter.cs | 7 +- .../Converters/BehaviourConverter.cs | 7 +- .../Converters/EngineTypeYamlConverterBase.cs | 8 +- .../Converters/Primitives/AABBConverter.cs | 7 +- .../Converters/Primitives/CircleConverter.cs | 6 +- .../Converters/Primitives/Line2DConverter.cs | 6 +- .../Primitives/Line2DEquationConverter.cs | 6 +- .../Primitives/Projection1DConverter.cs | 6 +- .../Primitives/QuaternionConverter.cs | 6 +- .../Converters/Primitives/Shape2DConverter.cs | 6 +- .../Primitives/TriangleConverter.cs | 6 +- .../Primitives/Vector2DConverter.cs | 6 +- .../Primitives/Vector3DConverter.cs | 6 +- .../Converters/SerializedClassConverter.cs | 9 +- .../Converters/StateEnableConverter.cs | 7 +- .../Converters/TypeContainerConverter.cs | 5 +- .../Converters/UniverseConverter.cs | 7 +- .../Converters/UniverseObjectConverter.cs | 5 +- .../Engine.Serializers.Yaml.csproj | 15 ++++ .../Engine.Serializers.Yaml/YamlSerializer.cs | 83 +++++++++++++++++++ YamlDotNet => Engine.Serializers/YamlDotNet | 0 Engine.sln | 22 +++-- 35 files changed, 269 insertions(+), 175 deletions(-) rename Engine.Core/Serialization/{ => Attributes}/IgnoreSerializationAttribute.cs (100%) rename Engine.Core/Serialization/{ => Attributes}/SerializeAllAttribute.cs (100%) rename Engine.Core/Serialization/{ => Attributes}/SerializeAttribute.cs (100%) create mode 100644 Engine.Core/Serialization/EntityRegistry.cs create mode 100644 Engine.Core/Serialization/ISerializer.cs delete mode 100644 Engine.Core/Serialization/Serializer.cs delete mode 100644 Engine.Core/Serialization/Serializers/Abstract/IEngineTypeYamlSerializer.cs create mode 100644 Engine.Serializers/Engine.Serializers.Yaml/Converters/Abstract/IEngineTypeYamlConverter.cs rename Engine.Core/Serialization/Serializers/BehaviourControllerSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourControllerConverter.cs (92%) rename Engine.Core/Serialization/Serializers/BehaviourSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourConverter.cs (91%) rename Engine.Core/Serialization/Serializers/EngineTypeYamlSerializerBase.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/EngineTypeYamlConverterBase.cs (80%) rename Engine.Core/Serialization/Serializers/Primitives/AABBSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/AABBConverter.cs (91%) rename Engine.Core/Serialization/Serializers/Primitives/CircleSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/CircleConverter.cs (90%) rename Engine.Core/Serialization/Serializers/Primitives/Line2DSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DConverter.cs (90%) rename Engine.Core/Serialization/Serializers/Primitives/Line2DEquationSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DEquationConverter.cs (90%) rename Engine.Core/Serialization/Serializers/Primitives/Projection1DSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Projection1DConverter.cs (89%) rename Engine.Core/Serialization/Serializers/Primitives/QuaternionSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/QuaternionConverter.cs (85%) rename Engine.Core/Serialization/Serializers/Primitives/Shape2DSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Shape2DConverter.cs (90%) rename Engine.Core/Serialization/Serializers/Primitives/TriangleSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/TriangleConverter.cs (92%) rename Engine.Core/Serialization/Serializers/Primitives/Vector2DSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector2DConverter.cs (84%) rename Engine.Core/Serialization/Serializers/Primitives/Vector3DSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector3DConverter.cs (85%) rename Engine.Core/Serialization/Serializers/SerializedClassSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/SerializedClassConverter.cs (84%) rename Engine.Core/Serialization/Serializers/StateEnableSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/StateEnableConverter.cs (87%) rename Engine.Core/Serialization/Serializers/TypeContainerSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/TypeContainerConverter.cs (89%) rename Engine.Core/Serialization/Serializers/UniverseSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseConverter.cs (93%) rename Engine.Core/Serialization/Serializers/UniverseObjectSerializer.cs => Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseObjectConverter.cs (96%) create mode 100644 Engine.Serializers/Engine.Serializers.Yaml/Engine.Serializers.Yaml.csproj create mode 100644 Engine.Serializers/Engine.Serializers.Yaml/YamlSerializer.cs rename YamlDotNet => Engine.Serializers/YamlDotNet (100%) diff --git a/.gitmodules b/.gitmodules index 3a4005d..5b155fd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "YamlDotNet"] - path = YamlDotNet +[submodule "Engine.Serializers/YamlDotNet"] + path = Engine.Serializers/YamlDotNet url = git@github.com:Syntriax/YamlDotNet.git diff --git a/Engine.Core/Engine.Core.csproj b/Engine.Core/Engine.Core.csproj index 497688f..402f9f6 100644 --- a/Engine.Core/Engine.Core.csproj +++ b/Engine.Core/Engine.Core.csproj @@ -7,8 +7,4 @@ Syntriax.Engine.Core - - - - diff --git a/Engine.Core/Serialization/IgnoreSerializationAttribute.cs b/Engine.Core/Serialization/Attributes/IgnoreSerializationAttribute.cs similarity index 100% rename from Engine.Core/Serialization/IgnoreSerializationAttribute.cs rename to Engine.Core/Serialization/Attributes/IgnoreSerializationAttribute.cs diff --git a/Engine.Core/Serialization/SerializeAllAttribute.cs b/Engine.Core/Serialization/Attributes/SerializeAllAttribute.cs similarity index 100% rename from Engine.Core/Serialization/SerializeAllAttribute.cs rename to Engine.Core/Serialization/Attributes/SerializeAllAttribute.cs diff --git a/Engine.Core/Serialization/SerializeAttribute.cs b/Engine.Core/Serialization/Attributes/SerializeAttribute.cs similarity index 100% rename from Engine.Core/Serialization/SerializeAttribute.cs rename to Engine.Core/Serialization/Attributes/SerializeAttribute.cs diff --git a/Engine.Core/Serialization/EntityReference.cs b/Engine.Core/Serialization/EntityReference.cs index 9c92ce4..8ad0bd6 100644 --- a/Engine.Core/Serialization/EntityReference.cs +++ b/Engine.Core/Serialization/EntityReference.cs @@ -1,35 +1,3 @@ -using System; -using System.Collections.Generic; - namespace Syntriax.Engine.Core.Serialization; public record class EntityReference(string? Id = null); - -public class EntityRegistry -{ - public event EntityRegisteredEventHandler? OnEntityRegistered = null!; - - private readonly Dictionary?> assignCallbacks = []; - private readonly Dictionary registeredEntities = []; - public IReadOnlyDictionary RegisteredEntities => registeredEntities; - - public void Add(IEntity entity) - { - if (registeredEntities.TryAdd(entity.Id, entity)) - OnEntityRegistered?.InvokeSafe(this, entity); - } - - public void QueueAssign(string id, Action setMethod) - { - assignCallbacks.TryAdd(id, null); - assignCallbacks[id] = assignCallbacks[id] + setMethod; - } - - public void AssignAll() - { - foreach ((string id, Action? action) in assignCallbacks) - action?.InvokeSafe(registeredEntities[id]); - } - - public delegate void EntityRegisteredEventHandler(EntityRegistry sender, IEntity entity); -} diff --git a/Engine.Core/Serialization/EntityRegistry.cs b/Engine.Core/Serialization/EntityRegistry.cs new file mode 100644 index 0000000..fa489b2 --- /dev/null +++ b/Engine.Core/Serialization/EntityRegistry.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; + +namespace Syntriax.Engine.Core.Serialization; + +public class EntityRegistry +{ + public event EntityRegisteredEventHandler? OnEntityRegistered = null!; + + private readonly Dictionary?> assignCallbacks = []; + private readonly Dictionary registeredEntities = []; + public IReadOnlyDictionary RegisteredEntities => registeredEntities; + + public void Add(IEntity entity) + { + if (registeredEntities.TryAdd(entity.Id, entity)) + OnEntityRegistered?.InvokeSafe(this, entity); + } + + public void QueueAssign(string id, Action setMethod) + { + assignCallbacks.TryAdd(id, null); + assignCallbacks[id] = assignCallbacks[id] + setMethod; + } + + public void AssignAll() + { + foreach ((string id, Action? action) in assignCallbacks) + action?.InvokeSafe(registeredEntities[id]); + } + + public void Reset() + { + assignCallbacks.Clear(); + registeredEntities.Clear(); + } + + public delegate void EntityRegisteredEventHandler(EntityRegistry sender, IEntity entity); +} diff --git a/Engine.Core/Serialization/ISerializer.cs b/Engine.Core/Serialization/ISerializer.cs new file mode 100644 index 0000000..18b9959 --- /dev/null +++ b/Engine.Core/Serialization/ISerializer.cs @@ -0,0 +1,12 @@ +using System; + +namespace Syntriax.Engine.Core.Serialization; + +public interface ISerializer +{ + object Deserialize(string configuration); + object Deserialize(string configuration, Type type); + T Deserialize(string configuration); + + string Serialize(object instance); +} diff --git a/Engine.Core/Serialization/SerializedClass.cs b/Engine.Core/Serialization/SerializedClass.cs index 6d5bd1e..992f772 100644 --- a/Engine.Core/Serialization/SerializedClass.cs +++ b/Engine.Core/Serialization/SerializedClass.cs @@ -26,7 +26,7 @@ public class SerializedClass Type type = @class.GetType(); Type = type.FullName ?? type.Name; - bool isFullySerializable = type.HasAttribute(); + bool shouldSerializeAll = type.HasAttribute(); Public.Clear(); Private.Clear(); @@ -39,7 +39,7 @@ public class SerializedClass if (privatePropertyInfo.SetMethod is null) continue; - if (!isFullySerializable && !privatePropertyInfo.HasAttribute()) + if (!shouldSerializeAll && !privatePropertyInfo.HasAttribute()) continue; object? value = privatePropertyInfo.GetValue(@class); @@ -57,7 +57,7 @@ public class SerializedClass if (publicPropertyInfo.SetMethod is null) continue; - if (!isFullySerializable && !publicPropertyInfo.HasAttribute()) + if (!shouldSerializeAll && !publicPropertyInfo.HasAttribute()) continue; object? value = publicPropertyInfo.GetValue(@class); @@ -72,7 +72,7 @@ public class SerializedClass if (privateFieldInfo.HasAttribute()) continue; - if (!isFullySerializable && !privateFieldInfo.HasAttribute()) + if (!shouldSerializeAll && !privateFieldInfo.HasAttribute()) continue; object? value = privateFieldInfo.GetValue(@class); @@ -87,7 +87,7 @@ public class SerializedClass if (publicFieldInfo.HasAttribute()) continue; - if (!isFullySerializable && !publicFieldInfo.HasAttribute()) + if (!shouldSerializeAll && !publicFieldInfo.HasAttribute()) continue; object? value = publicFieldInfo.GetValue(@class); diff --git a/Engine.Core/Serialization/Serializer.cs b/Engine.Core/Serialization/Serializer.cs deleted file mode 100644 index bdd2f73..0000000 --- a/Engine.Core/Serialization/Serializer.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; - -using YamlDotNet.Serialization; -using YamlDotNet.Serialization.NamingConventions; - -namespace Syntriax.Engine.Core.Serialization; - -public static class Serializer -{ - private static readonly ISerializer serializer = GetSerializer(); - private static ISerializer GetSerializer() - { - SerializerBuilder serializerBuilder = new SerializerBuilder() - .WithNamingConvention(PascalCaseNamingConvention.Instance) - .DisableAliases(); - - foreach (IEngineTypeYamlSerializer typeConverter in GetEngineYamlTypeConverters()) - serializerBuilder = serializerBuilder.WithTypeConverter(typeConverter); - - return serializerBuilder.Build(); - } - - private static IDeserializer GetDeserializer(EntityRegistry entityRegistry) - { - DeserializerBuilder serializerBuilder = new DeserializerBuilder() - .WithNamingConvention(PascalCaseNamingConvention.Instance); - - foreach (IEngineTypeYamlSerializer typeConverter in GetEngineYamlTypeConverters()) - { - typeConverter.EntityRegistry = entityRegistry; - serializerBuilder = serializerBuilder.WithTypeConverter(typeConverter); - } - - return serializerBuilder.Build(); - } - - private static IEnumerable GetEngineYamlTypeConverters() - { - foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(IEngineTypeYamlSerializer).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract)) - yield return (Activator.CreateInstance(type) as IEngineTypeYamlSerializer)!; - } - - public static string Serialize(object instance) - { - return serializer.Serialize(instance); - } - - public static object Deserialize(string yaml) - { - EntityRegistry entityRegistry = new(); - object result = GetDeserializer(entityRegistry).Deserialize(yaml)!; - entityRegistry.AssignAll(); - return result; - } - - public static object Deserialize(string yaml, Type type) - { - EntityRegistry entityRegistry = new(); - object result = GetDeserializer(entityRegistry).Deserialize(yaml, type)!; - entityRegistry.AssignAll(); - return result; - } - - public static T Deserialize(string yaml) - { - EntityRegistry entityRegistry = new(); - T result = GetDeserializer(entityRegistry).Deserialize(yaml); - entityRegistry.AssignAll(); - return result; - } -} diff --git a/Engine.Core/Serialization/Serializers/Abstract/IEngineTypeYamlSerializer.cs b/Engine.Core/Serialization/Serializers/Abstract/IEngineTypeYamlSerializer.cs deleted file mode 100644 index 8b60078..0000000 --- a/Engine.Core/Serialization/Serializers/Abstract/IEngineTypeYamlSerializer.cs +++ /dev/null @@ -1,8 +0,0 @@ -using YamlDotNet.Serialization; - -namespace Syntriax.Engine.Core.Serialization; - -public interface IEngineTypeYamlSerializer : IYamlTypeConverter -{ - EntityRegistry EntityRegistry { get; set; } -} diff --git a/Engine.Core/Serialization/Utils.cs b/Engine.Core/Serialization/Utils.cs index 5f9aa4f..6bf6eb1 100644 --- a/Engine.Core/Serialization/Utils.cs +++ b/Engine.Core/Serialization/Utils.cs @@ -5,12 +5,12 @@ using System.Reflection; namespace Syntriax.Engine.Core.Serialization; -internal static class Utils +public static class Utils { - internal static bool HasAttribute(this MemberInfo memberInfo) where T : Attribute => memberInfo.GetCustomAttribute() is not null; - internal static bool IsEnumerable(this Type type) => typeof(System.Collections.IEnumerable).IsAssignableFrom(type) && type != typeof(string); + public static bool HasAttribute(this MemberInfo memberInfo) where T : Attribute => memberInfo.GetCustomAttribute() is not null; + public static bool IsEnumerable(this Type type) => typeof(System.Collections.IEnumerable).IsAssignableFrom(type) && type != typeof(string); - internal static TypeData GetTypeData(this Type objectType) + public static TypeData GetTypeData(this Type objectType) { List eventInfos = objectType.GetEvents(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) .OrderBy(ei => ei.Name) @@ -26,7 +26,7 @@ internal static class Utils return new TypeData(fieldInfos, propertyInfos); } - internal static List GetFieldInfosIncludingBaseClasses(Type type, BindingFlags bindingFlags) + public static List GetFieldInfosIncludingBaseClasses(Type type, BindingFlags bindingFlags) { if (type.BaseType is null) return [.. type.GetFields(bindingFlags)]; @@ -44,7 +44,7 @@ internal static class Utils return [.. fieldInfoList.OrderBy(fi => fi.Name)]; } - internal static List GetPropertyInfosIncludingBaseClasses(Type type, BindingFlags bindingFlags) + public static List GetPropertyInfosIncludingBaseClasses(Type type, BindingFlags bindingFlags) { if (type.BaseType is null) return [.. type.GetProperties(bindingFlags)]; @@ -75,7 +75,7 @@ internal static class Utils } } -internal record struct TypeData(IEnumerable Fields, IEnumerable Properties) +public record struct TypeData(IEnumerable Fields, IEnumerable Properties) { public static implicit operator (IEnumerable fields, IEnumerable properties)(TypeData value) => (value.Fields, value.Properties); public static implicit operator TypeData((IEnumerable fields, IEnumerable properties) value) => new(value.fields, value.properties); diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Converters/Abstract/IEngineTypeYamlConverter.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Abstract/IEngineTypeYamlConverter.cs new file mode 100644 index 0000000..110cc90 --- /dev/null +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Abstract/IEngineTypeYamlConverter.cs @@ -0,0 +1,11 @@ +using Syntriax.Engine.Core.Serialization; + +using YamlDotNet.Serialization; + +namespace Syntriax.Engine.Serializers.Yaml; + +public interface IEngineTypeYamlConverter : IYamlTypeConverter +{ + YamlSerializer Serializer { get; set; } + EntityRegistry EntityRegistry { get; set; } +} diff --git a/Engine.Core/Serialization/Serializers/BehaviourControllerSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourControllerConverter.cs similarity index 92% rename from Engine.Core/Serialization/Serializers/BehaviourControllerSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourControllerConverter.cs index 5650c2f..3ebc134 100644 --- a/Engine.Core/Serialization/Serializers/BehaviourControllerSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourControllerConverter.cs @@ -2,13 +2,16 @@ using System; using System.Collections.Generic; using System.Linq; +using Syntriax.Engine.Core; +using Syntriax.Engine.Core.Serialization; + using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class BehaviourControllerSerializer : EngineTypeYamlSerializerBase +public class BehaviourControllerConverter : EngineTypeYamlSerializerBase { private const string BEHAVIOURS_SCALAR_NAME = "Behaviours"; diff --git a/Engine.Core/Serialization/Serializers/BehaviourSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourConverter.cs similarity index 91% rename from Engine.Core/Serialization/Serializers/BehaviourSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourConverter.cs index 737eac0..9a9c9b4 100644 --- a/Engine.Core/Serialization/Serializers/BehaviourSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/BehaviourConverter.cs @@ -1,12 +1,15 @@ using System; +using Syntriax.Engine.Core; +using Syntriax.Engine.Core.Serialization; + using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class BehaviourSerializer : EngineTypeYamlSerializerBase +public class BehaviourConverter : EngineTypeYamlSerializerBase { public override IBehaviour? Read(IParser parser, Type type, ObjectDeserializer rootDeserializer) { diff --git a/Engine.Core/Serialization/Serializers/EngineTypeYamlSerializerBase.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/EngineTypeYamlConverterBase.cs similarity index 80% rename from Engine.Core/Serialization/Serializers/EngineTypeYamlSerializerBase.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/EngineTypeYamlConverterBase.cs index 76d2ffd..2b2573f 100644 --- a/Engine.Core/Serialization/Serializers/EngineTypeYamlSerializerBase.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/EngineTypeYamlConverterBase.cs @@ -1,15 +1,19 @@ using System; +using Syntriax.Engine.Core; +using Syntriax.Engine.Core.Serialization; + using YamlDotNet.Core; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public abstract class EngineTypeYamlSerializerBase : IEngineTypeYamlSerializer +public abstract class EngineTypeYamlSerializerBase : IEngineTypeYamlConverter { protected const string SERIALIZED_SCALAR_NAME = "Properties"; public EntityRegistry EntityRegistry { get; set; } = null!; + public YamlSerializer Serializer { get; set; } = null!; public bool Accepts(Type type) => typeof(T).IsAssignableFrom(type); diff --git a/Engine.Core/Serialization/Serializers/Primitives/AABBSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/AABBConverter.cs similarity index 91% rename from Engine.Core/Serialization/Serializers/Primitives/AABBSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/AABBConverter.cs index 6c2dce6..bfc0001 100644 --- a/Engine.Core/Serialization/Serializers/Primitives/AABBSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/AABBConverter.cs @@ -1,12 +1,14 @@ using System; +using Syntriax.Engine.Core; + using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class AABBSerializer : EngineTypeYamlSerializerBase +public class AABBConverter : EngineTypeYamlSerializerBase { public override AABB Read(IParser parser, Type type, ObjectDeserializer rootDeserializer) { @@ -36,5 +38,4 @@ public class AABBSerializer : EngineTypeYamlSerializerBase serializer(aabb.UpperBoundary, typeof(Vector2D)); emitter.Emit(new MappingEnd()); } - } diff --git a/Engine.Core/Serialization/Serializers/Primitives/CircleSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/CircleConverter.cs similarity index 90% rename from Engine.Core/Serialization/Serializers/Primitives/CircleSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/CircleConverter.cs index b1af49d..32ad922 100644 --- a/Engine.Core/Serialization/Serializers/Primitives/CircleSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/CircleConverter.cs @@ -1,12 +1,14 @@ using System; +using Syntriax.Engine.Core; + using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class CircleSerializer : EngineTypeYamlSerializerBase +public class CircleConverter : EngineTypeYamlSerializerBase { public override Circle Read(IParser parser, Type type, ObjectDeserializer rootDeserializer) { diff --git a/Engine.Core/Serialization/Serializers/Primitives/Line2DSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DConverter.cs similarity index 90% rename from Engine.Core/Serialization/Serializers/Primitives/Line2DSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DConverter.cs index d4ddd92..85551c0 100644 --- a/Engine.Core/Serialization/Serializers/Primitives/Line2DSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DConverter.cs @@ -1,12 +1,14 @@ using System; +using Syntriax.Engine.Core; + using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class Line2DSerializer : EngineTypeYamlSerializerBase +public class Line2DConverter : EngineTypeYamlSerializerBase { public override Line2D Read(IParser parser, Type type, ObjectDeserializer rootDeserializer) { diff --git a/Engine.Core/Serialization/Serializers/Primitives/Line2DEquationSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DEquationConverter.cs similarity index 90% rename from Engine.Core/Serialization/Serializers/Primitives/Line2DEquationSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DEquationConverter.cs index 0a00c41..da70ea2 100644 --- a/Engine.Core/Serialization/Serializers/Primitives/Line2DEquationSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Line2DEquationConverter.cs @@ -1,12 +1,14 @@ using System; +using Syntriax.Engine.Core; + using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class Line2DEquationSerializer : EngineTypeYamlSerializerBase +public class Line2DEquationConverter : EngineTypeYamlSerializerBase { public override Line2DEquation Read(IParser parser, Type type, ObjectDeserializer rootDeserializer) { diff --git a/Engine.Core/Serialization/Serializers/Primitives/Projection1DSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Projection1DConverter.cs similarity index 89% rename from Engine.Core/Serialization/Serializers/Primitives/Projection1DSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Projection1DConverter.cs index c9ac8ef..9bad9bf 100644 --- a/Engine.Core/Serialization/Serializers/Primitives/Projection1DSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Projection1DConverter.cs @@ -1,12 +1,14 @@ using System; +using Syntriax.Engine.Core; + using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class Projection1DSerializer : EngineTypeYamlSerializerBase +public class Projection1DConverter : EngineTypeYamlSerializerBase { public override Projection1D Read(IParser parser, Type type, ObjectDeserializer rootDeserializer) { diff --git a/Engine.Core/Serialization/Serializers/Primitives/QuaternionSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/QuaternionConverter.cs similarity index 85% rename from Engine.Core/Serialization/Serializers/Primitives/QuaternionSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/QuaternionConverter.cs index 02b0da4..66e2a0d 100644 --- a/Engine.Core/Serialization/Serializers/Primitives/QuaternionSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/QuaternionConverter.cs @@ -1,12 +1,14 @@ using System; +using Syntriax.Engine.Core; + using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class QuaternionSerializer : EngineTypeYamlSerializerBase +public class QuaternionConverter : EngineTypeYamlSerializerBase { private static readonly int SUBSTRING_START_LENGTH = nameof(Quaternion).Length + 1; diff --git a/Engine.Core/Serialization/Serializers/Primitives/Shape2DSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Shape2DConverter.cs similarity index 90% rename from Engine.Core/Serialization/Serializers/Primitives/Shape2DSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Shape2DConverter.cs index 6b0dea3..239546e 100644 --- a/Engine.Core/Serialization/Serializers/Primitives/Shape2DSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Shape2DConverter.cs @@ -1,13 +1,15 @@ using System; using System.Collections.Generic; +using Syntriax.Engine.Core; + using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class Shape2DSerializer : EngineTypeYamlSerializerBase +public class Shape2DConverter : EngineTypeYamlSerializerBase { public override Shape2D Read(IParser parser, Type type, ObjectDeserializer rootDeserializer) { diff --git a/Engine.Core/Serialization/Serializers/Primitives/TriangleSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/TriangleConverter.cs similarity index 92% rename from Engine.Core/Serialization/Serializers/Primitives/TriangleSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/TriangleConverter.cs index 86a2901..d98efbb 100644 --- a/Engine.Core/Serialization/Serializers/Primitives/TriangleSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/TriangleConverter.cs @@ -1,12 +1,14 @@ using System; +using Syntriax.Engine.Core; + using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class TriangleSerializer : EngineTypeYamlSerializerBase +public class TriangleConverter : EngineTypeYamlSerializerBase { public override Triangle Read(IParser parser, Type type, ObjectDeserializer rootDeserializer) { diff --git a/Engine.Core/Serialization/Serializers/Primitives/Vector2DSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector2DConverter.cs similarity index 84% rename from Engine.Core/Serialization/Serializers/Primitives/Vector2DSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector2DConverter.cs index 7ef8673..1c1b420 100644 --- a/Engine.Core/Serialization/Serializers/Primitives/Vector2DSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector2DConverter.cs @@ -1,12 +1,14 @@ using System; +using Syntriax.Engine.Core; + using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class Vector2DSerializer : EngineTypeYamlSerializerBase +public class Vector2DConverter : EngineTypeYamlSerializerBase { private static readonly int SUBSTRING_START_LENGTH = nameof(Vector2D).Length + 1; diff --git a/Engine.Core/Serialization/Serializers/Primitives/Vector3DSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector3DConverter.cs similarity index 85% rename from Engine.Core/Serialization/Serializers/Primitives/Vector3DSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector3DConverter.cs index e67b086..64f49c2 100644 --- a/Engine.Core/Serialization/Serializers/Primitives/Vector3DSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/Primitives/Vector3DConverter.cs @@ -1,12 +1,14 @@ using System; +using Syntriax.Engine.Core; + using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class Vector3DSerializer : EngineTypeYamlSerializerBase +public class Vector3DConverter : EngineTypeYamlSerializerBase { private static readonly int SUBSTRING_START_LENGTH = nameof(Vector3D).Length + 1; diff --git a/Engine.Core/Serialization/Serializers/SerializedClassSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/SerializedClassConverter.cs similarity index 84% rename from Engine.Core/Serialization/Serializers/SerializedClassSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/SerializedClassConverter.cs index 7779126..41c3d33 100644 --- a/Engine.Core/Serialization/Serializers/SerializedClassSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/SerializedClassConverter.cs @@ -2,15 +2,16 @@ using System; using System.Collections.Generic; using System.Linq; +using Syntriax.Engine.Core.Serialization; using Syntriax.Engine.Core.Factory; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class SerializedClassSerializer : EngineTypeYamlSerializerBase +public class SerializedClassConverter : EngineTypeYamlSerializerBase { public override SerializedClass? Read(IParser parser, Type type, ObjectDeserializer rootDeserializer) { @@ -33,10 +34,10 @@ public class SerializedClassSerializer : EngineTypeYamlSerializerBase +public class StateEnableConverter : EngineTypeYamlSerializerBase { public override IStateEnable? Read(IParser parser, Type type, ObjectDeserializer rootDeserializer) { diff --git a/Engine.Core/Serialization/Serializers/TypeContainerSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/TypeContainerConverter.cs similarity index 89% rename from Engine.Core/Serialization/Serializers/TypeContainerSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/TypeContainerConverter.cs index 677602a..0b7a665 100644 --- a/Engine.Core/Serialization/Serializers/TypeContainerSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/TypeContainerConverter.cs @@ -1,14 +1,15 @@ using System; +using Syntriax.Engine.Core.Serialization; using Syntriax.Engine.Core.Factory; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class TypeContainerSerializer : EngineTypeYamlSerializerBase +public class TypeContainerConverter : EngineTypeYamlSerializerBase { public override TypeContainer Read(IParser parser, Type type, ObjectDeserializer rootDeserializer) { diff --git a/Engine.Core/Serialization/Serializers/UniverseSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseConverter.cs similarity index 93% rename from Engine.Core/Serialization/Serializers/UniverseSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseConverter.cs index 5c70612..982ffa5 100644 --- a/Engine.Core/Serialization/Serializers/UniverseSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseConverter.cs @@ -2,13 +2,16 @@ using System; using System.Collections.Generic; using System.Linq; +using Syntriax.Engine.Core; +using Syntriax.Engine.Core.Serialization; + using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; -public class UniverseSerializer : EngineTypeYamlSerializerBase +public class UniverseConverter : EngineTypeYamlSerializerBase { public override IUniverse? Read(IParser parser, Type type, ObjectDeserializer rootDeserializer) { diff --git a/Engine.Core/Serialization/Serializers/UniverseObjectSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseObjectConverter.cs similarity index 96% rename from Engine.Core/Serialization/Serializers/UniverseObjectSerializer.cs rename to Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseObjectConverter.cs index 7794d24..db3c267 100644 --- a/Engine.Core/Serialization/Serializers/UniverseObjectSerializer.cs +++ b/Engine.Serializers/Engine.Serializers.Yaml/Converters/UniverseObjectConverter.cs @@ -2,11 +2,14 @@ using System; using System.Collections.Generic; using System.Linq; +using Syntriax.Engine.Core; +using Syntriax.Engine.Core.Serialization; + using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Serialization; -namespace Syntriax.Engine.Core.Serialization; +namespace Syntriax.Engine.Serializers.Yaml; public class UniverseObjectSerializer : EngineTypeYamlSerializerBase { diff --git a/Engine.Serializers/Engine.Serializers.Yaml/Engine.Serializers.Yaml.csproj b/Engine.Serializers/Engine.Serializers.Yaml/Engine.Serializers.Yaml.csproj new file mode 100644 index 0000000..2580590 --- /dev/null +++ b/Engine.Serializers/Engine.Serializers.Yaml/Engine.Serializers.Yaml.csproj @@ -0,0 +1,15 @@ + + + + net8.0 + false + enable + Syntriax.Engine.Serializers.Yaml + + + + + + + + diff --git a/Engine.Serializers/Engine.Serializers.Yaml/YamlSerializer.cs b/Engine.Serializers/Engine.Serializers.Yaml/YamlSerializer.cs new file mode 100644 index 0000000..93cfe4c --- /dev/null +++ b/Engine.Serializers/Engine.Serializers.Yaml/YamlSerializer.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +using Syntriax.Engine.Core.Serialization; + +using YamlDotNet.Serialization; +using YamlDotNet.Serialization.NamingConventions; + +namespace Syntriax.Engine.Serializers.Yaml; + +public class YamlSerializer : Core.Serialization.ISerializer +{ + private readonly YamlDotNet.Serialization.ISerializer serializer = null!; + private readonly YamlDotNet.Serialization.IDeserializer deserializer = null!; + + private readonly EntityRegistry entityRegistry = null!; + + public YamlSerializer() + { + entityRegistry = new(); + + SerializerBuilder serializerBuilder = new SerializerBuilder() + .WithNamingConvention(PascalCaseNamingConvention.Instance) + .DisableAliases(); + + DeserializerBuilder deserializerBuilder = new DeserializerBuilder() + .WithNamingConvention(PascalCaseNamingConvention.Instance); + + foreach (IEngineTypeYamlConverter typeConverter in GetEngineYamlTypeConverters()) + { + typeConverter.Serializer = this; + typeConverter.EntityRegistry = entityRegistry; + + deserializerBuilder = deserializerBuilder.WithTypeConverter(typeConverter); + serializerBuilder = serializerBuilder.WithTypeConverter(typeConverter); + } + + serializer = serializerBuilder.Build(); + deserializer = deserializerBuilder.Build(); + } + + private static IEnumerable GetEngineYamlTypeConverters() + { + foreach (Type type in Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(IEngineTypeYamlConverter).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract)) + yield return (Activator.CreateInstance(type) as IEngineTypeYamlConverter)!; + } + + public string Serialize(object instance) + { + return serializer.Serialize(instance); + } + + public object Deserialize(string yaml) + { + entityRegistry.Reset(); + object result = deserializer.Deserialize(yaml)!; + entityRegistry.AssignAll(); + return result; + } + + public object Deserialize(string yaml, Type type) + { + entityRegistry.Reset(); + object result = deserializer.Deserialize(yaml, type)!; + entityRegistry.AssignAll(); + return result; + } + + public T Deserialize(string yaml) + { + entityRegistry.Reset(); + T result = deserializer.Deserialize(yaml); + entityRegistry.AssignAll(); + return result; + } + + internal object InternalDeserialize(string yaml, Type type) + { + return deserializer.Deserialize(yaml, type)!; + } +} diff --git a/YamlDotNet b/Engine.Serializers/YamlDotNet similarity index 100% rename from YamlDotNet rename to Engine.Serializers/YamlDotNet diff --git a/Engine.sln b/Engine.sln index ae3e447..ca5e093 100644 --- a/Engine.sln +++ b/Engine.sln @@ -11,7 +11,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Systems", "Engine.Sy EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine", "Engine\Engine.csproj", "{58AE79C1-9203-44AE-8022-AA180F0A71DC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YamlDotNet", "YamlDotNet\YamlDotNet\YamlDotNet.csproj", "{4C4906EB-0210-493E-A7D0-7DEBDF2969E8}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Engine.Serializers", "Engine.Serializers", "{F88E129A-9A47-4D27-96EE-6EC02F79594B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Engine.Serializers.Yaml", "Engine.Serializers\Engine.Serializers.Yaml\Engine.Serializers.Yaml.csproj", "{E9D1CDC3-5BFF-4C87-AFEB-6CE372709176}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YamlDotNet", "Engine.Serializers\YamlDotNet\YamlDotNet\YamlDotNet.csproj", "{3D852C92-BC14-4893-AEF2-50612DAFCD8F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -35,12 +39,20 @@ Global {58AE79C1-9203-44AE-8022-AA180F0A71DC}.Debug|Any CPU.Build.0 = Debug|Any CPU {58AE79C1-9203-44AE-8022-AA180F0A71DC}.Release|Any CPU.ActiveCfg = Release|Any CPU {58AE79C1-9203-44AE-8022-AA180F0A71DC}.Release|Any CPU.Build.0 = Release|Any CPU - {4C4906EB-0210-493E-A7D0-7DEBDF2969E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4C4906EB-0210-493E-A7D0-7DEBDF2969E8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4C4906EB-0210-493E-A7D0-7DEBDF2969E8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4C4906EB-0210-493E-A7D0-7DEBDF2969E8}.Release|Any CPU.Build.0 = Release|Any CPU + {E9D1CDC3-5BFF-4C87-AFEB-6CE372709176}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E9D1CDC3-5BFF-4C87-AFEB-6CE372709176}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9D1CDC3-5BFF-4C87-AFEB-6CE372709176}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E9D1CDC3-5BFF-4C87-AFEB-6CE372709176}.Release|Any CPU.Build.0 = Release|Any CPU + {3D852C92-BC14-4893-AEF2-50612DAFCD8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D852C92-BC14-4893-AEF2-50612DAFCD8F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D852C92-BC14-4893-AEF2-50612DAFCD8F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D852C92-BC14-4893-AEF2-50612DAFCD8F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {E9D1CDC3-5BFF-4C87-AFEB-6CE372709176} = {F88E129A-9A47-4D27-96EE-6EC02F79594B} + {3D852C92-BC14-4893-AEF2-50612DAFCD8F} = {F88E129A-9A47-4D27-96EE-6EC02F79594B} + EndGlobalSection EndGlobal