143 lines
4.4 KiB
C#

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<IEngineTypeYamlConverter> 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<T>(string configuration)
{
lock (Lock)
{
entityRegistry.Reset();
T result = deserializer.Deserialize<T>(configuration);
entityRegistry.AssignAll();
return result;
}
}
public ProgressiveTask<object> DeserializeAsync(string configuration)
{
lock (Lock)
{
progressionTracker.Reset();
Task<object> task = Task.Run(() => Deserialize(configuration));
return new ProgressiveTask<object>(progressionTracker, task);
}
}
public ProgressiveTask<object> DeserializeAsync(string configuration, Type type)
{
lock (Lock)
{
progressionTracker.Reset();
Task<object> task = Task.Run(() => Deserialize(configuration, type));
return new ProgressiveTask<object>(progressionTracker, task);
}
}
public ProgressiveTask<T> DeserializeAsync<T>(string configuration)
{
lock (Lock)
{
progressionTracker.Reset();
Task<T> task = Task.Run(() => Deserialize<T>(configuration));
return new ProgressiveTask<T>(progressionTracker, task);
}
}
public ProgressiveTask<string> SerializeAsync(object instance)
{
lock (Lock)
{
progressionTracker.Reset();
Task<string> task = Task.Run(() => Serialize(instance));
return new ProgressiveTask<string>(progressionTracker, task);
}
}
internal object InternalDeserialize(string configuration, Type type)
{
return deserializer.Deserialize(configuration, type)!;
}
}