diff --git a/ChangeLog.md b/ChangeLog.md index 79553a105..f78bd943f 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -63,6 +63,7 @@ Nazara Development Kit: - Add linear and angular damping accessor to PhysicsComponent3D - Fix GraphicsComponent cloning not copying renderable local matrices - ⚠️ Rename PhysicsComponent3D::[Get|Set]Velocity to [Get|Set]LinearVelocity +- Add OnEntityDisabled and OnEntityEnabled callbacks to BaseComponent # 0.4: diff --git a/SDK/include/NDK/BaseComponent.hpp b/SDK/include/NDK/BaseComponent.hpp index 427fb017e..696e43719 100644 --- a/SDK/include/NDK/BaseComponent.hpp +++ b/SDK/include/NDK/BaseComponent.hpp @@ -50,6 +50,8 @@ namespace Ndk virtual void OnComponentDetached(BaseComponent& component); virtual void OnDetached(); virtual void OnEntityDestruction(); + virtual void OnEntityDisabled(); + virtual void OnEntityEnabled(); void SetEntity(Entity* entity); diff --git a/SDK/include/NDK/Entity.hpp b/SDK/include/NDK/Entity.hpp index 93ad73bfe..3f785fa76 100644 --- a/SDK/include/NDK/Entity.hpp +++ b/SDK/include/NDK/Entity.hpp @@ -42,7 +42,7 @@ namespace Ndk const EntityHandle& Clone() const; inline void Disable(); - inline void Enable(bool enable = true); + void Enable(bool enable = true); inline BaseComponent& GetComponent(ComponentIndex index); template ComponentType& GetComponent(); diff --git a/SDK/include/NDK/Entity.inl b/SDK/include/NDK/Entity.inl index 4aa497391..06922097e 100644 --- a/SDK/include/NDK/Entity.inl +++ b/SDK/include/NDK/Entity.inl @@ -38,20 +38,6 @@ namespace Ndk Enable(false); } - /*! - * \brief Enables the entity - * - * \param enable Should the entity be enabled - */ - inline void Entity::Enable(bool enable) - { - if (m_enabled != enable) - { - m_enabled = enable; - Invalidate(); - } - } - /*! * \brief Gets a component in the entity by index * \return A reference to the component diff --git a/SDK/src/NDK/BaseComponent.cpp b/SDK/src/NDK/BaseComponent.cpp index 204076e54..36d726adf 100644 --- a/SDK/src/NDK/BaseComponent.cpp +++ b/SDK/src/NDK/BaseComponent.cpp @@ -63,6 +63,26 @@ namespace Ndk { } + /*! + * \brief Operation to perform when the entity is disabled + * + * \remark Disabling an entity will remove it from systems it belongs to, but sometimes the entity will need to do + * additional work in order to be properly disabled (i.e.: disabling physics simulation & collisions) + */ + void BaseComponent::OnEntityDisabled() + { + } + + /*! + * \brief Operation to perform when the entity is disabled + * + * \remark Enabling an entity will add it back to systems it belongs to, but sometimes the entity will need to do + * additional work in order to be properly re-enabled (i.e.: enabling physics simulation & collisions) + */ + void BaseComponent::OnEntityEnabled() + { + } + std::vector BaseComponent::s_entries; std::unordered_map BaseComponent::s_idToIndex; } diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index a417a4414..b92405cb0 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -96,6 +96,10 @@ namespace Ndk m_components[i]->OnComponentAttached(component); } + // If we are currently disabled, inform the component + if (!m_enabled) + component.OnEntityDisabled(); + return component; } @@ -106,7 +110,6 @@ namespace Ndk * \remark The close is enable by default, even if the original is disabled * \remark Produces a NazaraAssert if the entity is not valid */ - const EntityHandle& Entity::Clone() const { NazaraAssert(IsValid(), "Invalid entity"); @@ -114,10 +117,34 @@ namespace Ndk return m_world->CloneEntity(m_id); } + /*! + * \brief Enables the entity + * + * \param enable Should the entity be enabled + */ + void Entity::Enable(bool enable) + { + if (m_enabled != enable) + { + m_enabled = enable; + if (m_enabled) + { + for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + m_components[i]->OnEntityEnabled(); + } + else + { + for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + m_components[i]->OnEntityDisabled(); + } + + Invalidate(); + } + } + /*! * \brief Kills the entity */ - void Entity::Kill() { m_world->KillEntity(this); diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index 41336c71b..774c42867 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -138,12 +138,11 @@ namespace Ndk * * \param id Identifier of the entity * - * \remark Produces a NazaraError if the entity to clone does not exist + * \remark Cloning a disabled entity will produce an enabled clone */ - const EntityHandle& World::CloneEntity(EntityId id) { - EntityHandle original = GetEntity(id); + const EntityHandle& original = GetEntity(id); if (!original) { NazaraError("Invalid entity ID"); @@ -151,6 +150,8 @@ namespace Ndk } const EntityHandle& clone = CreateEntity(); + if (!original->IsEnabled()) + clone->Disable(); const Nz::Bitset<>& componentBits = original->GetComponentBits(); for (std::size_t i = componentBits.FindFirst(); i != componentBits.npos; i = componentBits.FindNext(i)) @@ -159,6 +160,8 @@ namespace Ndk clone->AddComponent(std::move(component)); } + clone->Enable(); + return clone; }