mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Serialize Data
This commit is contained in:
@@ -866,7 +866,9 @@ namespace GlitchyEditor
|
|||||||
/// Starts the play mode for the current scene
|
/// Starts the play mode for the current scene
|
||||||
private void OnScenePlay()
|
private void OnScenePlay()
|
||||||
{
|
{
|
||||||
// TODO: Dictionary<UUID, ScriptData> scriptData = _editorScene.SerializeScripts();
|
Dictionary<UUID, SerializedObject> serializedData = scope .();
|
||||||
|
|
||||||
|
ScriptEngine.SerializeScriptInstances(serializedData);
|
||||||
|
|
||||||
_editor.SceneViewportWindow.EditorMode = false;
|
_editor.SceneViewportWindow.EditorMode = false;
|
||||||
_sceneState = .Play;
|
_sceneState = .Play;
|
||||||
@@ -879,13 +881,18 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
SetActiveScene(runtimeScene, startRuntime: true, startSimulation: true);
|
SetActiveScene(runtimeScene, startRuntime: true, startSimulation: true);
|
||||||
|
|
||||||
// TODO: runtimeScene.DeserializeScripts(scriptData);
|
ScriptEngine.DeserializeScriptInstances(serializedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
_editor.CurrentScene = _activeScene;
|
_editor.CurrentScene = _activeScene;
|
||||||
|
|
||||||
if (Application.Instance.Settings.EditorSettings.SwitchToPlayerOnPlay)
|
if (Application.Instance.Settings.EditorSettings.SwitchToPlayerOnPlay)
|
||||||
SwitchToPlayWindow();
|
SwitchToPlayWindow();
|
||||||
|
|
||||||
|
for (let v in serializedData)
|
||||||
|
{
|
||||||
|
delete v.value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Activates the given scene.
|
/// Activates the given scene.
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ class EngineClasses
|
|||||||
|
|
||||||
public ScriptClass EntityEditor => s_EntityEditor;
|
public ScriptClass EntityEditor => s_EntityEditor;
|
||||||
|
|
||||||
|
public ScriptClass EntitySerializer => s_EntitySerializer;
|
||||||
|
//public ScriptClass SerializationContext => s_SerializationContext;
|
||||||
|
|
||||||
internal void ReleaseAndNullify()
|
internal void ReleaseAndNullify()
|
||||||
{
|
{
|
||||||
ReleaseRefAndNullify!(s_EngineObject);
|
ReleaseRefAndNullify!(s_EngineObject);
|
||||||
@@ -87,6 +90,9 @@ class EngineClasses
|
|||||||
|
|
||||||
// Editor classes
|
// Editor classes
|
||||||
s_EntityEditor = new ScriptClass("GlitchyEngine.Editor", "EntityEditor", image, .Class);
|
s_EntityEditor = new ScriptClass("GlitchyEngine.Editor", "EntityEditor", image, .Class);
|
||||||
|
|
||||||
|
s_EntitySerializer = new ScriptClass("GlitchyEngine.Serialization", "EntitySerializer", image, .Class);
|
||||||
|
//s_SerializationContext = new ScriptClass("GlitchyEngine.Serialization", "EntitySerializer.SerializationContext", image, .Class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -947,13 +953,34 @@ static class ScriptEngine
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Serializes all script instances
|
/// Serializes all script instances
|
||||||
public static void SerializeScriptInstances(String output)
|
public static void SerializeScriptInstances(Dictionary<UUID, SerializedObject> allObjects)
|
||||||
{
|
{
|
||||||
ScriptInstanceSerializer serializer = scope .();
|
|
||||||
|
|
||||||
for (let (id, script) in _entityScriptInstances)
|
for (let (id, script) in _entityScriptInstances)
|
||||||
{
|
{
|
||||||
serializer.Serialize(script);
|
if (script.ScriptClass.ClassName != "SerializationTest")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SerializedObject object = new SerializedObject(allObjects);
|
||||||
|
|
||||||
|
object.Id = script.EntityId;
|
||||||
|
object.AllObjects = allObjects;
|
||||||
|
|
||||||
|
object.Serialize(script);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deserializes the given data into the script instances
|
||||||
|
public static void DeserializeScriptInstances(Dictionary<UUID, SerializedObject> allObjects)
|
||||||
|
{
|
||||||
|
for (let (id, script) in _entityScriptInstances)
|
||||||
|
{
|
||||||
|
if (script.ScriptClass.ClassName != "SerializationTest")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (allObjects.TryGetValue(id, let object))
|
||||||
|
{
|
||||||
|
object.Deserialize(script);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -529,6 +529,37 @@ static class ScriptGlue
|
|||||||
return ScriptEngine.ApplicationInfo.IsInPlayMode;
|
return ScriptEngine.ApplicationInfo.IsInPlayMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Serialization
|
||||||
|
|
||||||
|
[RegisterCall("ScriptGlue::Serialization_SerializeField")]
|
||||||
|
static void Serialization_SerializeField(void* serializationContext, SerializationType type, MonoString* nameObject, MonoObject* valueObject)
|
||||||
|
{
|
||||||
|
SerializedObject context = Internal.UnsafeCastToObject(serializationContext) as SerializedObject;
|
||||||
|
|
||||||
|
Log.EngineLogger.AssertDebug(context != null);
|
||||||
|
|
||||||
|
char8* name = Mono.mono_string_to_utf8(nameObject);
|
||||||
|
|
||||||
|
context.AddField(StringView(name), type, valueObject);
|
||||||
|
|
||||||
|
Mono.mono_free(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
[RegisterCall("ScriptGlue::Serialization_CreateObject")]
|
||||||
|
static void Serialization_CreateObject(void* currentContext, out void* newContext, out UUID newId)
|
||||||
|
{
|
||||||
|
SerializedObject context = Internal.UnsafeCastToObject(currentContext) as SerializedObject;
|
||||||
|
|
||||||
|
Log.EngineLogger.AssertDebug(context != null);
|
||||||
|
|
||||||
|
SerializedObject newObject = new SerializedObject(context.AllObjects);
|
||||||
|
|
||||||
|
newContext = Internal.UnsafeCastToPtr(newObject);
|
||||||
|
newId = newObject.Id;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private static void RegisterCall<T>(String name, T method) where T : var
|
private static void RegisterCall<T>(String name, T method) where T : var
|
||||||
|
|||||||
@@ -0,0 +1,171 @@
|
|||||||
|
using Mono;
|
||||||
|
using System.Collections;
|
||||||
|
using System;
|
||||||
|
using GlitchyEngine.Core;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Scripting;
|
||||||
|
|
||||||
|
public enum SerializationType : int32
|
||||||
|
{
|
||||||
|
case None;
|
||||||
|
|
||||||
|
case Bool;
|
||||||
|
|
||||||
|
case Char;
|
||||||
|
case String;
|
||||||
|
|
||||||
|
case Int8;
|
||||||
|
case Int16;
|
||||||
|
case Int32;
|
||||||
|
case Int64;
|
||||||
|
case UInt8;
|
||||||
|
case UInt16;
|
||||||
|
case UInt32;
|
||||||
|
case UInt64;
|
||||||
|
|
||||||
|
case Float;
|
||||||
|
case Double;
|
||||||
|
case Decimal;
|
||||||
|
|
||||||
|
case Enum;
|
||||||
|
|
||||||
|
case EntityReference;
|
||||||
|
case ComponentReference;
|
||||||
|
|
||||||
|
case ObjectReference;
|
||||||
|
|
||||||
|
public int GetSize()
|
||||||
|
{
|
||||||
|
switch (this)
|
||||||
|
{
|
||||||
|
case .Bool:
|
||||||
|
return 1;
|
||||||
|
case .Char:
|
||||||
|
return 1;
|
||||||
|
case .Int8, .UInt8:
|
||||||
|
return 1;
|
||||||
|
case .Int16, .UInt16:
|
||||||
|
return 2;
|
||||||
|
case .Int32, .UInt32:
|
||||||
|
return 4;
|
||||||
|
case .Int64, .UInt64:
|
||||||
|
return 8;
|
||||||
|
case .Float:
|
||||||
|
return 4;
|
||||||
|
case .Double:
|
||||||
|
return 8;
|
||||||
|
case .Decimal:
|
||||||
|
return 16;
|
||||||
|
case .EntityReference, .ComponentReference, .ObjectReference:
|
||||||
|
return sizeof(UUID);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SerializedObject
|
||||||
|
{
|
||||||
|
public UUID Id;
|
||||||
|
|
||||||
|
public Dictionary<UUID, SerializedObject> AllObjects;
|
||||||
|
|
||||||
|
private List<String> _ownedString = new List<String>() ~ DeleteContainerAndItems!(_);
|
||||||
|
|
||||||
|
public append Dictionary<StringView, (SerializationType PrimitiveType, uint8[16] Data)> Fields = .();
|
||||||
|
|
||||||
|
public this(Dictionary<UUID, SerializedObject> allObjects)
|
||||||
|
{
|
||||||
|
AllObjects = allObjects;
|
||||||
|
|
||||||
|
// Make sure we have no duplicate keys
|
||||||
|
repeat
|
||||||
|
{
|
||||||
|
Id = UUID.Create();
|
||||||
|
}
|
||||||
|
while (AllObjects.ContainsKey(Id));
|
||||||
|
|
||||||
|
AllObjects.Add(Id, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddField(StringView name, SerializationType primitiveType, MonoObject* value)
|
||||||
|
{
|
||||||
|
uint8[16] data = .();
|
||||||
|
|
||||||
|
if (primitiveType == .String)
|
||||||
|
{
|
||||||
|
MonoString* string = (.)value;
|
||||||
|
|
||||||
|
char8* rawStringValue = Mono.mono_string_to_utf8(string);
|
||||||
|
|
||||||
|
String stringValue = new String(rawStringValue);
|
||||||
|
|
||||||
|
_ownedString.Add(stringValue);
|
||||||
|
|
||||||
|
Mono.mono_free(rawStringValue);
|
||||||
|
|
||||||
|
StringView valueView = stringValue;
|
||||||
|
|
||||||
|
Internal.MemCpy(&data, &valueView, sizeof(StringView));
|
||||||
|
}
|
||||||
|
else if (primitiveType == .Enum)
|
||||||
|
{
|
||||||
|
MonoString* string = (.)value;
|
||||||
|
|
||||||
|
char8* rawEnumValue = Mono.mono_string_to_utf8(string);
|
||||||
|
|
||||||
|
String enumValue = new String(rawEnumValue);
|
||||||
|
|
||||||
|
_ownedString.Add(enumValue);
|
||||||
|
|
||||||
|
Mono.mono_free(rawEnumValue);
|
||||||
|
|
||||||
|
StringView valueView = enumValue;
|
||||||
|
|
||||||
|
Internal.MemCpy(&data, &valueView, sizeof(StringView));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
void* rawValue = Mono.mono_object_unbox(value);
|
||||||
|
|
||||||
|
Internal.MemCpy(&data, rawValue, primitiveType.GetSize());
|
||||||
|
|
||||||
|
String nameCopy = new String(name);
|
||||||
|
_ownedString.Add(nameCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
String nameCopy = new String(name);
|
||||||
|
_ownedString.Add(nameCopy);
|
||||||
|
|
||||||
|
Fields.Add(nameCopy, (primitiveType, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
typealias SerializeMethod = function MonoObject*(MonoObject* entity, void* contextPtr, MonoException** exception);
|
||||||
|
typealias DeserializeMethod = function MonoObject*(MonoObject* entity, void* contextPtr, MonoException** exception);
|
||||||
|
|
||||||
|
public void Serialize(ScriptInstance scriptInstance)
|
||||||
|
{
|
||||||
|
SerializeMethod serialize = (SerializeMethod)ScriptEngine.Classes.EntitySerializer.GetMethodThunk("Serialize", 2);
|
||||||
|
|
||||||
|
void* thisPtr = Internal.UnsafeCastToPtr(this);
|
||||||
|
|
||||||
|
MonoException* exception = null;
|
||||||
|
serialize(scriptInstance.[Friend]_instance, thisPtr, &exception);
|
||||||
|
|
||||||
|
if (exception != null)
|
||||||
|
ScriptEngine.[Friend]HandleMonoException(exception, scriptInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Deserialize(ScriptInstance scriptInstance)
|
||||||
|
{
|
||||||
|
DeserializeMethod deserialize = (DeserializeMethod)ScriptEngine.Classes.EntitySerializer.GetMethodThunk("Serialize", 2);
|
||||||
|
|
||||||
|
void* thisPtr = Internal.UnsafeCastToPtr(this);
|
||||||
|
|
||||||
|
MonoException* exception = null;
|
||||||
|
deserialize(scriptInstance.[Friend]_instance, thisPtr, &exception);
|
||||||
|
|
||||||
|
if (exception != null)
|
||||||
|
ScriptEngine.[Friend]HandleMonoException(exception, scriptInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using GlitchyEngine.Core;
|
using GlitchyEngine.Core;
|
||||||
using GlitchyEngine.Math;
|
using GlitchyEngine.Math;
|
||||||
|
using GlitchyEngine.Serialization;
|
||||||
|
|
||||||
namespace GlitchyEngine;
|
namespace GlitchyEngine;
|
||||||
|
|
||||||
@@ -135,4 +136,14 @@ internal static class ScriptGlue
|
|||||||
internal static extern bool Application_IsInPlayMode();
|
internal static extern bool Application_IsInPlayMode();
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Serialization
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
|
internal static extern void Serialization_SerializeField(IntPtr serializationContext, SerializationType type, string name, object value);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
|
internal static extern void Serialization_CreateObject(IntPtr currentContext, out IntPtr context, out UUID id);
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,251 @@ using System.Reflection;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using GlitchyEngine.Core;
|
using GlitchyEngine.Core;
|
||||||
using GlitchyEngine.Extensions;
|
using GlitchyEngine.Extensions;
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace GlitchyEngine.Serialization;
|
namespace GlitchyEngine.Serialization;
|
||||||
|
|
||||||
|
public enum SerializationType : int
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
|
||||||
|
Bool,
|
||||||
|
|
||||||
|
Char,
|
||||||
|
String,
|
||||||
|
|
||||||
|
Int8,
|
||||||
|
Int16,
|
||||||
|
Int32,
|
||||||
|
Int64,
|
||||||
|
UInt8,
|
||||||
|
UInt16,
|
||||||
|
UInt32,
|
||||||
|
UInt64,
|
||||||
|
|
||||||
|
Float,
|
||||||
|
Double,
|
||||||
|
Decimal,
|
||||||
|
|
||||||
|
Enum,
|
||||||
|
|
||||||
|
EntityReference,
|
||||||
|
ComponentReference,
|
||||||
|
|
||||||
|
ObjectReference
|
||||||
|
}
|
||||||
|
|
||||||
public static class EntitySerializer
|
public static class EntitySerializer
|
||||||
{
|
{
|
||||||
|
public class SerializedObject
|
||||||
|
{
|
||||||
|
private IntPtr _internalContext;
|
||||||
|
|
||||||
|
private UUID _id;
|
||||||
|
|
||||||
|
private Stack<string> _structScope = new();
|
||||||
|
|
||||||
|
private string _structScopeName;
|
||||||
|
|
||||||
|
public Dictionary<object, SerializedObject> SerializedClasses;
|
||||||
|
|
||||||
|
public SerializedObject(IntPtr internalContext, UUID id, Dictionary<object, SerializedObject> serializedClasses)
|
||||||
|
{
|
||||||
|
_internalContext = internalContext;
|
||||||
|
_id = id;
|
||||||
|
SerializedClasses = serializedClasses;
|
||||||
|
}
|
||||||
|
|
||||||
|
private (SerializedObject context, bool newContext) GetSerializedObject(object o)
|
||||||
|
{
|
||||||
|
SerializedObject context;
|
||||||
|
|
||||||
|
if (SerializedClasses.TryGetValue(o, out context))
|
||||||
|
return (context, false);
|
||||||
|
|
||||||
|
ScriptGlue.Serialization_CreateObject(_internalContext, out IntPtr contextPtr, out UUID id);
|
||||||
|
|
||||||
|
context = new SerializedObject(contextPtr, id, SerializedClasses);
|
||||||
|
|
||||||
|
SerializedClasses.Add(o, context);
|
||||||
|
|
||||||
|
return (context, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PushScope(string name)
|
||||||
|
{
|
||||||
|
_structScope.Push(name);
|
||||||
|
|
||||||
|
_structScopeName += $"{name}.";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopScope()
|
||||||
|
{
|
||||||
|
string scopeToRemove = _structScope.Pop();
|
||||||
|
_structScopeName.Remove(_structScopeName.Length - scopeToRemove.Length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddField(string fieldName, SerializationType serializationType, object value)
|
||||||
|
{
|
||||||
|
string completeFieldName = $"{_structScopeName}{fieldName}";
|
||||||
|
|
||||||
|
ScriptGlue.Serialization_SerializeField(_internalContext, serializationType, completeFieldName, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Serialize(Entity entity)
|
||||||
|
{
|
||||||
|
SerializeFields(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SerializeFields(object obj)
|
||||||
|
{
|
||||||
|
Type type = obj.GetType();
|
||||||
|
|
||||||
|
foreach (FieldInfo field in type.GetFields())
|
||||||
|
{
|
||||||
|
if (!EntitySerializer.SerializeField(field))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
object fieldValue = field.GetValue(obj);
|
||||||
|
Type fieldType = fieldValue?.GetType() ?? field.FieldType;
|
||||||
|
|
||||||
|
SerializeField(field.Name, fieldValue, fieldType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SerializeField(string fieldName, object fieldValue, Type fieldType)
|
||||||
|
{
|
||||||
|
if (fieldType.IsPrimitive)
|
||||||
|
{
|
||||||
|
SerializePrimitive(fieldName, fieldValue, fieldType);
|
||||||
|
}
|
||||||
|
else if (fieldType == typeof(string))
|
||||||
|
{
|
||||||
|
AddField(fieldName, SerializationType.String, fieldValue.ToString());
|
||||||
|
}
|
||||||
|
else if (fieldType.IsEnum)
|
||||||
|
{
|
||||||
|
SerializeEnum(fieldName, fieldValue, fieldType);
|
||||||
|
}
|
||||||
|
else if (fieldType.IsArray)
|
||||||
|
{
|
||||||
|
Log.Error($"Array serialization not yet implemented");
|
||||||
|
}
|
||||||
|
else if (fieldType.IsGenericType)
|
||||||
|
{
|
||||||
|
if (fieldType.GetGenericTypeDefinition() == typeof(List<>))
|
||||||
|
{
|
||||||
|
//SerializeList(fieldName, type, o);
|
||||||
|
Log.Error($"List serialization not yet implemented");
|
||||||
|
}
|
||||||
|
//else if (fieldType.GetGenericTypeDefinition() == typeof(Dictionary<,>))
|
||||||
|
//{
|
||||||
|
// ImGui.Text($"{fieldName} Dictionary");
|
||||||
|
//}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: what to do?
|
||||||
|
Log.Error($"Generic class serialization not yet implemented");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (fieldType.IsValueType)
|
||||||
|
{
|
||||||
|
SerializeStruct(fieldName, fieldValue, fieldType);
|
||||||
|
}
|
||||||
|
else if (fieldType.IsClass)
|
||||||
|
{
|
||||||
|
SerializeClass(fieldName, fieldValue, fieldType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error($"Encountered unhandled type \"{fieldType}\" while serializing.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SerializePrimitive(string fieldName, object fieldValue, Type fieldType)
|
||||||
|
{
|
||||||
|
Debug.Assert(fieldType.IsPrimitive, $"{fieldType} is not a primitive type.");
|
||||||
|
|
||||||
|
SerializationType type = SerializationType.None;
|
||||||
|
|
||||||
|
if (fieldType == typeof(bool))
|
||||||
|
type = SerializationType.Bool;
|
||||||
|
else if (fieldType == typeof(char))
|
||||||
|
type = SerializationType.Char;
|
||||||
|
else if (fieldType == typeof(byte))
|
||||||
|
type = SerializationType.UInt8;
|
||||||
|
else if (fieldType == typeof(sbyte))
|
||||||
|
type = SerializationType.Int8;
|
||||||
|
else if (fieldType == typeof(ushort))
|
||||||
|
type = SerializationType.UInt16;
|
||||||
|
else if (fieldType == typeof(short))
|
||||||
|
type = SerializationType.Int16;
|
||||||
|
else if (fieldType == typeof(uint))
|
||||||
|
type = SerializationType.UInt32;
|
||||||
|
else if (fieldType == typeof(int))
|
||||||
|
type = SerializationType.Int32;
|
||||||
|
else if (fieldType == typeof(ulong))
|
||||||
|
type = SerializationType.UInt64;
|
||||||
|
else if (fieldType == typeof(long))
|
||||||
|
type = SerializationType.Int64;
|
||||||
|
else if (fieldType == typeof(float))
|
||||||
|
type = SerializationType.Float;
|
||||||
|
else if (fieldType == typeof(double))
|
||||||
|
type = SerializationType.Double;
|
||||||
|
else if (fieldType == typeof(decimal))
|
||||||
|
type = SerializationType.Decimal;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Error($"The primitive {fieldType} is not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
AddField(fieldName, type, fieldValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SerializeEnum(string fieldName, object fieldValue, Type fieldType)
|
||||||
|
{
|
||||||
|
AddField(fieldName, SerializationType.Enum, fieldValue.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SerializeStruct(string fieldName, object fieldValue, Type fieldType)
|
||||||
|
{
|
||||||
|
PushScope(fieldName);
|
||||||
|
|
||||||
|
SerializeFields(fieldValue);
|
||||||
|
|
||||||
|
PopScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SerializeClass(string fieldName, object fieldValue, Type fieldType)
|
||||||
|
{
|
||||||
|
if (typeof(Entity).IsAssignableFrom(fieldType))
|
||||||
|
{
|
||||||
|
AddField(fieldName, SerializationType.EntityReference, ((Entity)fieldValue)?.UUID ?? UUID.Zero);
|
||||||
|
}
|
||||||
|
else if (typeof(Component).IsAssignableFrom(fieldType))
|
||||||
|
{
|
||||||
|
AddField(fieldName, SerializationType.ComponentReference, ((Component)fieldValue)?.UUID ?? UUID.Zero);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (fieldValue == null)
|
||||||
|
{
|
||||||
|
AddField(fieldName, SerializationType.ObjectReference, UUID.Zero);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var (context, newContext) = GetSerializedObject(fieldValue);
|
||||||
|
|
||||||
|
if (newContext)
|
||||||
|
{
|
||||||
|
context.SerializeFields(fieldValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddField(fieldName, SerializationType.ObjectReference, context._id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class SerializationContext
|
public class SerializationContext
|
||||||
{
|
{
|
||||||
StringBuilder _builder = new();
|
StringBuilder _builder = new();
|
||||||
@@ -257,11 +496,17 @@ public static class EntitySerializer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Serialize(Entity entity, SerializationContext context)
|
//public static void Serialize(Entity entity, SerializationContext context)
|
||||||
{
|
//{
|
||||||
context ??= new SerializationContext();
|
// context ??= new SerializationContext();
|
||||||
|
|
||||||
context.Serialize($"Entity: {entity.UUID}", typeof(Entity), entity, false);
|
// context.Serialize($"Entity: {entity.UUID}", typeof(Entity), entity, false);
|
||||||
|
//}
|
||||||
|
|
||||||
|
public static void Serialize(Entity entity, IntPtr internalContext)
|
||||||
|
{
|
||||||
|
SerializedObject obj = new SerializedObject(internalContext, UUID.Zero, new Dictionary<object, SerializedObject>());
|
||||||
|
obj.Serialize(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool SerializeField(FieldInfo fieldInfo)
|
public static bool SerializeField(FieldInfo fieldInfo)
|
||||||
|
|||||||
Reference in New Issue
Block a user