diff --git a/ChangeLog.md b/ChangeLog.md index 0665bcc5c..8f11dacba 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -292,6 +292,7 @@ Nazara Development Kit: - ⚠️ Console now supports text color in history - Added World::CloneEntity overload taking an EntityHandle const reference, allowing to copy entities from other worlds - Fixed PhysicsComponent2D copy not copying physics attributes +- Added Entity::DropComponent which detaches a component without necessarily destroying it # 0.4: diff --git a/SDK/include/NDK/Entity.hpp b/SDK/include/NDK/Entity.hpp index e09f4eac4..85e43da19 100644 --- a/SDK/include/NDK/Entity.hpp +++ b/SDK/include/NDK/Entity.hpp @@ -43,6 +43,10 @@ namespace Ndk const EntityHandle& Clone() const; inline void Disable(); + + std::unique_ptr DropComponent(ComponentIndex index); + template std::unique_ptr DropComponent(); + void Enable(bool enable = true); inline BaseComponent& GetComponent(ComponentIndex index); @@ -83,8 +87,6 @@ namespace Ndk void Create(); void Destroy(); - void DestroyComponent(ComponentIndex index); - inline Nz::Bitset<>& GetRemovedComponentBits(); inline void RegisterEntityList(EntityList* list); diff --git a/SDK/include/NDK/Entity.inl b/SDK/include/NDK/Entity.inl index 7b8fa5736..799384182 100644 --- a/SDK/include/NDK/Entity.inl +++ b/SDK/include/NDK/Entity.inl @@ -64,6 +64,15 @@ namespace Ndk * \remark Produces a NazaraAssert if component is not available in this entity */ + template + std::unique_ptr Entity::DropComponent() + { + static_assert(std::is_base_of::value, "ComponentType is not a component"); + + ComponentIndex index = GetComponentIndex(); + return DropComponent(index); + } + template ComponentType& Entity::GetComponent() { diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index 4e211f0db..8086e5905 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -97,6 +97,36 @@ namespace Ndk return m_world->CloneEntity(m_id); } + /*! + * \brief Detaches a component from the entity + * \return An owning pointer to the component + * + * Instantly detaches a component from the entity and returns it, allowing to attach it to another entity + * + * \remark Unlike RemoveComponent, this function instantly removes the component + */ + std::unique_ptr Entity::DropComponent(ComponentIndex index) + { + if (!HasComponent(index)) + return nullptr; + + // We get the component and we alert existing components of the deleted one + std::unique_ptr component = std::move(m_components[index]); + m_components[index].reset(); + + for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + { + if (i != index) + m_components[i]->OnComponentDetached(*component); + } + m_componentBits.Reset(index); + m_removedComponentBits.UnboundedReset(index); + + component->SetEntity(nullptr); + + return component; + } + /*! * \brief Enables the entity * @@ -208,32 +238,4 @@ namespace Ndk m_valid = false; } - - /*! - * \brief Destroys a component by index - * - * \param index Index of the component - * - * \remark If component is not available, no action is performed - */ - - void Entity::DestroyComponent(ComponentIndex index) - { - if (HasComponent(index)) - { - // We get the component and we alert existing components of the deleted one - BaseComponent& component = *m_components[index].get(); - for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) - { - if (i != index) - m_components[i]->OnComponentDetached(component); - } - - component.SetEntity(nullptr); - - m_components[index].reset(); - m_componentBits.Reset(index); - } - } - } diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index dc848625a..ef59463bc 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -249,8 +249,7 @@ namespace Ndk Nz::Bitset<>& removedComponents = entity->GetRemovedComponentBits(); for (std::size_t j = removedComponents.FindFirst(); j != m_dirtyEntities.back.npos; j = removedComponents.FindNext(j)) - entity->DestroyComponent(static_cast(j)); - removedComponents.Reset(); + entity->DropComponent(static_cast(j)); for (auto& system : m_orderedSystems) {