using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; using Syntriax.Engine.Core; 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!; private readonly IProgressionTracker progressionTracker = null!; private readonly System.Threading.Lock Lock = new(); public YamlSerializer() { entityRegistry = new(); progressionTracker = new ProgressionTracker(); 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; typeConverter.ProgressionTracker = progressionTracker; 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) { lock (Lock) { return serializer.Serialize(instance); } } public object Deserialize(string configuration) { lock (Lock) { entityRegistry.Reset(); object result = deserializer.Deserialize(configuration)!; entityRegistry.AssignAll(); return result; } } public object Deserialize(string configuration, Type type) { lock (Lock) { entityRegistry.Reset(); object result = deserializer.Deserialize(configuration, type)!; entityRegistry.AssignAll(); return result; } } public T Deserialize(string configuration) { lock (Lock) { entityRegistry.Reset(); T result = deserializer.Deserialize(configuration); entityRegistry.AssignAll(); return result; } } public ProgressiveTask DeserializeAsync(string configuration) { lock (Lock) { progressionTracker.Reset(); Task task = Task.Run(() => Deserialize(configuration)); return new ProgressiveTask(progressionTracker, task); } } public ProgressiveTask DeserializeAsync(string configuration, Type type) { lock (Lock) { progressionTracker.Reset(); Task task = Task.Run(() => Deserialize(configuration, type)); return new ProgressiveTask(progressionTracker, task); } } public ProgressiveTask DeserializeAsync(string configuration) { lock (Lock) { progressionTracker.Reset(); Task task = Task.Run(() => Deserialize(configuration)); return new ProgressiveTask(progressionTracker, task); } } public ProgressiveTask SerializeAsync(object instance) { lock (Lock) { progressionTracker.Reset(); Task task = Task.Run(() => Serialize(instance)); return new ProgressiveTask(progressionTracker, task); } } internal object InternalDeserialize(string configuration, Type type) { return deserializer.Deserialize(configuration, type)!; } }