diff --git a/SDK/include/NDK/BaseComponent.hpp b/SDK/include/NDK/BaseComponent.hpp index 8a4d51bfe..e21a1e38f 100644 --- a/SDK/include/NDK/BaseComponent.hpp +++ b/SDK/include/NDK/BaseComponent.hpp @@ -47,6 +47,7 @@ namespace Ndk virtual void OnComponentAttached(BaseComponent& component); virtual void OnComponentDetached(BaseComponent& component); virtual void OnDetached(); + virtual void OnEntityDestruction(); void SetEntity(Entity* entity); diff --git a/SDK/include/NDK/Components/PhysicsComponent2D.hpp b/SDK/include/NDK/Components/PhysicsComponent2D.hpp index 1f4cc63c9..2bbe693a1 100644 --- a/SDK/include/NDK/Components/PhysicsComponent2D.hpp +++ b/SDK/include/NDK/Components/PhysicsComponent2D.hpp @@ -55,6 +55,7 @@ namespace Ndk void OnComponentAttached(BaseComponent& component) override; void OnComponentDetached(BaseComponent& component) override; void OnDetached() override; + void OnEntityDestruction() override; std::unique_ptr m_object; }; diff --git a/SDK/include/NDK/Components/PhysicsComponent3D.hpp b/SDK/include/NDK/Components/PhysicsComponent3D.hpp index f6f13ec09..8be86537e 100644 --- a/SDK/include/NDK/Components/PhysicsComponent3D.hpp +++ b/SDK/include/NDK/Components/PhysicsComponent3D.hpp @@ -62,6 +62,7 @@ namespace Ndk void OnComponentAttached(BaseComponent& component) override; void OnComponentDetached(BaseComponent& component) override; void OnDetached() override; + void OnEntityDestruction() override; std::unique_ptr m_object; }; diff --git a/SDK/include/NDK/Entity.hpp b/SDK/include/NDK/Entity.hpp index ecf9fcc62..e386100f8 100644 --- a/SDK/include/NDK/Entity.hpp +++ b/SDK/include/NDK/Entity.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -65,6 +66,8 @@ namespace Ndk Entity& operator=(const Entity&) = delete; Entity& operator=(Entity&&) = delete; + NazaraSignal(OnEntityDestruction, Entity* /*entity*/); + private: Entity(World* world, EntityId id); diff --git a/SDK/src/NDK/BaseComponent.cpp b/SDK/src/NDK/BaseComponent.cpp index 4af8caed2..204076e54 100644 --- a/SDK/src/NDK/BaseComponent.cpp +++ b/SDK/src/NDK/BaseComponent.cpp @@ -54,6 +54,15 @@ namespace Ndk { } + /*! + * \brief Operation to perform when the entity is destroyed and we're still attached to it + * + * \remark This is always called before the entity proper destruction, and thus its components. + */ + void BaseComponent::OnEntityDestruction() + { + } + std::vector BaseComponent::s_entries; std::unordered_map BaseComponent::s_idToIndex; } diff --git a/SDK/src/NDK/Components/PhysicsComponent2D.cpp b/SDK/src/NDK/Components/PhysicsComponent2D.cpp index b64ee37b5..58cab2982 100644 --- a/SDK/src/NDK/Components/PhysicsComponent2D.cpp +++ b/SDK/src/NDK/Components/PhysicsComponent2D.cpp @@ -88,5 +88,11 @@ namespace Ndk m_object.reset(); } + void PhysicsComponent2D::OnEntityDestruction() + { + // Kill rigidbody before entity destruction to force contact callbacks to be called while the entity is still valid + m_object.reset(); + } + ComponentIndex PhysicsComponent2D::componentIndex; } diff --git a/SDK/src/NDK/Components/PhysicsComponent3D.cpp b/SDK/src/NDK/Components/PhysicsComponent3D.cpp index 2581723a7..e0a22d08f 100644 --- a/SDK/src/NDK/Components/PhysicsComponent3D.cpp +++ b/SDK/src/NDK/Components/PhysicsComponent3D.cpp @@ -88,5 +88,12 @@ namespace Ndk m_object.reset(); } + void PhysicsComponent3D::OnEntityDestruction() + { + // Kill rigid body before entity destruction to force contact callbacks to be called while the entity is still valid + m_object.reset(); + + } + ComponentIndex PhysicsComponent3D::componentIndex; } diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index d88556a31..ae5743163 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -145,6 +145,13 @@ namespace Ndk void Entity::Destroy() { + OnEntityDestruction(this); + OnEntityDestruction.Clear(); + + // We prepare components for entity destruction (some components needs this to handle some final callbacks while the entity is still valid) + for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + m_components[i]->OnEntityDestruction(); + // We alert each system for (std::size_t index = m_systemBits.FindFirst(); index != m_systemBits.npos; index = m_systemBits.FindNext(index)) {