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