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); 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; bool result = v != other;
if (result && v && other && v->HasPrefabLink() && other->HasPrefabLink()) 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 // 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) // 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; return result;
} }

View File

@@ -448,15 +448,20 @@ namespace Serialization
// Scripting Object // 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> 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; return !otherObj || v != *(const T**)otherObj;
} }
template<typename T> 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); stream.Guid(v ? v->GetID() : Guid::Empty);
} }
@@ -470,9 +475,9 @@ namespace Serialization
} }
template<typename T> 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 // Scripting Object Reference
@@ -480,7 +485,7 @@ namespace Serialization
template<typename T> template<typename T>
inline bool ShouldSerialize(const ScriptingObjectReference<T>& v, const void* otherObj) 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> template<typename T>
inline void Serialize(ISerializable::SerializeStream& stream, const ScriptingObjectReference<T>& v, const void* otherObj) inline void Serialize(ISerializable::SerializeStream& stream, const ScriptingObjectReference<T>& v, const void* otherObj)
@@ -501,7 +506,7 @@ namespace Serialization
template<typename T> template<typename T>
inline bool ShouldSerialize(const SoftObjectReference<T>& v, const void* otherObj) 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> template<typename T>
inline void Serialize(ISerializable::SerializeStream& stream, const SoftObjectReference<T>& v, const void* otherObj) 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 // Explicit auto-cast for object pointer
#define SERIALIZE_OBJ(name) \ #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); \ stream.JKEY(#name); \
Serialization::Serialize(stream, (const ScriptingObject*&)name, other ? &other->name : nullptr); \ Serialization::Serialize(stream, (const ScriptingObject*&)name, other ? &other->name : nullptr); \