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:
@@ -65,6 +65,9 @@ class EngineClasses
|
||||
|
||||
public ScriptClass EntityEditor => s_EntityEditor;
|
||||
|
||||
public ScriptClass EntitySerializer => s_EntitySerializer;
|
||||
//public ScriptClass SerializationContext => s_SerializationContext;
|
||||
|
||||
internal void ReleaseAndNullify()
|
||||
{
|
||||
ReleaseRefAndNullify!(s_EngineObject);
|
||||
@@ -87,6 +90,9 @@ class EngineClasses
|
||||
|
||||
// Editor classes
|
||||
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
|
||||
public static void SerializeScriptInstances(String output)
|
||||
public static void SerializeScriptInstances(Dictionary<UUID, SerializedObject> allObjects)
|
||||
{
|
||||
ScriptInstanceSerializer serializer = scope .();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user