Increase size to 40 bytes to store Double3 without allocations Change Ray and BoundingBox to be stored inlined in BoundingBox Use safer accessors to read Variant explicit data type
789 lines
27 KiB
C++
789 lines
27 KiB
C++
// Copyright (c) 2012-2022 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"
|
|
#include "Engine/Core/Types/TimeSpan.h"
|
|
#include "Engine/Core/Math/Ray.h"
|
|
#include "Engine/Core/Math/Vector2.h"
|
|
#include "Engine/Core/Math/Vector3.h"
|
|
#include "Engine/Core/Math/Vector4.h"
|
|
#include "Engine/Core/Math/Double2.h"
|
|
#include "Engine/Core/Math/Double3.h"
|
|
#include "Engine/Core/Math/Double4.h"
|
|
#include "Engine/Core/Math/Quaternion.h"
|
|
#include "Engine/Core/Math/BoundingBox.h"
|
|
#include "Engine/Core/Math/BoundingSphere.h"
|
|
#include "Engine/Core/Math/Rectangle.h"
|
|
#include "Engine/Core/Math/Transform.h"
|
|
#include "Engine/Core/Math/Int2.h"
|
|
#include "Engine/Core/Math/Int3.h"
|
|
#include "Engine/Core/Math/Int4.h"
|
|
#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/Scripting/ScriptingObjectReference.h"
|
|
#include "Engine/Content/Asset.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)
|
|
{
|
|
auto member = stream.FindMember(memberName);
|
|
if (member != stream.MemberEnd())
|
|
Deserialize(member->value, modifier);
|
|
}
|
|
|
|
#define DESERIALIZE_HELPER(stream, name, var, defaultValue) \
|
|
{ \
|
|
const auto m = SERIALIZE_FIND_MEMBER(stream, name); \
|
|
if (m != stream.MemberEnd()) \
|
|
Deserialize(m->value, var, modifier); \
|
|
else \
|
|
var = defaultValue;\
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const VariantType& v, const void* otherObj)
|
|
{
|
|
return !otherObj || v != *(VariantType*)otherObj;
|
|
}
|
|
|
|
void Serialization::Serialize(ISerializable::SerializeStream& stream, const VariantType& v, const void* otherObj)
|
|
{
|
|
if (v.TypeName == nullptr)
|
|
{
|
|
stream.Int(static_cast<int32>(v.Type));
|
|
}
|
|
else
|
|
{
|
|
stream.StartObject();
|
|
|
|
stream.JKEY("Type");
|
|
stream.Int(static_cast<int32>(v.Type));
|
|
|
|
stream.JKEY("TypeName");
|
|
stream.String(v.TypeName);
|
|
|
|
stream.EndObject();
|
|
}
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, VariantType& v, ISerializeModifier* modifier)
|
|
{
|
|
if (stream.IsObject())
|
|
{
|
|
const auto mType = SERIALIZE_FIND_MEMBER(stream, "Type");
|
|
if (mType != stream.MemberEnd())
|
|
v.Type = (VariantType::Types)mType->value.GetInt();
|
|
else
|
|
v.Type = VariantType::Null;
|
|
const auto mTypeName = SERIALIZE_FIND_MEMBER(stream, "TypeName");
|
|
if (mTypeName != stream.MemberEnd() && mTypeName->value.IsString())
|
|
v.SetTypeName(StringAnsiView(mTypeName->value.GetStringAnsiView()));
|
|
}
|
|
else
|
|
{
|
|
v.Type = (VariantType::Types)stream.GetInt();
|
|
}
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Variant& v, const void* otherObj)
|
|
{
|
|
return !otherObj || v != *(Variant*)otherObj;
|
|
}
|
|
|
|
void Serialization::Serialize(ISerializable::SerializeStream& stream, const Variant& v, const void* otherObj)
|
|
{
|
|
stream.StartObject();
|
|
|
|
stream.JKEY("Type");
|
|
Serialize(stream, v.Type, nullptr);
|
|
|
|
stream.JKEY("Value");
|
|
switch (v.Type.Type)
|
|
{
|
|
case VariantType::Null:
|
|
case VariantType::Void:
|
|
stream.StartObject();
|
|
stream.EndObject();
|
|
break;
|
|
case VariantType::Bool:
|
|
stream.Bool(v.AsBool);
|
|
break;
|
|
case VariantType::Int:
|
|
stream.Int(v.AsInt);
|
|
break;
|
|
case VariantType::Uint:
|
|
stream.Uint(v.AsUint);
|
|
break;
|
|
case VariantType::Int64:
|
|
stream.Int64(v.AsInt64);
|
|
break;
|
|
case VariantType::Uint64:
|
|
case VariantType::Enum:
|
|
stream.Uint64(v.AsUint64);
|
|
break;
|
|
case VariantType::Float:
|
|
stream.Float(v.AsFloat);
|
|
break;
|
|
case VariantType::Double:
|
|
stream.Double(v.AsDouble);
|
|
break;
|
|
case VariantType::Pointer:
|
|
stream.Uint64((uint64)(uintptr)v.AsPointer);
|
|
break;
|
|
case VariantType::String:
|
|
if (v.AsBlob.Data)
|
|
stream.String((const Char*)v.AsBlob.Data, v.AsBlob.Length / sizeof(Char) - 1);
|
|
else
|
|
stream.String("", 0);
|
|
break;
|
|
case VariantType::Blob:
|
|
stream.Blob(v.AsBlob.Data, v.AsBlob.Length);
|
|
break;
|
|
case VariantType::Object:
|
|
stream.Guid(v.AsObject ? v.AsObject->GetID() : Guid::Empty);
|
|
break;
|
|
case VariantType::Asset:
|
|
stream.Guid(v.AsAsset ? v.AsAsset->GetID() : Guid::Empty);
|
|
break;
|
|
case VariantType::Vector2:
|
|
stream.Vector2(*(Vector2*)v.AsData);
|
|
break;
|
|
case VariantType::Vector3:
|
|
stream.Vector3(*(Vector3*)v.AsData);
|
|
break;
|
|
case VariantType::Vector4:
|
|
stream.Vector4(*(Vector4*)v.AsData);
|
|
break;
|
|
case VariantType::Double2:
|
|
stream.Double2(v.AsDouble2());
|
|
break;
|
|
case VariantType::Double3:
|
|
stream.Double3(v.AsDouble3());
|
|
break;
|
|
case VariantType::Double4:
|
|
stream.Double4(v.AsDouble4());
|
|
break;
|
|
case VariantType::Int2:
|
|
stream.Int2(v.AsInt2());
|
|
break;
|
|
case VariantType::Int3:
|
|
stream.Int3(v.AsInt3());
|
|
break;
|
|
case VariantType::Int4:
|
|
stream.Int4(v.AsInt4());
|
|
break;
|
|
case VariantType::Color:
|
|
stream.Color(v.AsColor());
|
|
break;
|
|
case VariantType::Guid:
|
|
stream.Guid(v.AsGuid());
|
|
break;
|
|
case VariantType::BoundingSphere:
|
|
stream.BoundingSphere(v.AsBoundingSphere());
|
|
break;
|
|
case VariantType::Quaternion:
|
|
stream.Quaternion(v.AsQuaternion());
|
|
break;
|
|
case VariantType::Rectangle:
|
|
stream.Rectangle(v.AsRectangle());
|
|
break;
|
|
case VariantType::BoundingBox:
|
|
stream.BoundingBox(v.AsBoundingBox());
|
|
break;
|
|
case VariantType::Transform:
|
|
stream.Transform(v.AsTransform());
|
|
break;
|
|
case VariantType::Ray:
|
|
stream.Ray(v.AsRay());
|
|
break;
|
|
case VariantType::Matrix:
|
|
stream.Matrix(v.AsMatrix());
|
|
break;
|
|
case VariantType::Array:
|
|
Serialize(stream, v.AsArray(), nullptr);
|
|
break;
|
|
case VariantType::Dictionary:
|
|
Serialize(stream, *v.AsDictionary, nullptr);
|
|
break;
|
|
case VariantType::Typename:
|
|
if (v.AsBlob.Data)
|
|
stream.String((const char*)v.AsBlob.Data, v.AsBlob.Length - 1);
|
|
else
|
|
stream.String("", 0);
|
|
break;
|
|
case VariantType::ManagedObject:
|
|
case VariantType::Structure:
|
|
{
|
|
#if USE_MONO
|
|
MonoObject* obj;
|
|
if (v.Type.Type == VariantType::Structure)
|
|
obj = MUtils::BoxVariant(v);
|
|
else
|
|
obj = (MonoObject*)v;
|
|
ManagedSerialization::Serialize(stream, obj);
|
|
#endif
|
|
break;
|
|
}
|
|
default:
|
|
Platform::CheckFailed("", __FILE__, __LINE__);
|
|
stream.StartObject();
|
|
stream.EndObject();
|
|
}
|
|
|
|
stream.EndObject();
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Variant& v, ISerializeModifier* modifier)
|
|
{
|
|
const auto mType = SERIALIZE_FIND_MEMBER(stream, "Type");
|
|
if (mType == stream.MemberEnd())
|
|
return;
|
|
VariantType type;
|
|
Deserialize(mType->value, type, modifier);
|
|
v.SetType(MoveTemp(type));
|
|
|
|
const auto mValue = SERIALIZE_FIND_MEMBER(stream, "Value");
|
|
if (mValue == stream.MemberEnd())
|
|
return;
|
|
auto& value = mValue->value;
|
|
Guid id;
|
|
switch (v.Type.Type)
|
|
{
|
|
case VariantType::Null:
|
|
case VariantType::Void:
|
|
break;
|
|
case VariantType::Bool:
|
|
v.AsBool = value.GetBool();
|
|
break;
|
|
case VariantType::Int:
|
|
v.AsInt = value.GetInt();
|
|
break;
|
|
case VariantType::Uint:
|
|
v.AsUint = value.GetUint();
|
|
break;
|
|
case VariantType::Int64:
|
|
v.AsInt64 = value.GetInt64();
|
|
break;
|
|
case VariantType::Uint64:
|
|
case VariantType::Enum:
|
|
v.AsUint64 = value.GetUint64();
|
|
break;
|
|
case VariantType::Float:
|
|
v.AsFloat = value.GetFloat();
|
|
break;
|
|
case VariantType::Double:
|
|
v.AsDouble = value.GetDouble();
|
|
break;
|
|
case VariantType::Pointer:
|
|
v.AsPointer = (void*)(uintptr)value.GetUint64();
|
|
break;
|
|
case VariantType::String:
|
|
CHECK(value.IsString());
|
|
v.SetString(value.GetStringAnsiView());
|
|
break;
|
|
case VariantType::Object:
|
|
Deserialize(value, id, modifier);
|
|
modifier->IdsMapping.TryGet(id, id);
|
|
v.SetObject(FindObject(id, ScriptingObject::GetStaticClass()));
|
|
break;
|
|
case VariantType::Asset:
|
|
Deserialize(value, id, modifier);
|
|
v.SetAsset(LoadAsset(id, Asset::TypeInitializer));
|
|
break;
|
|
case VariantType::Blob:
|
|
CHECK(value.IsString());
|
|
id.A = value.GetStringLength();
|
|
v.SetBlob(id.A);
|
|
Encryption::Base64Decode(value.GetString(), id.A, (byte*)v.AsBlob.Data);
|
|
break;
|
|
case VariantType::Vector2:
|
|
Deserialize(value, *(Vector2*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::Vector3:
|
|
Deserialize(value, *(Vector3*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::Vector4:
|
|
Deserialize(value, *(Vector4*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::Double2:
|
|
Deserialize(value, *(Double2*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::Double3:
|
|
Deserialize(value, *(Double3*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::Double4:
|
|
Deserialize(value, *(Double4*)v.AsBlob.Data, modifier);
|
|
break;
|
|
case VariantType::Int2:
|
|
Deserialize(value, *(Int2*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::Int3:
|
|
Deserialize(value, *(Int3*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::Int4:
|
|
Deserialize(value, *(Int4*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::Color:
|
|
Deserialize(value, *(Color*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::Guid:
|
|
Deserialize(value, *(Guid*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::BoundingSphere:
|
|
Deserialize(value, *(BoundingSphere*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::Quaternion:
|
|
Deserialize(value, *(Quaternion*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::Rectangle:
|
|
Deserialize(value, *(Rectangle*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::BoundingBox:
|
|
Deserialize(value, *(BoundingBox*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::Transform:
|
|
Deserialize(value, *(Transform*)v.AsBlob.Data, modifier);
|
|
break;
|
|
case VariantType::Ray:
|
|
Deserialize(value, *(Ray*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::Matrix:
|
|
Deserialize(value, *(Matrix*)v.AsBlob.Data, modifier);
|
|
break;
|
|
case VariantType::Array:
|
|
Deserialize(value, *(Array<Variant, HeapAllocation>*)v.AsData, modifier);
|
|
break;
|
|
case VariantType::Dictionary:
|
|
Deserialize(value, *v.AsDictionary, modifier);
|
|
break;
|
|
case VariantType::Typename:
|
|
CHECK(value.IsString());
|
|
v.SetTypename(value.GetStringAnsiView());
|
|
break;
|
|
case VariantType::ManagedObject:
|
|
case VariantType::Structure:
|
|
{
|
|
#if USE_MONO
|
|
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);
|
|
if (v.Type.Type == VariantType::ManagedObject)
|
|
v.SetManagedObject(obj);
|
|
}
|
|
ManagedSerialization::Deserialize(value, obj);
|
|
if (v.Type.Type == VariantType::Structure)
|
|
v = MUtils::UnboxVariant(obj);
|
|
#endif
|
|
break;
|
|
}
|
|
default:
|
|
Platform::CheckFailed("", __FILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Guid& v, const void* otherObj)
|
|
{
|
|
return v.IsValid();
|
|
}
|
|
|
|
void Serialization::Serialize(ISerializable::SerializeStream& stream, const Guid& v, const void* otherObj)
|
|
{
|
|
stream.Guid(v);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Guid& v, ISerializeModifier* modifier)
|
|
{
|
|
if (!stream.IsString() || stream.GetStringLength() != 32)
|
|
{
|
|
v = Guid::Empty;
|
|
return;
|
|
}
|
|
const char* a = stream.GetString();
|
|
const char* b = a + 8;
|
|
const char* c = b + 8;
|
|
const char* d = c + 8;
|
|
StringUtils::ParseHex(a, 8, &v.A);
|
|
StringUtils::ParseHex(b, 8, &v.B);
|
|
StringUtils::ParseHex(c, 8, &v.C);
|
|
StringUtils::ParseHex(d, 8, &v.D);
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const DateTime& v, const void* otherObj)
|
|
{
|
|
return !otherObj || v != *(DateTime*)otherObj;
|
|
}
|
|
|
|
void Serialization::Serialize(ISerializable::SerializeStream& stream, const DateTime& v, const void* otherObj)
|
|
{
|
|
stream.DateTime(v);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, DateTime& v, ISerializeModifier* modifier)
|
|
{
|
|
v.Ticks = stream.GetInt64();
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const TimeSpan& v, const void* otherObj)
|
|
{
|
|
return !otherObj || v != *(TimeSpan*)otherObj;
|
|
}
|
|
|
|
void Serialization::Serialize(ISerializable::SerializeStream& stream, const TimeSpan& v, const void* otherObj)
|
|
{
|
|
stream.Int64(v.Ticks);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, TimeSpan& v, ISerializeModifier* modifier)
|
|
{
|
|
v.Ticks = stream.GetInt64();
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Version& v, const void* otherObj)
|
|
{
|
|
return !otherObj || v != *(Version*)otherObj;
|
|
}
|
|
|
|
void Serialization::Serialize(ISerializable::SerializeStream& stream, const Version& v, const void* otherObj)
|
|
{
|
|
stream.String(v.ToString());
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Version& v, ISerializeModifier* modifier)
|
|
{
|
|
if (stream.IsString())
|
|
{
|
|
Version::Parse(stream.GetText(), &v);
|
|
}
|
|
else if (stream.IsObject())
|
|
{
|
|
const auto mMajor = SERIALIZE_FIND_MEMBER(stream, "Major");
|
|
if (mMajor != stream.MemberEnd())
|
|
{
|
|
const auto mMinor = SERIALIZE_FIND_MEMBER(stream, "Minor");
|
|
if (mMinor != stream.MemberEnd())
|
|
{
|
|
const auto mBuild = SERIALIZE_FIND_MEMBER(stream, "Build");
|
|
if (mBuild != stream.MemberEnd())
|
|
{
|
|
const auto mRevision = SERIALIZE_FIND_MEMBER(stream, "mRevision");
|
|
if (mRevision != stream.MemberEnd())
|
|
v = Version(mMajor->value.GetInt(), mMinor->value.GetInt(), mBuild->value.GetInt(), mRevision->value.GetInt());
|
|
else
|
|
v = Version(mMajor->value.GetInt(), mMinor->value.GetInt(), mBuild->value.GetInt());
|
|
}
|
|
else
|
|
v = Version(mMajor->value.GetInt(), mMinor->value.GetInt());
|
|
}
|
|
else
|
|
v = Version(mMajor->value.GetInt(), 0);
|
|
}
|
|
else
|
|
v = Version();
|
|
}
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Vector2& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !Vector2::NearEqual(v, *(Vector2*)otherObj, SERIALIZE_EPSILON);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Vector2& v, ISerializeModifier* modifier)
|
|
{
|
|
const auto mX = SERIALIZE_FIND_MEMBER(stream, "X");
|
|
const auto mY = SERIALIZE_FIND_MEMBER(stream, "Y");
|
|
v.X = mX != stream.MemberEnd() ? mX->value.GetFloat() : 0.0f;
|
|
v.Y = mY != stream.MemberEnd() ? mY->value.GetFloat() : 0.0f;
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Vector3& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !Vector3::NearEqual(v, *(Vector3*)otherObj, SERIALIZE_EPSILON);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Vector3& v, ISerializeModifier* modifier)
|
|
{
|
|
const auto mX = SERIALIZE_FIND_MEMBER(stream, "X");
|
|
const auto mY = SERIALIZE_FIND_MEMBER(stream, "Y");
|
|
const auto mZ = SERIALIZE_FIND_MEMBER(stream, "Z");
|
|
v.X = mX != stream.MemberEnd() ? mX->value.GetFloat() : 0.0f;
|
|
v.Y = mY != stream.MemberEnd() ? mY->value.GetFloat() : 0.0f;
|
|
v.Z = mZ != stream.MemberEnd() ? mZ->value.GetFloat() : 0.0f;
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Vector4& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !Vector4::NearEqual(v, *(Vector4*)otherObj, SERIALIZE_EPSILON);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Vector4& v, ISerializeModifier* modifier)
|
|
{
|
|
const auto mX = SERIALIZE_FIND_MEMBER(stream, "X");
|
|
const auto mY = SERIALIZE_FIND_MEMBER(stream, "Y");
|
|
const auto mZ = SERIALIZE_FIND_MEMBER(stream, "Z");
|
|
const auto mW = SERIALIZE_FIND_MEMBER(stream, "W");
|
|
v.X = mX != stream.MemberEnd() ? mX->value.GetFloat() : 0.0f;
|
|
v.Y = mY != stream.MemberEnd() ? mY->value.GetFloat() : 0.0f;
|
|
v.Z = mZ != stream.MemberEnd() ? mZ->value.GetFloat() : 0.0f;
|
|
v.W = mW != stream.MemberEnd() ? mW->value.GetFloat() : 0.0f;
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Double2& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !Double2::NearEqual(v, *(Double2*)otherObj, SERIALIZE_EPSILON_DOUBLE);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Double2& v, ISerializeModifier* modifier)
|
|
{
|
|
const auto mX = SERIALIZE_FIND_MEMBER(stream, "X");
|
|
const auto mY = SERIALIZE_FIND_MEMBER(stream, "Y");
|
|
v.X = mX != stream.MemberEnd() ? mX->value.GetFloat() : 0.0f;
|
|
v.Y = mY != stream.MemberEnd() ? mY->value.GetFloat() : 0.0f;
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Double3& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !Double3::NearEqual(v, *(Double3*)otherObj, SERIALIZE_EPSILON_DOUBLE);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Double3& v, ISerializeModifier* modifier)
|
|
{
|
|
const auto mX = SERIALIZE_FIND_MEMBER(stream, "X");
|
|
const auto mY = SERIALIZE_FIND_MEMBER(stream, "Y");
|
|
const auto mZ = SERIALIZE_FIND_MEMBER(stream, "Z");
|
|
v.X = mX != stream.MemberEnd() ? mX->value.GetFloat() : 0.0f;
|
|
v.Y = mY != stream.MemberEnd() ? mY->value.GetFloat() : 0.0f;
|
|
v.Z = mZ != stream.MemberEnd() ? mZ->value.GetFloat() : 0.0f;
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Double4& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !Double4::NearEqual(v, *(Double4*)otherObj, SERIALIZE_EPSILON_DOUBLE);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Double4& v, ISerializeModifier* modifier)
|
|
{
|
|
const auto mX = SERIALIZE_FIND_MEMBER(stream, "X");
|
|
const auto mY = SERIALIZE_FIND_MEMBER(stream, "Y");
|
|
const auto mZ = SERIALIZE_FIND_MEMBER(stream, "Z");
|
|
const auto mW = SERIALIZE_FIND_MEMBER(stream, "W");
|
|
v.X = mX != stream.MemberEnd() ? mX->value.GetFloat() : 0.0f;
|
|
v.Y = mY != stream.MemberEnd() ? mY->value.GetFloat() : 0.0f;
|
|
v.Z = mZ != stream.MemberEnd() ? mZ->value.GetFloat() : 0.0f;
|
|
v.W = mW != stream.MemberEnd() ? mW->value.GetFloat() : 0.0f;
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Int2& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !(v == *(Int2*)otherObj);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Int2& v, ISerializeModifier* modifier)
|
|
{
|
|
const auto mX = SERIALIZE_FIND_MEMBER(stream, "X");
|
|
const auto mY = SERIALIZE_FIND_MEMBER(stream, "Y");
|
|
v.X = mX != stream.MemberEnd() ? mX->value.GetInt() : 0;
|
|
v.Y = mY != stream.MemberEnd() ? mY->value.GetInt() : 0;
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Int3& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !(v == *(Int3*)otherObj);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Int3& v, ISerializeModifier* modifier)
|
|
{
|
|
const auto mX = SERIALIZE_FIND_MEMBER(stream, "X");
|
|
const auto mY = SERIALIZE_FIND_MEMBER(stream, "Y");
|
|
const auto mZ = SERIALIZE_FIND_MEMBER(stream, "Z");
|
|
v.X = mX != stream.MemberEnd() ? mX->value.GetInt() : 0;
|
|
v.Y = mY != stream.MemberEnd() ? mY->value.GetInt() : 0;
|
|
v.Z = mZ != stream.MemberEnd() ? mZ->value.GetInt() : 0;
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Int4& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !(v == *(Int4*)otherObj);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Int4& v, ISerializeModifier* modifier)
|
|
{
|
|
const auto mX = SERIALIZE_FIND_MEMBER(stream, "X");
|
|
const auto mY = SERIALIZE_FIND_MEMBER(stream, "Y");
|
|
const auto mZ = SERIALIZE_FIND_MEMBER(stream, "Z");
|
|
const auto mW = SERIALIZE_FIND_MEMBER(stream, "W");
|
|
v.X = mX != stream.MemberEnd() ? mX->value.GetInt() : 0;
|
|
v.Y = mY != stream.MemberEnd() ? mY->value.GetInt() : 0;
|
|
v.Z = mZ != stream.MemberEnd() ? mZ->value.GetInt() : 0;
|
|
v.W = mW != stream.MemberEnd() ? mW->value.GetInt() : 0;
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Quaternion& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !Quaternion::NearEqual(v, *(Quaternion*)otherObj, SERIALIZE_EPSILON);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Quaternion& v, ISerializeModifier* modifier)
|
|
{
|
|
const auto mX = SERIALIZE_FIND_MEMBER(stream, "X");
|
|
const auto mY = SERIALIZE_FIND_MEMBER(stream, "Y");
|
|
const auto mZ = SERIALIZE_FIND_MEMBER(stream, "Z");
|
|
const auto mW = SERIALIZE_FIND_MEMBER(stream, "W");
|
|
v.X = mX != stream.MemberEnd() ? mX->value.GetFloat() : 0.0f;
|
|
v.Y = mY != stream.MemberEnd() ? mY->value.GetFloat() : 0.0f;
|
|
v.Z = mZ != stream.MemberEnd() ? mZ->value.GetFloat() : 0.0f;
|
|
v.W = mW != stream.MemberEnd() ? mW->value.GetFloat() : 0.0f;
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Color& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !Color::NearEqual(v, *(Color*)otherObj, SERIALIZE_EPSILON);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Color& v, ISerializeModifier* modifier)
|
|
{
|
|
const auto mR = SERIALIZE_FIND_MEMBER(stream, "R");
|
|
const auto mG = SERIALIZE_FIND_MEMBER(stream, "G");
|
|
const auto mB = SERIALIZE_FIND_MEMBER(stream, "B");
|
|
const auto mA = SERIALIZE_FIND_MEMBER(stream, "A");
|
|
v.R = mR != stream.MemberEnd() ? mR->value.GetFloat() : 0.0f;
|
|
v.G = mG != stream.MemberEnd() ? mG->value.GetFloat() : 0.0f;
|
|
v.B = mB != stream.MemberEnd() ? mB->value.GetFloat() : 0.0f;
|
|
v.A = mA != stream.MemberEnd() ? mA->value.GetFloat() : 0.0f;
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Color32& v, const void* otherObj)
|
|
{
|
|
return !otherObj || v != *(Color32*)otherObj;
|
|
}
|
|
|
|
void Serialization::Serialize(ISerializable::SerializeStream& stream, const Color32& v, const void* otherObj)
|
|
{
|
|
stream.StartObject();
|
|
stream.JKEY("R");
|
|
stream.Int(v.R);
|
|
stream.JKEY("G");
|
|
stream.Int(v.G);
|
|
stream.JKEY("B");
|
|
stream.Int(v.B);
|
|
stream.JKEY("A");
|
|
stream.Int(v.A);
|
|
stream.EndObject();
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Color32& v, ISerializeModifier* modifier)
|
|
{
|
|
const auto mR = SERIALIZE_FIND_MEMBER(stream, "R");
|
|
const auto mG = SERIALIZE_FIND_MEMBER(stream, "G");
|
|
const auto mB = SERIALIZE_FIND_MEMBER(stream, "B");
|
|
const auto mA = SERIALIZE_FIND_MEMBER(stream, "A");
|
|
v.R = mR != stream.MemberEnd() ? mR->value.GetInt() : 0;
|
|
v.G = mG != stream.MemberEnd() ? mG->value.GetInt() : 0;
|
|
v.B = mB != stream.MemberEnd() ? mB->value.GetInt() : 0;
|
|
v.A = mA != stream.MemberEnd() ? mA->value.GetInt() : 0;
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const BoundingBox& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !BoundingBox::NearEqual(v, *(BoundingBox*)otherObj, SERIALIZE_EPSILON);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, BoundingBox& v, ISerializeModifier* modifier)
|
|
{
|
|
DESERIALIZE_HELPER(stream, "Minimum", v.Minimum, Vector3::Zero);
|
|
DESERIALIZE_HELPER(stream, "Maximum", v.Maximum, Vector3::Zero);
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const BoundingSphere& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !BoundingSphere::NearEqual(v, *(BoundingSphere*)otherObj, SERIALIZE_EPSILON);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, BoundingSphere& v, ISerializeModifier* modifier)
|
|
{
|
|
DESERIALIZE_HELPER(stream, "Center", v.Center, Vector3::Zero);
|
|
DESERIALIZE_HELPER(stream, "Radius", v.Radius, 0.0f);
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Ray& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !Ray::NearEqual(v, *(Ray*)otherObj);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Ray& v, ISerializeModifier* modifier)
|
|
{
|
|
DESERIALIZE_HELPER(stream, "Position", v.Position, Vector3::Zero);
|
|
DESERIALIZE_HELPER(stream, "Direction", v.Direction, Vector3::Zero);
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Rectangle& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !Rectangle::NearEqual(v, *(Rectangle*)otherObj, SERIALIZE_EPSILON);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Rectangle& v, ISerializeModifier* modifier)
|
|
{
|
|
DESERIALIZE_HELPER(stream, "Location", v.Location, Vector2::Zero);
|
|
DESERIALIZE_HELPER(stream, "Size", v.Size, Vector2::Zero);
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Transform& v, const void* otherObj)
|
|
{
|
|
return !otherObj || !Transform::NearEqual(v, *(Transform*)otherObj, SERIALIZE_EPSILON);
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Transform& v, ISerializeModifier* modifier)
|
|
{
|
|
DESERIALIZE_HELPER(stream, "Translation", v.Translation, Vector3::Zero);
|
|
DESERIALIZE_HELPER(stream, "Scale", v.Scale, Vector3::One);
|
|
DESERIALIZE_HELPER(stream, "Orientation", v.Orientation, Quaternion::Identity);
|
|
}
|
|
|
|
bool Serialization::ShouldSerialize(const Matrix& v, const void* otherObj)
|
|
{
|
|
return !otherObj || v != *(Matrix*)otherObj;
|
|
}
|
|
|
|
void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Matrix& v, ISerializeModifier* modifier)
|
|
{
|
|
DESERIALIZE_HELPER(stream, "M11", v.M11, 0);
|
|
DESERIALIZE_HELPER(stream, "M12", v.M12, 0);
|
|
DESERIALIZE_HELPER(stream, "M13", v.M13, 0);
|
|
DESERIALIZE_HELPER(stream, "M14", v.M14, 0);
|
|
DESERIALIZE_HELPER(stream, "M21", v.M21, 0);
|
|
DESERIALIZE_HELPER(stream, "M22", v.M22, 0);
|
|
DESERIALIZE_HELPER(stream, "M23", v.M23, 0);
|
|
DESERIALIZE_HELPER(stream, "M24", v.M24, 0);
|
|
DESERIALIZE_HELPER(stream, "M31", v.M31, 0);
|
|
DESERIALIZE_HELPER(stream, "M32", v.M32, 0);
|
|
DESERIALIZE_HELPER(stream, "M33", v.M33, 0);
|
|
DESERIALIZE_HELPER(stream, "M34", v.M34, 0);
|
|
DESERIALIZE_HELPER(stream, "M41", v.M41, 0);
|
|
DESERIALIZE_HELPER(stream, "M42", v.M42, 0);
|
|
DESERIALIZE_HELPER(stream, "M43", v.M43, 0);
|
|
DESERIALIZE_HELPER(stream, "M44", v.M44, 0);
|
|
}
|
|
|
|
#undef DESERIALIZE_HELPER
|