Add SerializableScriptingObject for easier serialization of scripting objects in gameplay or content

This commit is contained in:
Wojtek Figat
2023-08-04 10:11:58 +02:00
parent cab1d8cac4
commit b5fa5fa68e
5 changed files with 92 additions and 77 deletions

View File

@@ -1,6 +1,7 @@
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#include "ScriptingObject.h"
#include "SerializableScriptingObject.h"
#include "Scripting.h"
#include "BinaryModule.h"
#include "Engine/Level/Actor.h"
@@ -10,12 +11,14 @@
#include "Engine/Content/Content.h"
#include "Engine/Profiler/ProfilerCPU.h"
#include "Engine/Threading/ThreadLocal.h"
#include "Engine/Serialization/SerializationFwd.h"
#include "ManagedCLR/MAssembly.h"
#include "ManagedCLR/MClass.h"
#include "ManagedCLR/MUtils.h"
#include "ManagedCLR/MField.h"
#include "ManagedCLR/MCore.h"
#include "Internal/InternalCalls.h"
#include "Internal/ManagedSerialization.h"
#include "FlaxEngine.Gen.h"
#define ScriptingObject_unmanagedPtr "__unmanagedPtr"
@@ -24,6 +27,64 @@
// TODO: don't leak memory (use some kind of late manual GC for those wrapper objects)
Dictionary<ScriptingObject*, void*> ScriptingObjectsInterfaceWrappers;
SerializableScriptingObject::SerializableScriptingObject(const SpawnParams& params)
: ScriptingObject(params)
{
}
void SerializableScriptingObject::Serialize(SerializeStream& stream, const void* otherObj)
{
SERIALIZE_GET_OTHER_OBJ(SerializableScriptingObject);
#if !COMPILE_WITHOUT_CSHARP
// Handle C# objects data serialization
if (EnumHasAnyFlags(Flags, ObjectFlags::IsManagedType))
{
stream.JKEY("V");
if (other)
{
ManagedSerialization::SerializeDiff(stream, GetOrCreateManagedInstance(), other->GetOrCreateManagedInstance());
}
else
{
ManagedSerialization::Serialize(stream, GetOrCreateManagedInstance());
}
}
#endif
// Handle custom scripting objects data serialization
if (EnumHasAnyFlags(Flags, ObjectFlags::IsCustomScriptingType))
{
stream.JKEY("D");
_type.Module->SerializeObject(stream, this, other);
}
}
void SerializableScriptingObject::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
{
#if !COMPILE_WITHOUT_CSHARP
// Handle C# objects data serialization
if (EnumHasAnyFlags(Flags, ObjectFlags::IsManagedType))
{
auto* const v = SERIALIZE_FIND_MEMBER(stream, "V");
if (v != stream.MemberEnd() && v->value.IsObject() && v->value.MemberCount() != 0)
{
ManagedSerialization::Deserialize(v->value, GetOrCreateManagedInstance());
}
}
#endif
// Handle custom scripting objects data serialization
if (EnumHasAnyFlags(Flags, ObjectFlags::IsCustomScriptingType))
{
auto* const v = SERIALIZE_FIND_MEMBER(stream, "D");
if (v != stream.MemberEnd() && v->value.IsObject() && v->value.MemberCount() != 0)
{
_type.Module->DeserializeObject(v->value, this, modifier);
}
}
}
ScriptingObject::ScriptingObject(const SpawnParams& params)
: _gcHandle(0)
, _type(params.Type)