refactor: moved serialization into core project
This commit is contained in:
120
Engine.Core/Serialization/SerializedClass.cs
Normal file
120
Engine.Core/Serialization/SerializedClass.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
using Syntriax.Engine.Core.Factory;
|
||||
|
||||
namespace Syntriax.Engine.Core.Serialization;
|
||||
|
||||
public class SerializedClass
|
||||
{
|
||||
private const BindingFlags PRIVATE_BINDING_FLAGS = BindingFlags.Instance | BindingFlags.NonPublic;
|
||||
private const BindingFlags PUBLIC_BINDING_FLAGS = BindingFlags.Instance | BindingFlags.Public;
|
||||
|
||||
public string Type { get; set; } = string.Empty;
|
||||
public Dictionary<string, object?> Public { get; set; } = [];
|
||||
public Dictionary<string, object?> Private { get; set; } = [];
|
||||
|
||||
public SerializedClass() { }
|
||||
public SerializedClass(object @class)
|
||||
{
|
||||
UpdateClass(@class);
|
||||
}
|
||||
|
||||
private void UpdateClass(object @class)
|
||||
{
|
||||
Type type = @class.GetType();
|
||||
Type = type.FullName ?? type.Name;
|
||||
|
||||
bool isFullySerializable = type.HasAttribute<SerializeAllAttribute>();
|
||||
|
||||
Public.Clear();
|
||||
Private.Clear();
|
||||
|
||||
foreach (PropertyInfo privatePropertyInfo in Utils.GetPropertyInfosIncludingBaseClasses(type, PRIVATE_BINDING_FLAGS))
|
||||
{
|
||||
if (privatePropertyInfo.HasAttribute<IgnoreSerializationAttribute>())
|
||||
continue;
|
||||
|
||||
if (privatePropertyInfo.SetMethod is null)
|
||||
continue;
|
||||
|
||||
if (!isFullySerializable && !privatePropertyInfo.HasAttribute<SerializeAttribute>())
|
||||
continue;
|
||||
|
||||
object? value = privatePropertyInfo.GetValue(@class);
|
||||
if (value is IEntity entity)
|
||||
Private.Add(privatePropertyInfo.Name, entity.Id);
|
||||
else
|
||||
Private.Add(privatePropertyInfo.Name, value);
|
||||
}
|
||||
|
||||
foreach (PropertyInfo publicPropertyInfo in Utils.GetPropertyInfosIncludingBaseClasses(type, PUBLIC_BINDING_FLAGS))
|
||||
{
|
||||
if (publicPropertyInfo.HasAttribute<IgnoreSerializationAttribute>())
|
||||
continue;
|
||||
|
||||
if (publicPropertyInfo.SetMethod is null)
|
||||
continue;
|
||||
|
||||
if (!isFullySerializable && !publicPropertyInfo.HasAttribute<SerializeAttribute>())
|
||||
continue;
|
||||
|
||||
object? value = publicPropertyInfo.GetValue(@class);
|
||||
if (value is IEntity entity)
|
||||
Public.Add(publicPropertyInfo.Name, entity.Id);
|
||||
else
|
||||
Public.Add(publicPropertyInfo.Name, value);
|
||||
}
|
||||
|
||||
foreach (FieldInfo privateFieldInfo in Utils.GetFieldInfosIncludingBaseClasses(type, PRIVATE_BINDING_FLAGS))
|
||||
{
|
||||
if (privateFieldInfo.HasAttribute<System.Runtime.CompilerServices.CompilerGeneratedAttribute>())
|
||||
continue;
|
||||
|
||||
if (!isFullySerializable && !privateFieldInfo.HasAttribute<SerializeAttribute>())
|
||||
continue;
|
||||
|
||||
object? value = privateFieldInfo.GetValue(@class);
|
||||
if (value is IEntity entity)
|
||||
Private.Add(privateFieldInfo.Name, entity.Id);
|
||||
else
|
||||
Private.Add(privateFieldInfo.Name, value);
|
||||
}
|
||||
|
||||
foreach (FieldInfo publicFieldInfo in Utils.GetFieldInfosIncludingBaseClasses(type, PUBLIC_BINDING_FLAGS))
|
||||
{
|
||||
if (publicFieldInfo.HasAttribute<System.Runtime.CompilerServices.CompilerGeneratedAttribute>())
|
||||
continue;
|
||||
|
||||
if (!isFullySerializable && !publicFieldInfo.HasAttribute<SerializeAttribute>())
|
||||
continue;
|
||||
|
||||
object? value = publicFieldInfo.GetValue(@class);
|
||||
if (value is IEntity entity)
|
||||
Public.Add(publicFieldInfo.Name, entity.Id);
|
||||
else
|
||||
Public.Add(publicFieldInfo.Name, value);
|
||||
}
|
||||
}
|
||||
|
||||
public object CreateInstance()
|
||||
{
|
||||
Type type = TypeFactory.GetType(Type);
|
||||
object instance = TypeFactory.Get(type);
|
||||
|
||||
foreach ((string key, object? value) in Private)
|
||||
if (type.GetField(key, PRIVATE_BINDING_FLAGS) is FieldInfo fieldInfo)
|
||||
fieldInfo.SetValue(instance, value);
|
||||
else if (type.GetProperty(key, PRIVATE_BINDING_FLAGS) is PropertyInfo propertyInfo)
|
||||
propertyInfo.SetValue(instance, value);
|
||||
|
||||
foreach ((string key, object? value) in Public)
|
||||
if (type.GetField(key, PUBLIC_BINDING_FLAGS) is FieldInfo fieldInfo)
|
||||
fieldInfo.SetValue(instance, value);
|
||||
else if (type.GetProperty(key, PUBLIC_BINDING_FLAGS) is PropertyInfo propertyInfo)
|
||||
propertyInfo.SetValue(instance, value);
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user