From 10e8b3c282746dd3ff96531089cd7a67321f8062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Sat, 1 Mar 2025 00:48:31 +0100 Subject: [PATCH] Simplified serialization/deserialization of EngineObjects + added support for Assets (actually any EngineObject!) --- .../src/Scripting/ScriptInstanceSerializer.bf | 2 +- .../src/Serialization/SerializationType.bf | 9 +++-- .../src/Serialization/SerializedObject.bf | 17 +++------ .../Serialization/DeserializationObject.cs | 38 +++++++++++-------- ScriptCore/Serialization/SerializationType.cs | 9 ++--- ScriptCore/Serialization/SerializedObject.cs | 8 +--- 6 files changed, 41 insertions(+), 42 deletions(-) diff --git a/GlitchyEngine/src/Scripting/ScriptInstanceSerializer.bf b/GlitchyEngine/src/Scripting/ScriptInstanceSerializer.bf index 65d91f2..55cc1d2 100644 --- a/GlitchyEngine/src/Scripting/ScriptInstanceSerializer.bf +++ b/GlitchyEngine/src/Scripting/ScriptInstanceSerializer.bf @@ -121,7 +121,7 @@ public class ScriptInstanceSerializer { for (var fieldData in ref object.Fields.Values) { - if (fieldData.PrimitiveType != .EntityReference && fieldData.PrimitiveType != .ComponentReference) + if (fieldData.PrimitiveType != .EngineObjectReference) continue; if (originalToCopyIds.TryGetValue(fieldData.Data.EngineObject.ID, let copyId)) diff --git a/GlitchyEngine/src/Serialization/SerializationType.bf b/GlitchyEngine/src/Serialization/SerializationType.bf index 66b7f18..cc28382 100644 --- a/GlitchyEngine/src/Serialization/SerializationType.bf +++ b/GlitchyEngine/src/Serialization/SerializationType.bf @@ -36,10 +36,9 @@ public enum SerializationType : uint32 case Enum = 1 << 26; - case EntityReference = 1 << 25; - case ComponentReference = 1 << 24; + case EngineObjectReference = 1 << 25; - case ObjectReference = 1 << 23; + case ObjectReference = 1 << 24; public int GetSize() { @@ -63,7 +62,9 @@ public enum SerializationType : uint32 return 8; case .Decimal: return 16; - case .EntityReference, .ComponentReference, .ObjectReference: + case .EngineObjectReference: + return sizeof(UUID); + case .ObjectReference: return sizeof(UUID); case .String: return sizeof(StringView); diff --git a/GlitchyEngine/src/Serialization/SerializedObject.bf b/GlitchyEngine/src/Serialization/SerializedObject.bf index 5bd918f..a5644d2 100644 --- a/GlitchyEngine/src/Serialization/SerializedObject.bf +++ b/GlitchyEngine/src/Serialization/SerializedObject.bf @@ -115,7 +115,7 @@ class SerializedObject } data.StringView = valueView; - case .EntityReference, .ComponentReference: + case .EngineObjectReference: String typeName = null; if (fullTypeName != null) @@ -191,7 +191,7 @@ class SerializedObject { case .String, .Enum: *(StringView*)target = field.Data.StringView; - case .EntityReference, .ComponentReference: + case .EngineObjectReference: let engineObjectData = field.Data.EngineObject; *(char8**)target = engineObjectData.FullTypeName?.CStr(); @@ -303,13 +303,8 @@ class SerializedObject writer.Type("Enum"); #unwarn Serialize.Value(writer, ValueView(typeof(StringView), &field.Data.StringView), environment); - case .EntityReference: - writer.Type("Entity"); - if (field.Data.EngineObject.FullTypeName != null) - writer.Type(field.Data.EngineObject.FullTypeName); - Serialize.Value(writer, field.Data.EngineObject.ID, environment); - case .ComponentReference: - writer.Type("Component"); + case .EngineObjectReference: + writer.Type("EngineObject"); if (field.Data.EngineObject.FullTypeName != null) writer.Type(field.Data.EngineObject.FullTypeName); Serialize.Value(writer, field.Data.EngineObject.ID, environment); @@ -502,7 +497,7 @@ class SerializedObject break HandleField; } - else if (fieldTypeName == "Entity" || fieldTypeName == "Component") + else if (fieldTypeName == "EngineObject") { String entityTypeName = null; @@ -521,7 +516,7 @@ class SerializedObject Deserialize.[Friend]Integer!(typeof(uint64), reader, ValueView(typeof(uint64), &id)); UUID reference = UUID(id); - fieldType = (fieldTypeName == "Entity") ? .EntityReference : .ComponentReference; + fieldType = .EngineObjectReference; fieldData.EngineObject = (FullTypeName: entityTypeName, ID: reference); break HandleField; diff --git a/ScriptCore/Serialization/DeserializationObject.cs b/ScriptCore/Serialization/DeserializationObject.cs index cf71344..119bde2 100644 --- a/ScriptCore/Serialization/DeserializationObject.cs +++ b/ScriptCore/Serialization/DeserializationObject.cs @@ -139,17 +139,17 @@ public class DeserializationObject _structScopeName = _structScopeName.Remove(_structScopeName.Length - scopeToRemove.Length - 1); } + [StructLayout(LayoutKind.Sequential)] + public unsafe struct EngineObjectReferenceHelper + { + public byte* FullTypeName; + public long FullTypeNameLength; + public UUID Id; + } + [StructLayout(LayoutKind.Explicit)] - private unsafe struct DataHelper + private struct DataHelper { - [StructLayout(LayoutKind.Sequential)] - public struct EngineObjectReferenceHelper - { - public byte* FullTypeName; - public long FullTypeNameLength; - public UUID Id; - } - [FieldOffset(0)] public EngineObjectReferenceHelper EngineObjectReference; @@ -220,8 +220,7 @@ public class DeserializationObject SerializationType.Double => *(double*)rawData, SerializationType.Decimal => *(decimal*)rawData, SerializationType.Enum => GetString(), - SerializationType.EntityReference => dataHelper.EngineObjectReference, - SerializationType.ComponentReference => dataHelper.EngineObjectReference, + SerializationType.EngineObjectReference => dataHelper.EngineObjectReference, SerializationType.ObjectReference => dataHelper.UUID, _ => NoValueDeserialized }; @@ -549,12 +548,13 @@ public class DeserializationObject bool isEntity = typeof(Entity).IsAssignableFrom(fieldType); bool isComponent = fieldType.IsSubclassOf(typeof(Component)); + bool isEngineObject = fieldType.IsSubclassOf(typeof(EngineObject)); - if (isEntity || isComponent) + if (isEntity || isComponent || isEngineObject) { - object? fieldData = GetFieldValue(fieldName, isEntity ? SerializationType.EntityReference : SerializationType.ComponentReference); + object? fieldData = GetFieldValue(fieldName, SerializationType.EngineObjectReference); - if (fieldData is not DataHelper.EngineObjectReferenceHelper data) + if (fieldData is not EngineObjectReferenceHelper data) return NoValueDeserialized; UUID id = data.Id; @@ -578,12 +578,20 @@ public class DeserializationObject return Entity.GetScriptReference(id, type); } - else + if (isComponent) { Entity entity = new Entity(id); return entity.GetComponent(type); } + if (isEngineObject) + { + EngineObject? engineObject = ActivatorExtension.CreateEngineObject(type, id); + + return engineObject; + } + + return NoValueDeserialized; } else { diff --git a/ScriptCore/Serialization/SerializationType.cs b/ScriptCore/Serialization/SerializationType.cs index b66fc4d..4d0ba77 100644 --- a/ScriptCore/Serialization/SerializationType.cs +++ b/ScriptCore/Serialization/SerializationType.cs @@ -35,10 +35,10 @@ public enum SerializationType : uint Enum = 1 << 26, - EntityReference = 1 << 25, - ComponentReference = 1 << 24, + // Used for everything that inherits from EngineObject (Assets, Components, Entities) + EngineObjectReference = 1 << 25, - ObjectReference = 1 << 23, + ObjectReference = 1 << 24, } public static class SerializationTypeExtension @@ -69,8 +69,7 @@ public static class SerializationTypeExtension SerializationType.Double => typeof(double), SerializationType.Decimal => typeof(decimal), SerializationType.Enum => typeof(Enum), - SerializationType.EntityReference => typeof(UUID), - SerializationType.ComponentReference => typeof(UUID), + SerializationType.EngineObjectReference => typeof(UUID), SerializationType.ObjectReference => typeof(UUID), _ => null }; diff --git a/ScriptCore/Serialization/SerializedObject.cs b/ScriptCore/Serialization/SerializedObject.cs index 80458f8..2fc456a 100644 --- a/ScriptCore/Serialization/SerializedObject.cs +++ b/ScriptCore/Serialization/SerializedObject.cs @@ -316,13 +316,9 @@ public class SerializedObject public void SerializeClass(string fieldName, object? fieldValue, Type fieldType) { - if (typeof(Entity).IsAssignableFrom(fieldType)) + if (fieldType.IsSubclassOf(typeof(EngineObject))) { - AddField(fieldName, SerializationType.EntityReference, ((Entity?)fieldValue)?.UUID ?? UUID.Zero, fieldValue?.GetType().FullName); - } - else if (fieldType.IsSubclassOf(typeof(Component))) - { - AddField(fieldName, SerializationType.ComponentReference, ((Component?)fieldValue)?.UUID ?? UUID.Zero, fieldValue?.GetType().FullName); + AddField(fieldName, SerializationType.EngineObjectReference, ((EngineObject?)fieldValue)?.UUID ?? UUID.Zero, fieldValue?.GetType().FullName); } else {