From 868047e650e6d1c0d8126977a486a5e974003354 Mon Sep 17 00:00:00 2001 From: Evgeny Prikazchikov Date: Wed, 1 May 2024 16:59:11 +0300 Subject: [PATCH] Editor: Re-import of prefab could lead to a crash #761 --- engine/includes/resources/prefab.h | 4 ++++ engine/src/components/actor.cpp | 1 + engine/src/resources/prefab.cpp | 30 ++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/engine/includes/resources/prefab.h b/engine/includes/resources/prefab.h index 80bde9258..488b638f1 100644 --- a/engine/includes/resources/prefab.h +++ b/engine/includes/resources/prefab.h @@ -19,6 +19,10 @@ class ENGINE_EXPORT Prefab : public Resource { Actor *actor() const; void setActor(Actor *actor); +private: + void loadUserData(const VariantMap &data) override; + VariantMap saveUserData() const override; + private: friend class ActorTest; diff --git a/engine/src/components/actor.cpp b/engine/src/components/actor.cpp index db55c9e01..781473054 100644 --- a/engine/src/components/actor.cpp +++ b/engine/src/components/actor.cpp @@ -689,6 +689,7 @@ void Actor::prefabUpdated(int state, void *ptr) { p->m_data = p->saveUserData(); } break; case Resource::Ready: { + p->m_transform = nullptr; Object::ObjectList prefabObjects; Object::enumObjects(p->m_prefab->actor(), prefabObjects); diff --git a/engine/src/resources/prefab.cpp b/engine/src/resources/prefab.cpp index e91ba8e3e..79c62acd7 100644 --- a/engine/src/resources/prefab.cpp +++ b/engine/src/resources/prefab.cpp @@ -2,6 +2,10 @@ #include +namespace { + const char *gActor("Actor"); +}; + /*! \class Prefab \brief A small piece of objects hierarchy which can be placed on the scene. @@ -37,3 +41,29 @@ void Prefab::setActor(Actor *actor) { m_actor->setParent(this); } } + +/*! + \internal +*/ +void Prefab::loadUserData(const VariantMap &data) { + Resource::loadUserData(data); + + auto it = data.find(gActor); + if(it != data.end()) { + uint32_t uuid = uint32_t((*it).second.toInt()); + Object *object = Engine::findObject(uuid, Engine::findRoot(this)); + setActor(dynamic_cast(object)); + } +} +/*! + \internal +*/ +VariantMap Prefab::saveUserData() const { + VariantMap result(Resource::saveUserData()); + + if(m_actor) { + result[gActor] = int(m_actor->uuid()); + } + + return result; +}