Refactor Variant type ManagedObject serialization to be usable for Visual Scripting
This commit is contained in:
@@ -279,7 +279,16 @@ namespace FlaxEngine.Json
|
||||
cache.MemoryStream.Initialize(jsonBuffer, jsonLength);
|
||||
cache.Reader.DiscardBufferedData();
|
||||
var jsonReader = new JsonTextReader(cache.Reader);
|
||||
cache.JsonSerializer.Populate(jsonReader, input);
|
||||
if (*jsonBuffer != (byte)'{' && input is LocalizedString asLocalizedString)
|
||||
{
|
||||
// Hack for objects that are serialized into sth different thant "{..}" (eg. LocalizedString can be saved as plain string if not using localization)
|
||||
asLocalizedString.Id = null;
|
||||
asLocalizedString.Value = jsonReader.ReadAsString();
|
||||
}
|
||||
else
|
||||
{
|
||||
cache.JsonSerializer.Populate(jsonReader, input);
|
||||
}
|
||||
|
||||
if (!cache.JsonSerializer.CheckAdditionalContent)
|
||||
return;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Serialization.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Types/Version.h"
|
||||
#include "Engine/Core/Types/Variant.h"
|
||||
#include "Engine/Core/Types/DateTime.h"
|
||||
@@ -20,7 +21,12 @@
|
||||
#include "Engine/Core/Math/Color.h"
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
#include "Engine/Core/Math/Matrix.h"
|
||||
#include "Engine/Scripting/ManagedSerialization.h"
|
||||
#include "Engine/Scripting/ManagedCLR/MUtils.h"
|
||||
#include "Engine/Utilities/Encryption.h"
|
||||
#if USE_MONO
|
||||
#include <ThirdParty/mono-2.0/mono/metadata/object.h>
|
||||
#endif
|
||||
|
||||
void ISerializable::DeserializeIfExists(DeserializeStream& stream, const char* memberName, ISerializeModifier* modifier)
|
||||
{
|
||||
@@ -99,7 +105,6 @@ void Serialization::Serialize(ISerializable::SerializeStream& stream, const Vari
|
||||
{
|
||||
case VariantType::Null:
|
||||
case VariantType::Void:
|
||||
case VariantType::ManagedObject:
|
||||
stream.StartObject();
|
||||
stream.EndObject();
|
||||
break;
|
||||
@@ -201,6 +206,9 @@ void Serialization::Serialize(ISerializable::SerializeStream& stream, const Vari
|
||||
else
|
||||
stream.String("", 0);
|
||||
break;
|
||||
case VariantType::ManagedObject:
|
||||
ManagedSerialization::Serialize(stream, (MonoObject*)v);
|
||||
break;
|
||||
default:
|
||||
Platform::CheckFailed("", __FILE__, __LINE__);
|
||||
stream.StartObject();
|
||||
@@ -217,7 +225,7 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Varian
|
||||
return;
|
||||
VariantType type;
|
||||
Deserialize(mType->value, type, modifier);
|
||||
v.SetType(type);
|
||||
v.SetType(MoveTemp(type));
|
||||
|
||||
const auto mValue = SERIALIZE_FIND_MEMBER(stream, "Value");
|
||||
if (mValue == stream.MemberEnd())
|
||||
@@ -228,7 +236,6 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Varian
|
||||
{
|
||||
case VariantType::Null:
|
||||
case VariantType::Void:
|
||||
case VariantType::ManagedObject:
|
||||
break;
|
||||
case VariantType::Bool:
|
||||
v.AsBool = value.GetBool();
|
||||
@@ -330,6 +337,30 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Varian
|
||||
CHECK(value.IsString());
|
||||
v.SetTypename(value.GetStringAnsiView());
|
||||
break;
|
||||
case VariantType::ManagedObject:
|
||||
{
|
||||
auto obj = (MonoObject*)v;
|
||||
if (!obj && v.Type.TypeName)
|
||||
{
|
||||
MonoClass* klass = MUtils::GetClass(v.Type);
|
||||
if (!klass)
|
||||
{
|
||||
LOG(Error, "Invalid variant type {0}", v.Type);
|
||||
return;
|
||||
}
|
||||
obj = mono_object_new(mono_domain_get(), klass);
|
||||
if (!obj)
|
||||
{
|
||||
LOG(Error, "Failed to managed instance of the variant type {0}", v.Type);
|
||||
return;
|
||||
}
|
||||
if (!mono_class_is_valuetype(klass))
|
||||
mono_runtime_object_init(obj);
|
||||
v.SetManagedObject(obj);
|
||||
}
|
||||
ManagedSerialization::Deserialize(value, obj);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Platform::CheckFailed("", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,18 @@
|
||||
|
||||
#include "ReadStream.h"
|
||||
#include "WriteStream.h"
|
||||
#include "JsonWriters.h"
|
||||
#include "Engine/Core/Types/CommonValue.h"
|
||||
#include "Engine/Core/Types/Variant.h"
|
||||
#include "Engine/Core/Collections/Dictionary.h"
|
||||
#include "Engine/Content/Asset.h"
|
||||
#include "Engine/Debug/DebugLog.h"
|
||||
#include "Engine/Scripting/ManagedSerialization.h"
|
||||
#include "Engine/Scripting/Scripting.h"
|
||||
#include "Engine/Scripting/ScriptingObject.h"
|
||||
#include "Engine/Scripting/ScriptingObjectReference.h"
|
||||
#include "Engine/Scripting/ManagedCLR/MCore.h"
|
||||
#include "Engine/Scripting/ManagedCLR/MUtils.h"
|
||||
|
||||
void ReadStream::ReadStringAnsi(StringAnsi* data)
|
||||
{
|
||||
@@ -269,7 +274,6 @@ void ReadStream::ReadVariant(Variant* data)
|
||||
{
|
||||
case VariantType::Null:
|
||||
case VariantType::Void:
|
||||
case VariantType::ManagedObject:
|
||||
break;
|
||||
case VariantType::Bool:
|
||||
data->AsBool = ReadBool();
|
||||
@@ -335,6 +339,42 @@ void ReadStream::ReadVariant(Variant* data)
|
||||
data->SetObject(FindObject(id, ScriptingObject::GetStaticClass()));
|
||||
break;
|
||||
}
|
||||
case VariantType::ManagedObject:
|
||||
{
|
||||
const byte format = ReadByte();
|
||||
if (format == 0)
|
||||
{
|
||||
// No data
|
||||
}
|
||||
else if (format == 1)
|
||||
{
|
||||
// Json
|
||||
StringAnsi json;
|
||||
ReadStringAnsi(&json, -71);
|
||||
MCore::AttachThread();
|
||||
MonoClass* klass = MUtils::GetClass(data->Type);
|
||||
if (!klass)
|
||||
{
|
||||
LOG(Error, "Invalid variant type {0}", data->Type);
|
||||
return;
|
||||
}
|
||||
MonoObject* obj = mono_object_new(mono_domain_get(), klass);
|
||||
if (!obj)
|
||||
{
|
||||
LOG(Error, "Failed to managed instance of the variant type {0}", data->Type);
|
||||
return;
|
||||
}
|
||||
if (!mono_class_is_valuetype(klass))
|
||||
mono_runtime_object_init(obj);
|
||||
ManagedSerialization::Deserialize(json, obj);
|
||||
data->SetManagedObject(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(Error, "Invalid Variant {0) format {1}", data->Type.ToString(), format);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VariantType::Structure:
|
||||
{
|
||||
int32 length;
|
||||
@@ -572,7 +612,6 @@ void WriteStream::WriteVariant(const Variant& data)
|
||||
{
|
||||
case VariantType::Null:
|
||||
case VariantType::Void:
|
||||
case VariantType::ManagedObject:
|
||||
break;
|
||||
case VariantType::Bool:
|
||||
WriteBool(data.AsBool);
|
||||
@@ -674,6 +713,25 @@ void WriteStream::WriteVariant(const Variant& data)
|
||||
case VariantType::Typename:
|
||||
WriteStringAnsi((StringAnsiView)data, -14);
|
||||
break;
|
||||
case VariantType::ManagedObject:
|
||||
{
|
||||
MonoObject* obj = (MonoObject*)data;
|
||||
if (obj)
|
||||
{
|
||||
WriteByte(1);
|
||||
rapidjson_flax::StringBuffer json;
|
||||
CompactJsonWriter writerObj(json);
|
||||
MCore::AttachThread();
|
||||
ManagedSerialization::Serialize(writerObj, obj);
|
||||
WriteStringAnsi(StringAnsiView(json.GetString(), (int32)json.GetSize()), -71);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteByte(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CRASH;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user