Fix scene object reference serialization in C++ to use correct serializer

#3255
This commit is contained in:
Wojtek Figat
2025-08-30 23:52:54 +02:00
parent 3f7fe635d8
commit 8fdda1a71a
3 changed files with 15 additions and 10 deletions

View File

@@ -790,14 +790,14 @@ void Serialization::Deserialize(ISerializable::DeserializeStream& stream, Matrix
DESERIALIZE_HELPER(stream, "M44", v.M44, 0);
}
bool Serialization::ShouldSerialize(const SceneObject* v, const SceneObject* other)
bool Serialization::ShouldSerializeRef(const SceneObject* v, const SceneObject* other)
{
bool result = v != other;
if (result && v && other && v->HasPrefabLink() && other->HasPrefabLink())
{
// Special case when saving reference to prefab object and the objects are different but the point to the same prefab object
// In that case, skip saving reference as it's defined in prefab (will be populated via IdsMapping during deserialization)
result &= v->GetPrefabObjectID() != other->GetPrefabObjectID();
result = v->GetPrefabObjectID() != other->GetPrefabObjectID();
}
return result;
}

View File

@@ -448,15 +448,20 @@ namespace Serialization
// Scripting Object
FLAXENGINE_API bool ShouldSerialize(const SceneObject* v, const SceneObject* other);
inline bool ShouldSerializeRef(const ScriptingObject* v, const ScriptingObject* other)
{
return v != other;
}
FLAXENGINE_API bool ShouldSerializeRef(const SceneObject* v, const SceneObject* other);
template<typename T>
inline typename TEnableIf<TIsBaseOf<ScriptingObject, T>::Value, bool>::Type ShouldSerialize(const T*& v, const void* otherObj)
inline typename TEnableIf<TAnd<TIsBaseOf<ScriptingObject, T>, TNot<TIsBaseOf<SceneObject, T>>>::Value, bool>::Type ShouldSerialize(const T* v, const void* otherObj)
{
return !otherObj || v != *(const T**)otherObj;
}
template<typename T>
inline typename TEnableIf<TIsBaseOf<ScriptingObject, T>::Value>::Type Serialize(ISerializable::SerializeStream& stream, const T*& v, const void* otherObj)
inline typename TEnableIf<TIsBaseOf<ScriptingObject, T>::Value>::Type Serialize(ISerializable::SerializeStream& stream, const T* v, const void* otherObj)
{
stream.Guid(v ? v->GetID() : Guid::Empty);
}
@@ -470,9 +475,9 @@ namespace Serialization
}
template<typename T>
inline typename TEnableIf<TIsBaseOf<SceneObject, T>::Value, bool>::Type ShouldSerialize(const T*& v, const void* otherObj)
inline typename TEnableIf<TIsBaseOf<SceneObject, T>::Value, bool>::Type ShouldSerialize(const T* v, const void* otherObj)
{
return !otherObj || ShouldSerialize((const SceneObject*)v, *(const SceneObject**)otherObj);
return !otherObj || ShouldSerializeRef((const SceneObject*)v, *(const SceneObject**)otherObj);
}
// Scripting Object Reference
@@ -480,7 +485,7 @@ namespace Serialization
template<typename T>
inline bool ShouldSerialize(const ScriptingObjectReference<T>& v, const void* otherObj)
{
return !otherObj || ShouldSerialize(v.Get(), ((ScriptingObjectReference<T>*)otherObj)->Get());
return !otherObj || ShouldSerializeRef(v.Get(), ((ScriptingObjectReference<T>*)otherObj)->Get());
}
template<typename T>
inline void Serialize(ISerializable::SerializeStream& stream, const ScriptingObjectReference<T>& v, const void* otherObj)
@@ -501,7 +506,7 @@ namespace Serialization
template<typename T>
inline bool ShouldSerialize(const SoftObjectReference<T>& v, const void* otherObj)
{
return !otherObj || ShouldSerialize(v.Get(), ((SoftObjectReference<T>*)otherObj)->Get());
return !otherObj || ShouldSerializeRef(v.Get(), ((SoftObjectReference<T>*)otherObj)->Get());
}
template<typename T>
inline void Serialize(ISerializable::SerializeStream& stream, const SoftObjectReference<T>& v, const void* otherObj)

View File

@@ -80,7 +80,7 @@ class ISerializeModifier;
// Explicit auto-cast for object pointer
#define SERIALIZE_OBJ(name) \
if (Serialization::ShouldSerialize((const ScriptingObject*&)name, other ? &other->name : nullptr)) \
if (Serialization::ShouldSerialize(name, decltype(name)(other ? &other->name : nullptr))) \
{ \
stream.JKEY(#name); \
Serialization::Serialize(stream, (const ScriptingObject*&)name, other ? &other->name : nullptr); \