101 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Linq;
 | 
						|
 | 
						|
using Engine.Core;
 | 
						|
using Engine.Core.Factory;
 | 
						|
using Engine.Core.Serialization;
 | 
						|
 | 
						|
using YamlDotNet.Core;
 | 
						|
using YamlDotNet.Core.Events;
 | 
						|
using YamlDotNet.Serialization;
 | 
						|
 | 
						|
namespace Engine.Serializers.Yaml;
 | 
						|
 | 
						|
public class SerializedClassConverter : EngineTypeYamlSerializerBase<SerializedClass>
 | 
						|
{
 | 
						|
    public override SerializedClass? Read(IParser parser, Type type, ObjectDeserializer rootDeserializer)
 | 
						|
    {
 | 
						|
        bool isTrackingController = ProgressionTracker.Progression.ApproximatelyEquals(0f);
 | 
						|
        ProgressionTracker.Set(isTrackingController ? .1f : ProgressionTracker.Progression, $"Reading class");
 | 
						|
 | 
						|
        SerializedClass serializedClass = new();
 | 
						|
        Dictionary<string, object> publicDictionary = [];
 | 
						|
        Dictionary<string, object> privateDictionary = [];
 | 
						|
 | 
						|
        parser.Consume<MappingStart>();
 | 
						|
 | 
						|
        while (!parser.TryConsume<MappingEnd>(out _))
 | 
						|
        {
 | 
						|
            string key = parser.Consume<Scalar>().Value;
 | 
						|
 | 
						|
            switch (key)
 | 
						|
            {
 | 
						|
                case nameof(SerializedClass.Type): serializedClass.Type = parser.Consume<Scalar>().Value; break;
 | 
						|
                case nameof(SerializedClass.Public): publicDictionary = (Dictionary<string, object>)rootDeserializer(typeof(Dictionary<string, object>))!; break;
 | 
						|
                case nameof(SerializedClass.Private): privateDictionary = (Dictionary<string, object>)rootDeserializer(typeof(Dictionary<string, object>))!; break;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        Type classType = TypeFactory.GetType(serializedClass.Type);
 | 
						|
 | 
						|
        foreach ((string key, object @object) in publicDictionary)
 | 
						|
            if (@object is TypeContainer typeContainer)
 | 
						|
                serializedClass.Public.Add(key, Serializer.InternalDeserialize(typeContainer.Value!.ToString()!, TypeFactory.GetType(typeContainer.Type)));
 | 
						|
            else
 | 
						|
                serializedClass.Public.Add(key, Serializer.InternalDeserialize(@object.ToString()!, (classType.GetProperty(key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)?.PropertyType ?? classType.GetField(key, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)?.FieldType)!));
 | 
						|
 | 
						|
        foreach ((string key, object @object) in privateDictionary)
 | 
						|
            if (@object is TypeContainer typeContainer)
 | 
						|
                serializedClass.Private.Add(key, Serializer.InternalDeserialize(typeContainer.Value!.ToString()!, TypeFactory.GetType(typeContainer.Type)));
 | 
						|
            else
 | 
						|
                serializedClass.Private.Add(key, Serializer.InternalDeserialize(@object.ToString()!, (classType.GetProperty(key, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Default)?.PropertyType ?? classType.GetField(key, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Default)?.FieldType)!));
 | 
						|
 | 
						|
        ProgressionTracker.Set(isTrackingController ? 1f : ProgressionTracker.Progression, $"Read {serializedClass.Type}");
 | 
						|
        return serializedClass;
 | 
						|
    }
 | 
						|
 | 
						|
    public override void WriteYaml(IEmitter emitter, object? value, Type type, ObjectSerializer serializer)
 | 
						|
    {
 | 
						|
        SerializedClass serializedClass = (SerializedClass)value!;
 | 
						|
 | 
						|
        bool isTrackingController = ProgressionTracker.Progression.ApproximatelyEquals(0f);
 | 
						|
        ProgressionTracker.Set(isTrackingController ? .25f : ProgressionTracker.Progression, $"Serializing {serializedClass.Type}");
 | 
						|
 | 
						|
        Dictionary<string, object> publics = [];
 | 
						|
        Dictionary<string, object> privates = [];
 | 
						|
 | 
						|
        foreach ((string key, object? @object) in serializedClass.Public.Where(v => !v.GetType().HasAttribute<IgnoreSerializationAttribute>()))
 | 
						|
            if (@object?.GetType().IsClass == false)
 | 
						|
                publics.Add(key, @object!);
 | 
						|
            else
 | 
						|
                publics.Add(key, new TypeContainer(@object));
 | 
						|
 | 
						|
        foreach ((string key, object? @object) in serializedClass.Private.Where(v => !v.GetType().HasAttribute<IgnoreSerializationAttribute>()))
 | 
						|
            if (@object?.GetType().IsClass == false)
 | 
						|
                privates.Add(key, @object!);
 | 
						|
            else
 | 
						|
                privates.Add(key, new TypeContainer(@object));
 | 
						|
 | 
						|
        emitter.Emit(new MappingStart());
 | 
						|
 | 
						|
        emitter.Emit(new Scalar(nameof(SerializedClass.Type)));
 | 
						|
        emitter.Emit(new Scalar(serializedClass.Type));
 | 
						|
 | 
						|
        if (publics.Count > 0)
 | 
						|
        {
 | 
						|
            emitter.Emit(new Scalar(nameof(SerializedClass.Public)));
 | 
						|
            serializer(publics);
 | 
						|
        }
 | 
						|
 | 
						|
        if (privates.Count > 0)
 | 
						|
        {
 | 
						|
            emitter.Emit(new Scalar(nameof(SerializedClass.Private)));
 | 
						|
            serializer(privates);
 | 
						|
        }
 | 
						|
 | 
						|
        ProgressionTracker.Set(isTrackingController ? 1f : ProgressionTracker.Progression, $"Serialized {serializedClass.Type}");
 | 
						|
        emitter.Emit(new MappingEnd());
 | 
						|
    }
 | 
						|
}
 |