diff --git a/SDK/include/NDK/Entity.hpp b/SDK/include/NDK/Entity.hpp index 6069a13c0..ae6b1acf5 100644 --- a/SDK/include/NDK/Entity.hpp +++ b/SDK/include/NDK/Entity.hpp @@ -52,8 +52,8 @@ namespace Ndk inline bool IsEnabled() const; inline bool IsValid() const; - void RemoveAllComponents(); - void RemoveComponent(ComponentIndex index); + inline void RemoveAllComponents(); + inline void RemoveComponent(ComponentIndex index); template void RemoveComponent(); inline Nz::String ToString() const; @@ -67,6 +67,10 @@ namespace Ndk void Create(); void Destroy(); + void DestroyComponent(ComponentIndex index); + + inline Nz::Bitset<>& GetRemovedComponentBits(); + inline void RegisterSystem(SystemIndex index); inline void SetWorld(World* world) noexcept; @@ -75,6 +79,7 @@ namespace Ndk std::vector> m_components; Nz::Bitset<> m_componentBits; + Nz::Bitset<> m_removedComponentBits; Nz::Bitset<> m_systemBits; EntityId m_id; World* m_world; diff --git a/SDK/include/NDK/Entity.inl b/SDK/include/NDK/Entity.inl index 799ffd97e..c7937b786 100644 --- a/SDK/include/NDK/Entity.inl +++ b/SDK/include/NDK/Entity.inl @@ -103,12 +103,31 @@ namespace Ndk RemoveComponent(index); } + inline void Entity::RemoveAllComponents() + { + m_removedComponentBits = m_componentBits; + + Invalidate(); + } + + inline void Entity::RemoveComponent(ComponentIndex index) + { + m_removedComponentBits.UnboundedSet(index); + + Invalidate(); + } + inline Nz::String Entity::ToString() const { Nz::StringStream ss; return ss << "Entity(" << GetId() << ')'; } + inline Nz::Bitset<>& Entity::GetRemovedComponentBits() + { + return m_removedComponentBits; + } + inline void Entity::RegisterSystem(SystemIndex index) { m_systemBits.UnboundedSet(index); diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index f037e5f9a..680ff56d9 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -44,6 +44,7 @@ namespace Ndk // Affectation et retour du component m_components[index] = std::move(componentPtr); m_componentBits.UnboundedSet(index); + m_removedComponentBits.UnboundedReset(index); Invalidate(); @@ -71,40 +72,6 @@ namespace Ndk m_world->Invalidate(m_id); } - void Entity::RemoveAllComponents() - { - for (std::size_t i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) - RemoveComponent(static_cast(i)); - - NazaraAssert(m_componentBits.TestNone(), "All components should be gone"); - - m_components.clear(); - - Invalidate(); - } - - void Entity::RemoveComponent(ComponentIndex index) - { - ///DOC: N'a aucun effet si le component n'est pas présent - if (HasComponent(index)) - { - // On récupère le component et on informe les composants du détachement - 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); - - Invalidate(); - } - } - void Entity::Create() { m_enabled = true; @@ -128,4 +95,25 @@ namespace Ndk m_valid = false; } + + void Entity::DestroyComponent(ComponentIndex index) + { + ///DOC: N'a aucun effet si le component n'est pas présent + if (HasComponent(index)) + { + // On récupère le component et on informe les composants du détachement + 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 5d0e4900b..e5b2d874a 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -139,6 +139,11 @@ namespace Ndk if (!entity->IsValid()) continue; + Nz::Bitset<>& removedComponents = entity->GetRemovedComponentBits(); + for (std::size_t j = removedComponents.FindFirst(); j != m_dirtyEntities.npos; j = removedComponents.FindNext(j)) + entity->DestroyComponent(j); + removedComponents.Reset(); + for (auto& system : m_systems) { // Ignore non-existent systems