From 1fc0d564ce6d268660aae6c7dc6d5c1f2ec8ddd2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 11 Aug 2016 01:02:40 +0200 Subject: [PATCH] SDK/Entity: Delay component removal until world update Allows system to freely remove components while updating Former-commit-id: db5877bc20e6a0dfadd69f81a339f0a57d8404df [formerly 74327b8f1429855625613f258894b37d026041fe] [formerly 65b8f2ba78d2690b7a469d4b9818b189524633db [formerly 71be95adb46b7183261a8038352c4d8bd17cacc3]] Former-commit-id: ba91d5abad60792e648d47e646ae49d43a1c94b5 [formerly 8d0667574ff665e151e7fda5f854fc11a16c854d] Former-commit-id: eb7b06c2739ef698a153a6221870a8d0956dc875 --- SDK/include/NDK/Entity.hpp | 9 ++++-- SDK/include/NDK/Entity.inl | 19 +++++++++++++ SDK/src/NDK/Entity.cpp | 56 +++++++++++++++----------------------- SDK/src/NDK/World.cpp | 5 ++++ 4 files changed, 53 insertions(+), 36 deletions(-) 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