84 lines
2.6 KiB
C#

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<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)
{
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<T>(string yaml)
{
entityRegistry.Reset();
T result = deserializer.Deserialize<T>(yaml);
entityRegistry.AssignAll();
return result;
}
internal object InternalDeserialize(string yaml, Type type)
{
return deserializer.Deserialize(yaml, type)!;
}
}