diff --git a/Engine.Serialization/SerializeAllAttribute.cs b/Engine.Serialization/SerializeAllAttribute.cs new file mode 100644 index 0000000..9ed6d50 --- /dev/null +++ b/Engine.Serialization/SerializeAllAttribute.cs @@ -0,0 +1,4 @@ +namespace Syntriax.Engine.Serialization; + +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct)] +public class SerializeAllAttribute : Attribute; diff --git a/Engine.Serialization/SerializedClass.cs b/Engine.Serialization/SerializedClass.cs new file mode 100644 index 0000000..2185f9e --- /dev/null +++ b/Engine.Serialization/SerializedClass.cs @@ -0,0 +1,102 @@ +using System.Reflection; + +using Syntriax.Engine.Core.Factory; + +namespace Syntriax.Engine.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 Public { get; set; } = []; + public Dictionary 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(); + + Public.Clear(); + Private.Clear(); + + foreach (PropertyInfo privatePropertyInfo in Utils.GetPropertyInfosIncludingBaseClasses(type, PRIVATE_BINDING_FLAGS)) + { + if (privatePropertyInfo.HasAttribute()) + continue; + + if (privatePropertyInfo.SetMethod is null) + continue; + + if (!isFullySerializable && !privatePropertyInfo.HasAttribute()) + continue; + + Private.Add(privatePropertyInfo.Name, privatePropertyInfo.GetValue(@class)); + } + + foreach (PropertyInfo publicPropertyInfo in Utils.GetPropertyInfosIncludingBaseClasses(type, PUBLIC_BINDING_FLAGS)) + { + if (publicPropertyInfo.HasAttribute()) + continue; + + if (publicPropertyInfo.SetMethod is null) + continue; + + if (!isFullySerializable && !publicPropertyInfo.HasAttribute()) + continue; + + Public.Add(publicPropertyInfo.Name, publicPropertyInfo.GetValue(@class)); + } + + foreach (FieldInfo privateFieldInfo in Utils.GetFieldInfosIncludingBaseClasses(type, PRIVATE_BINDING_FLAGS)) + { + if (privateFieldInfo.HasAttribute()) + continue; + + if (!isFullySerializable && !privateFieldInfo.HasAttribute()) + continue; + + Private.Add(privateFieldInfo.Name, privateFieldInfo.GetValue(@class)); + } + + foreach (FieldInfo publicFieldInfo in Utils.GetFieldInfosIncludingBaseClasses(type, PUBLIC_BINDING_FLAGS)) + { + if (publicFieldInfo.HasAttribute()) + continue; + + if (!isFullySerializable && !publicFieldInfo.HasAttribute()) + continue; + + Public.Add(publicFieldInfo.Name, publicFieldInfo.GetValue(@class)); + } + } + + 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; + } +} diff --git a/Engine.Serialization/SerializedEntity.cs b/Engine.Serialization/SerializedEntity.cs deleted file mode 100644 index 8631021..0000000 --- a/Engine.Serialization/SerializedEntity.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Reflection; -using Syntriax.Engine.Core; - -namespace Syntriax.Engine.Serialization; - -public class SerializedEntity -{ - public string Id { get; set; } = string.Empty; - public string Type { get; set; } = string.Empty; - - public Dictionary Public = []; - public Dictionary Private = []; - - public SerializedEntity() { } - public SerializedEntity(object entity) - { - Type type = entity.GetType(); - Type = type.FullName ?? throw new($"Object {entity} has no {nameof(System.Type.FullName)}"); - Id = type.GetProperty(nameof(IEntity.Id), BindingFlags.Instance | BindingFlags.Public)?.GetValue(entity)?.ToString() ?? string.Empty; - - foreach (PropertyInfo privatePropertyInfo in Utils.GetPropertyInfosIncludingBaseClasses(type, BindingFlags.Instance | BindingFlags.NonPublic)) - { - if (privatePropertyInfo.HasAttribute()) - continue; - - Private.Add(privatePropertyInfo.Name, privatePropertyInfo.GetValue(entity)); - } - - foreach (PropertyInfo publicPropertyInfo in Utils.GetPropertyInfosIncludingBaseClasses(type, BindingFlags.Instance | BindingFlags.Public)) - { - if (publicPropertyInfo.HasAttribute()) - continue; - - Public.Add(publicPropertyInfo.Name, publicPropertyInfo.GetValue(entity)); - } - - foreach (FieldInfo privateFieldInfo in Utils.GetFieldInfosIncludingBaseClasses(type, BindingFlags.Instance | BindingFlags.NonPublic)) - { - if (privateFieldInfo.HasAttribute()) - continue; - - // if (!privateFieldInfo.HasAttribute()) - // continue; - - Private.Add(privateFieldInfo.Name, privateFieldInfo.GetValue(entity)); - } - - foreach (FieldInfo publicFieldInfo in Utils.GetFieldInfosIncludingBaseClasses(type, BindingFlags.Instance | BindingFlags.Public)) - { - if (publicFieldInfo.HasAttribute()) - continue; - - // if (!publicFieldInfo.HasAttribute()) - // continue; - - Public.Add(publicFieldInfo.Name, publicFieldInfo.GetValue(entity)); - } - } -}