diff --git a/SDK/include/NDK/BaseComponent.hpp b/SDK/include/NDK/BaseComponent.hpp index 53a6121ec..fc1e88058 100644 --- a/SDK/include/NDK/BaseComponent.hpp +++ b/SDK/include/NDK/BaseComponent.hpp @@ -14,8 +14,11 @@ namespace Ndk { + class Entity; + class NDK_API BaseComponent { + friend Entity; friend class Sdk; public: @@ -35,10 +38,15 @@ namespace Ndk protected: ComponentIndex m_componentIndex; + Entity* m_entity; static ComponentIndex RegisterComponent(ComponentId id, Factory factoryFunc); private: + virtual void OnComponentAttached(BaseComponent& component); + virtual void OnComponentDetached(BaseComponent& component); + void SetEntity(Entity* entity); + static bool Initialize(); static void Uninitialize(); diff --git a/SDK/include/NDK/BaseComponent.inl b/SDK/include/NDK/BaseComponent.inl index 0ac1678e0..290a5de2d 100644 --- a/SDK/include/NDK/BaseComponent.inl +++ b/SDK/include/NDK/BaseComponent.inl @@ -7,7 +7,8 @@ namespace Ndk { inline BaseComponent::BaseComponent(ComponentIndex index) : - m_componentIndex(index) + m_componentIndex(index), + m_entity(nullptr) { } @@ -35,6 +36,11 @@ namespace Ndk return index; } + inline void BaseComponent::SetEntity(Entity* entity) + { + m_entity = entity; + } + inline bool BaseComponent::Initialize() { // Rien à faire diff --git a/SDK/src/NDK/BaseComponent.cpp b/SDK/src/NDK/BaseComponent.cpp index 3c90cef21..6a54563df 100644 --- a/SDK/src/NDK/BaseComponent.cpp +++ b/SDK/src/NDK/BaseComponent.cpp @@ -8,6 +8,16 @@ namespace Ndk { BaseComponent::~BaseComponent() = default; + void BaseComponent::OnComponentAttached(BaseComponent& component) + { + NazaraUnused(component); + } + + void BaseComponent::OnComponentDetached(BaseComponent& component) + { + NazaraUnused(component); + } + 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 f7074c9b8..1c051214f 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -23,24 +23,34 @@ namespace Ndk Destroy(); } - BaseComponent& Entity::AddComponent(std::unique_ptr&& component) + BaseComponent& Entity::AddComponent(std::unique_ptr&& componentPtr) { - NazaraAssert(component, "Component must be valid"); + NazaraAssert(componentPtr, "Component must be valid"); - ComponentIndex index = component->GetIndex(); + ComponentIndex index = componentPtr->GetIndex(); // Nous nous assurons que le vecteur de component est suffisamment grand pour contenir le nouveau component if (index >= m_components.size()) m_components.resize(index + 1); // Affectation et retour du component - m_components[index] = std::move(component); + m_components[index] = std::move(componentPtr); m_componentBits.UnboundedSet(index); // On informe le monde que nous avons besoin d'une mise à jour m_world->Invalidate(m_id); - return *m_components[index].get(); + // On récupère le component et on informe les composants existants du nouvel arrivant + BaseComponent& component = *m_components[index].get(); + component.SetEntity(this); + + for (unsigned int i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + { + if (i != index) + m_components[index]->OnComponentAttached(component); + } + + return component; } EntityHandle Entity::CreateHandle() @@ -60,8 +70,12 @@ namespace Ndk void Entity::RemoveAllComponents() { + for (unsigned int i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + RemoveComponent(i); + + NazaraAssert(m_componentBits.TestNone(), "All components should be gone"); + m_components.clear(); - m_componentBits.Clear(); // On informe le monde que nous avons besoin d'une mise à jour m_world->Invalidate(m_id); @@ -72,6 +86,16 @@ namespace Ndk ///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 (unsigned int i = m_componentBits.FindFirst(); i != m_componentBits.npos; i = m_componentBits.FindNext(i)) + { + if (i != index) + m_components[index]->OnComponentDetached(component); + } + + component.SetEntity(nullptr); + m_components[index].reset(); m_componentBits.Reset(index);