Re-remade component and system ids

Former-commit-id: 98b76695cca904c55c7333801c3cdf693da15086
This commit is contained in:
Lynix 2015-03-30 04:18:44 +02:00
parent 3fd217b8a3
commit 6d1ac4fe18
17 changed files with 196 additions and 126 deletions

View File

@ -11,10 +11,9 @@
namespace Ndk namespace Ndk
{ {
template<unsigned int N> ComponentId BuildComponentId(const char (&id)[N]); template<unsigned int N> ComponentId BuildComponentId(const char (&name)[N]);
template<unsigned int N> SystemId BuildSystemId(const char (&id)[N]); template<typename ComponentType> constexpr ComponentIndex GetComponentIndex();
template<typename ComponentType> constexpr ComponentId GetComponentId(); template<typename SystemType> constexpr SystemIndex GetSystemIndex();
template<typename SystemType> constexpr SystemId GetSystemId();
} }
#include <Ndk/Algorithm.inl> #include <Ndk/Algorithm.inl>

View File

@ -8,38 +8,26 @@ namespace Ndk
{ {
///TODO: constexpr avec le C++14 ///TODO: constexpr avec le C++14
template<unsigned int N> template<unsigned int N>
ComponentId BuildComponentId(const char (&id)[N]) ComponentId BuildComponentId(const char (&name)[N])
{ {
static_assert(N-1 <= sizeof(ComponentId), "ID too long for this size of component id"); static_assert(N-1 <= sizeof(ComponentId), "Name too long for this size of component id");
ComponentId componentId = 0; ComponentId componentId = 0;
for (int i = 0; i < N; ++i) for (int i = 0; i < N; ++i)
componentId |= static_cast<ComponentId>(id[i]) << i*8; componentId |= static_cast<ComponentId>(name[i]) << i*8;
return componentId;
}
template<unsigned int N>
SystemId BuildSystemId(const char (&id)[N])
{
static_assert(N-1 <= sizeof(ComponentId), "ID too long for this size of component id");
ComponentId componentId = 0;
for (int i = 0; i < N; ++i)
componentId |= static_cast<ComponentId>(id[i]) << i*8;
return componentId; return componentId;
} }
template<typename ComponentType> template<typename ComponentType>
constexpr ComponentId GetComponentId() constexpr ComponentIndex GetComponentIndex()
{ {
return ComponentType::ComponentId; return ComponentType::ComponentIndex;
} }
template<typename SystemType> template<typename SystemType>
constexpr SystemId GetSystemId() constexpr SystemIndex GetSystemIndex()
{ {
return SystemType::SystemId; return SystemType::SystemIndex;
} }
} }

View File

@ -8,21 +8,41 @@
#define NDK_BASECOMPONENT_HPP #define NDK_BASECOMPONENT_HPP
#include <NDK/Prerequesites.hpp> #include <NDK/Prerequesites.hpp>
#include <functional>
#include <unordered_map>
#include <vector>
namespace Ndk namespace Ndk
{ {
class NDK_API BaseComponent class NDK_API BaseComponent
{ {
public: public:
BaseComponent(ComponentId componentId); using Factory = std::function<BaseComponent*()>;
BaseComponent(ComponentIndex componentIndex);
virtual ~BaseComponent(); virtual ~BaseComponent();
virtual BaseComponent* Clone() const = 0; virtual BaseComponent* Clone() const = 0;
ComponentId GetId() const; ComponentIndex GetIndex() const;
template<typename ComponentType, unsigned int N>
static ComponentIndex Register(const char (&name)[N]);
static ComponentIndex Register(ComponentId id, Factory factoryFunc);
protected: protected:
ComponentId m_componentId; ComponentIndex m_componentIndex;
private:
struct ComponentEntry
{
ComponentId id;
Factory factory;
};
static std::vector<ComponentEntry> s_entries;
static std::unordered_map<ComponentId, ComponentIndex> s_idToIndex;
}; };
} }

View File

@ -2,15 +2,46 @@
// This file is part of the "Nazara Development Kit" // This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp // For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <Ndk/Algorithm.hpp>
#include <type_traits>
namespace Ndk namespace Ndk
{ {
inline BaseComponent::BaseComponent(ComponentId componentId) : inline BaseComponent::BaseComponent(ComponentIndex index) :
m_componentId(componentId) m_componentIndex(index)
{ {
} }
inline ComponentId BaseComponent::GetId() const inline ComponentIndex BaseComponent::GetIndex() const
{ {
return m_componentId; return m_componentIndex;
}
template<typename ComponentType, unsigned int N>
ComponentIndex BaseComponent::Register(const char (&name)[N])
{
static_assert(std::is_default_constructible<ComponentType>::value, "ComponentType should be default-constructible");
ComponentId id = BuildComponentId(name);
auto factory = []() -> BaseComponent*
{
return new ComponentType;
};
return Register(id, factory);
}
inline ComponentIndex BaseComponent::Register(ComponentId id, Factory factoryFunc)
{
ComponentIndex index = s_entries.size();
s_entries.resize(index + 1);
ComponentEntry& entry = s_entries.back();
entry.factory = factoryFunc;
entry.id = id;
s_idToIndex[id] = index;
return index;
} }
} }

View File

@ -10,7 +10,6 @@
#include <Nazara/Core/Bitset.hpp> #include <Nazara/Core/Bitset.hpp>
#include <NDK/EntityHandle.hpp> #include <NDK/EntityHandle.hpp>
#include <vector> #include <vector>
#include <unordered_set>
namespace Ndk namespace Ndk
{ {
@ -22,7 +21,7 @@ namespace Ndk
friend World; friend World;
public: public:
BaseSystem(SystemId systemId); BaseSystem(SystemIndex systemId);
virtual ~BaseSystem(); virtual ~BaseSystem();
virtual BaseSystem* Clone() const = 0; virtual BaseSystem* Clone() const = 0;
@ -30,19 +29,21 @@ namespace Ndk
bool Filters(const Entity* entity) const; bool Filters(const Entity* entity) const;
const std::vector<EntityHandle>& GetEntities() const; const std::vector<EntityHandle>& GetEntities() const;
SystemId GetId() const; SystemIndex GetIndex() const;
World& GetWorld() const; World& GetWorld() const;
bool HasEntity(const Entity* entity) const; bool HasEntity(const Entity* entity) const;
static SystemIndex GetNextIndex();
protected: protected:
template<typename ComponentType> void Excludes(); template<typename ComponentType> void Excludes();
template<typename ComponentType1, typename ComponentType2, typename... Rest> void Excludes(); template<typename ComponentType1, typename ComponentType2, typename... Rest> void Excludes();
void ExcludesComponent(ComponentId componentId); void ExcludesComponent(ComponentIndex index);
template<typename ComponentType> void Requires(); template<typename ComponentType> void Requires();
template<typename ComponentType1, typename ComponentType2, typename... Rest> void Requires(); template<typename ComponentType1, typename ComponentType2, typename... Rest> void Requires();
void RequiresComponent(ComponentId componentId); void RequiresComponent(ComponentIndex index);
private: private:
void AddEntity(Entity* entity); void AddEntity(Entity* entity);
@ -56,10 +57,13 @@ namespace Ndk
std::vector<EntityHandle> m_entities; std::vector<EntityHandle> m_entities;
NzBitset<nzUInt64> m_entityBits; NzBitset<nzUInt64> m_entityBits;
std::unordered_set<ComponentId> m_excludedComponents; NzBitset<> m_excludedComponents;
std::unordered_set<ComponentId> m_requiredComponents; mutable NzBitset<> m_filterResult;
SystemId m_systemId; NzBitset<> m_requiredComponents;
SystemIndex m_systemIndex;
World* m_world; World* m_world;
static SystemIndex s_nextIndex;
}; };
} }

View File

@ -7,8 +7,8 @@
namespace Ndk namespace Ndk
{ {
inline BaseSystem::BaseSystem(SystemId systemId) : inline BaseSystem::BaseSystem(SystemIndex systemId) :
m_systemId(systemId) m_systemIndex(systemId)
{ {
} }
@ -17,9 +17,9 @@ namespace Ndk
return m_entities; return m_entities;
} }
inline SystemId BaseSystem::GetId() const inline SystemIndex BaseSystem::GetIndex() const
{ {
return m_systemId; return m_systemIndex;
} }
inline World& BaseSystem::GetWorld() const inline World& BaseSystem::GetWorld() const
@ -35,12 +35,17 @@ namespace Ndk
return m_entityBits.UnboundedTest(entity->GetId()); return m_entityBits.UnboundedTest(entity->GetId());
} }
inline SystemIndex BaseSystem::GetNextIndex()
{
return s_nextIndex++;
}
template<typename ComponentType> template<typename ComponentType>
void BaseSystem::Excludes() void BaseSystem::Excludes()
{ {
static_assert(std::is_base_of<BaseComponent, ComponentType>(), "ComponentType is not a component"); static_assert(std::is_base_of<BaseComponent, ComponentType>(), "ComponentType is not a component");
ExcludesComponent(GetComponentId<ComponentType>()); ExcludesComponent(GetComponentIndex<ComponentType>());
} }
template<typename ComponentType1, typename ComponentType2, typename... Rest> template<typename ComponentType1, typename ComponentType2, typename... Rest>
@ -50,9 +55,9 @@ namespace Ndk
Excludes<ComponentType2, Rest...>(); Excludes<ComponentType2, Rest...>();
} }
inline void BaseSystem::ExcludesComponent(ComponentId componentId) inline void BaseSystem::ExcludesComponent(ComponentIndex index)
{ {
m_excludedComponents.insert(componentId); m_excludedComponents.UnboundedSet(index);
} }
template<typename ComponentType> template<typename ComponentType>
@ -60,7 +65,7 @@ namespace Ndk
{ {
static_assert(std::is_base_of<BaseComponent, ComponentType>(), "ComponentType is not a component"); static_assert(std::is_base_of<BaseComponent, ComponentType>(), "ComponentType is not a component");
RequiresComponent(GetComponentId<ComponentType>()); RequiresComponent(GetComponentIndex<ComponentType>());
} }
template<typename ComponentType1, typename ComponentType2, typename... Rest> template<typename ComponentType1, typename ComponentType2, typename... Rest>
@ -70,9 +75,9 @@ namespace Ndk
Requires<ComponentType2, Rest...>(); Requires<ComponentType2, Rest...>();
} }
inline void BaseSystem::RequiresComponent(ComponentId componentId) inline void BaseSystem::RequiresComponent(ComponentIndex index)
{ {
m_requiredComponents.insert(componentId); m_requiredComponents.UnboundedSet(index);
} }
inline void BaseSystem::AddEntity(Entity* entity) inline void BaseSystem::AddEntity(Entity* entity)
@ -82,7 +87,7 @@ namespace Ndk
m_entities.push_back(entity->CreateHandle()); m_entities.push_back(entity->CreateHandle());
m_entityBits.UnboundedSet(entity->GetId(), true); m_entityBits.UnboundedSet(entity->GetId(), true);
entity->RegisterSystem(m_systemId); entity->RegisterSystem(m_systemIndex);
OnEntityAdded(entity); OnEntityAdded(entity);
} }
@ -99,7 +104,7 @@ namespace Ndk
m_entities.pop_back(); // On le sort du vector m_entities.pop_back(); // On le sort du vector
m_entityBits.Reset(entity->GetId()); m_entityBits.Reset(entity->GetId());
entity->UnregisterSystem(m_systemId); entity->UnregisterSystem(m_systemIndex);
OnEntityRemoved(entity); // Et on appelle le callback OnEntityRemoved(entity); // Et on appelle le callback
} }

View File

@ -2,14 +2,13 @@
// This file is part of the "Nazara Development Kit" // This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp // For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <Ndk/Algorithm.hpp>
#include <type_traits> #include <type_traits>
namespace Ndk namespace Ndk
{ {
template<typename ComponentType> template<typename ComponentType>
Component<ComponentType>::Component() : Component<ComponentType>::Component() :
BaseComponent(GetComponentId<ComponentType>()) BaseComponent(GetComponentIndex<ComponentType>())
{ {
} }

View File

@ -11,8 +11,6 @@
#include <NDK/Component.hpp> #include <NDK/Component.hpp>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <unordered_map>
#include <unordered_set>
namespace Ndk namespace Ndk
{ {
@ -35,12 +33,14 @@ namespace Ndk
EntityHandle CreateHandle(); EntityHandle CreateHandle();
BaseComponent& GetComponent(ComponentId componentId); BaseComponent& GetComponent(ComponentIndex index);
template<typename ComponentType> ComponentType& GetComponent(); template<typename ComponentType> ComponentType& GetComponent();
const NzBitset<>& GetComponentBits() const;
EntityId GetId() const; EntityId GetId() const;
const NzBitset<>& GetSystemBits() const;
World* GetWorld() const; World* GetWorld() const;
bool HasComponent(ComponentId componentId) const; bool HasComponent(ComponentIndex index) const;
template<typename ComponentType> bool HasComponent() const; template<typename ComponentType> bool HasComponent() const;
void Kill(); void Kill();
@ -48,7 +48,7 @@ namespace Ndk
bool IsValid() const; bool IsValid() const;
void RemoveAllComponents(); void RemoveAllComponents();
void RemoveComponent(ComponentId componentId); void RemoveComponent(ComponentIndex index);
template<typename ComponentType> void RemoveComponent(); template<typename ComponentType> void RemoveComponent();
Entity& operator=(const Entity&) = delete; Entity& operator=(const Entity&) = delete;
@ -61,14 +61,15 @@ namespace Ndk
void Destroy(); void Destroy();
void RegisterHandle(EntityHandle* handle); void RegisterHandle(EntityHandle* handle);
void RegisterSystem(SystemId systemId); void RegisterSystem(SystemIndex index);
void UnregisterHandle(EntityHandle* handle); void UnregisterHandle(EntityHandle* handle);
void UnregisterSystem(SystemId systemId); void UnregisterSystem(SystemIndex index);
std::vector<std::unique_ptr<BaseComponent>> m_components;
std::vector<EntityHandle*> m_handles; std::vector<EntityHandle*> m_handles;
std::unordered_map<ComponentId, std::unique_ptr<BaseComponent>> m_components;
std::unordered_set<SystemId> m_systems;
EntityId m_id; EntityId m_id;
NzBitset<> m_componentBits;
NzBitset<> m_systemBits;
World* m_world; World* m_world;
bool m_valid; bool m_valid;
}; };

View File

@ -25,12 +25,12 @@ namespace Ndk
return static_cast<ComponentType&>(AddComponent(std::move(ptr))); return static_cast<ComponentType&>(AddComponent(std::move(ptr)));
} }
inline BaseComponent& Entity::GetComponent(ComponentId componentId) inline BaseComponent& Entity::GetComponent(ComponentIndex index)
{ {
///DOC: Le component doit être présent ///DOC: Le component doit être présent
NazaraAssert(HasComponent(componentId), "This component is not part of the entity"); NazaraAssert(HasComponent(index), "This component is not part of the entity");
BaseComponent* component = m_components[componentId].get(); BaseComponent* component = m_components[index].get();
NazaraAssert(component, "Invalid component pointer"); NazaraAssert(component, "Invalid component pointer");
return *component; return *component;
@ -42,8 +42,13 @@ namespace Ndk
///DOC: Le component doit être présent ///DOC: Le component doit être présent
static_assert(std::is_base_of<BaseComponent, ComponentType>(), "ComponentType is not a component"); static_assert(std::is_base_of<BaseComponent, ComponentType>(), "ComponentType is not a component");
ComponentId componentId = GetComponentId<ComponentType>(); ComponentIndex index = GetComponentIndex<ComponentType>();
return static_cast<ComponentType&>(GetComponent(componentId)); return static_cast<ComponentType&>(GetComponent(index));
}
inline const NzBitset<>& Entity::GetComponentBits() const
{
return m_componentBits;
} }
inline EntityId Entity::GetId() const inline EntityId Entity::GetId() const
@ -51,14 +56,19 @@ namespace Ndk
return m_id; return m_id;
} }
inline const NzBitset<>& Entity::GetSystemBits() const
{
return m_systemBits;
}
inline World* Entity::GetWorld() const inline World* Entity::GetWorld() const
{ {
return m_world; return m_world;
} }
inline bool Entity::HasComponent(ComponentId componentId) const inline bool Entity::HasComponent(ComponentIndex index) const
{ {
return m_components.count(componentId) > 0; return m_componentBits.UnboundedTest(index);
} }
template<typename ComponentType> template<typename ComponentType>
@ -66,8 +76,8 @@ namespace Ndk
{ {
static_assert(std::is_base_of<BaseComponent, ComponentType>(), "ComponentType is not a component"); static_assert(std::is_base_of<BaseComponent, ComponentType>(), "ComponentType is not a component");
ComponentId componentId = GetComponentId<ComponentType>(); ComponentIndex index = GetComponentIndex<ComponentType>();
return HasComponent(componentId); return HasComponent(index);
} }
template<typename ComponentType> template<typename ComponentType>
@ -75,8 +85,8 @@ namespace Ndk
{ {
static_assert(std::is_base_of<BaseComponent, ComponentType>(), "ComponentType is not a component"); static_assert(std::is_base_of<BaseComponent, ComponentType>(), "ComponentType is not a component");
ComponentId componentId = GetComponentId<ComponentType>(); ComponentIndex index = GetComponentIndex<ComponentType>();
RemoveComponent(componentId); RemoveComponent(index);
} }
inline void Entity::RegisterHandle(EntityHandle* handle) inline void Entity::RegisterHandle(EntityHandle* handle)
@ -85,9 +95,9 @@ namespace Ndk
m_handles.push_back(handle); m_handles.push_back(handle);
} }
inline void Entity::RegisterSystem(SystemId systemId) inline void Entity::RegisterSystem(SystemIndex index)
{ {
m_systems.insert(systemId); m_systemBits.UnboundedSet(index);
} }
inline void Entity::UnregisterHandle(EntityHandle* handle) inline void Entity::UnregisterHandle(EntityHandle* handle)
@ -100,8 +110,8 @@ namespace Ndk
m_handles.pop_back(); m_handles.pop_back();
} }
inline void Entity::UnregisterSystem(SystemId systemId) inline void Entity::UnregisterSystem(SystemIndex index)
{ {
m_systems.erase(systemId); m_systemBits.UnboundedReset(index);
} }
} }

View File

@ -57,9 +57,10 @@
namespace Ndk namespace Ndk
{ {
using ComponentId = nzUInt32; using ComponentId = nzUInt64;
using ComponentIndex = nzUInt32;
using EntityId = nzUInt32; using EntityId = nzUInt32;
using SystemId = nzUInt32; using SystemIndex = nzUInt32;
} }
#endif // NDK_PREREQUESITES_HPP #endif // NDK_PREREQUESITES_HPP

View File

@ -9,7 +9,7 @@ namespace Ndk
{ {
template<typename SystemType> template<typename SystemType>
System<SystemType>::System() : System<SystemType>::System() :
BaseSystem(GetSystemId<SystemType>()) BaseSystem(GetSystemIndex<SystemType>())
{ {
} }

View File

@ -38,10 +38,10 @@ namespace Ndk
void Clear(); void Clear();
const EntityHandle& GetEntity(EntityId id); const EntityHandle& GetEntity(EntityId id);
BaseSystem& GetSystem(SystemId systemId); BaseSystem& GetSystem(SystemIndex index);
template<typename SystemType> SystemType& GetSystem(); template<typename SystemType> SystemType& GetSystem();
bool HasSystem(SystemId systemId) const; bool HasSystem(SystemIndex index) const;
template<typename SystemType> bool HasSystem() const; template<typename SystemType> bool HasSystem() const;
void KillEntity(Entity* entity); void KillEntity(Entity* entity);
@ -51,7 +51,7 @@ namespace Ndk
bool IsEntityIdValid(EntityId id) const; bool IsEntityIdValid(EntityId id) const;
void RemoveAllSystems(); void RemoveAllSystems();
void RemoveSystem(SystemId systemId); void RemoveSystem(SystemIndex index);
template<typename SystemType> void RemoveSystem(); template<typename SystemType> void RemoveSystem();
void Update(); void Update();
@ -71,9 +71,9 @@ namespace Ndk
unsigned int aliveIndex; unsigned int aliveIndex;
}; };
std::vector<std::unique_ptr<BaseSystem>> m_systems;
std::vector<EntityId> m_freeIdList; std::vector<EntityId> m_freeIdList;
std::vector<EntityBlock> m_entities; std::vector<EntityBlock> m_entities;
std::unordered_map<SystemId, std::unique_ptr<BaseSystem>> m_systems;
EntityList m_aliveEntities; EntityList m_aliveEntities;
NzBitset<nzUInt64> m_dirtyEntities; NzBitset<nzUInt64> m_dirtyEntities;
NzBitset<nzUInt64> m_killedEntities; NzBitset<nzUInt64> m_killedEntities;

View File

@ -11,15 +11,19 @@ namespace Ndk
{ {
NazaraAssert(system, "System must be valid"); NazaraAssert(system, "System must be valid");
SystemId systemId = system->GetId(); SystemIndex index = system->GetIndex();
// Nous nous assurons que le vecteur de component est suffisamment grand pour contenir le nouveau component
if (index >= m_systems.size())
m_systems.resize(index + 1);
// Affectation et retour du système // Affectation et retour du système
m_systems[systemId] = std::move(system); m_systems[index] = std::move(system);
m_systems[systemId]->SetWorld(*this); m_systems[index]->SetWorld(*this);
MarkAllAsDirty(); // On force une mise à jour de toutes les entités MarkAllAsDirty(); // On force une mise à jour de toutes les entités
return *m_systems[systemId].get(); return *m_systems[index].get();
} }
template<typename SystemType, typename... Args> template<typename SystemType, typename... Args>
@ -43,12 +47,12 @@ namespace Ndk
return list; return list;
} }
inline BaseSystem& World::GetSystem(SystemId systemId) inline BaseSystem& World::GetSystem(SystemIndex index)
{ {
///DOC: Le système doit être présent ///DOC: Le système doit être présent
NazaraAssert(HasSystem(systemId), "This system is not part of the world"); NazaraAssert(HasSystem(index), "This system is not part of the world");
BaseSystem* system = m_systems[systemId].get(); BaseSystem* system = m_systems[index].get();
NazaraAssert(system, "Invalid system pointer"); NazaraAssert(system, "Invalid system pointer");
return *system; return *system;
@ -60,13 +64,13 @@ namespace Ndk
///DOC: Le système doit être présent ///DOC: Le système doit être présent
static_assert(std::is_base_of<BaseSystem, SystemType>(), "SystemType is not a system"); static_assert(std::is_base_of<BaseSystem, SystemType>(), "SystemType is not a system");
SystemId systemId = GetSystemId<SystemType>(); SystemIndex index = GetSystemIndex<SystemType>();
return static_cast<SystemType&>(GetSystem(systemId)); return static_cast<SystemType&>(GetSystem(index));
} }
inline bool World::HasSystem(SystemId systemId) const inline bool World::HasSystem(SystemIndex index) const
{ {
return m_systems.count(systemId) > 0; return index < m_systems.size() && m_systems[index];
} }
template<typename SystemType> template<typename SystemType>
@ -74,8 +78,8 @@ namespace Ndk
{ {
static_assert(std::is_base_of<BaseSystem, SystemType>(), "SystemType is not a component"); static_assert(std::is_base_of<BaseSystem, SystemType>(), "SystemType is not a component");
SystemId systemId = GetSystemId<SystemType>(); SystemIndex index = GetSystemIndex<SystemType>();
return HasSystem(systemId); return HasSystem(index);
} }
inline void World::KillEntities(const EntityList& list) inline void World::KillEntities(const EntityList& list)
@ -99,11 +103,11 @@ namespace Ndk
m_systems.clear(); m_systems.clear();
} }
inline void World::RemoveSystem(SystemId systemId) inline void World::RemoveSystem(SystemIndex index)
{ {
///DOC: N'a aucun effet si le système n'est pas présent ///DOC: N'a aucun effet si le système n'est pas présent
if (HasSystem(systemId)) if (HasSystem(index))
m_systems[systemId].reset(); m_systems[index].reset();
} }
template<typename SystemType> template<typename SystemType>
@ -111,8 +115,8 @@ namespace Ndk
{ {
static_assert(std::is_base_of<BaseSystem, SystemType>(), "SystemType is not a system"); static_assert(std::is_base_of<BaseSystem, SystemType>(), "SystemType is not a system");
SystemId systemId = GetSystemId<SystemType>(); SystemIndex index = GetSystemIndex<SystemType>();
RemoveSystem(systemId); RemoveSystem(index);
} }
inline void World::MarkAllAsDirty() inline void World::MarkAllAsDirty()

View File

@ -7,4 +7,7 @@
namespace Ndk namespace Ndk
{ {
BaseComponent::~BaseComponent() = default; BaseComponent::~BaseComponent() = default;
std::vector<BaseComponent::ComponentEntry> BaseComponent::s_entries;
std::unordered_map<ComponentId, ComponentIndex> BaseComponent::s_idToIndex;
} }

View File

@ -9,7 +9,7 @@ namespace Ndk
BaseSystem::~BaseSystem() BaseSystem::~BaseSystem()
{ {
for (const EntityHandle& entity : m_entities) for (const EntityHandle& entity : m_entities)
entity->UnregisterSystem(m_systemId); entity->UnregisterSystem(m_systemIndex);
} }
bool BaseSystem::Filters(const Entity* entity) const bool BaseSystem::Filters(const Entity* entity) const
@ -17,17 +17,15 @@ namespace Ndk
if (!entity) if (!entity)
return false; return false;
for (ComponentId component : m_requiredComponents) const NzBitset<>& components = entity->GetComponentBits();
{
if (!entity->HasComponent(component))
return false; // Au moins un component requis n'est pas présent
}
for (ComponentId component : m_excludedComponents) m_filterResult.PerformsAND(m_requiredComponents, components);
{ if (m_filterResult != m_requiredComponents)
if (entity->HasComponent(component)) return false; // Au moins un component requis n'est pas présent
m_filterResult.PerformsAND(m_excludedComponents, components);
if (m_filterResult.TestAny())
return false; // Au moins un component exclu est présent return false; // Au moins un component exclu est présent
}
return true; return true;
} }
@ -41,4 +39,6 @@ namespace Ndk
{ {
NazaraUnused(entity); NazaraUnused(entity);
} }
SystemIndex BaseSystem::s_nextIndex = 0;
} }

View File

@ -27,15 +27,20 @@ namespace Ndk
{ {
NazaraAssert(component, "Component must be valid"); NazaraAssert(component, "Component must be valid");
ComponentId componentId = component->GetId(); ComponentIndex index = component->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 // Affectation et retour du component
m_components[componentId] = std::move(component); m_components[index] = std::move(component);
m_componentBits.UnboundedSet(index);
// On informe le monde que nous avons besoin d'une mise à jour // On informe le monde que nous avons besoin d'une mise à jour
m_world->MarkAsDirty(m_id); m_world->MarkAsDirty(m_id);
return *m_components[componentId].get(); return *m_components[index].get();
} }
EntityHandle Entity::CreateHandle() EntityHandle Entity::CreateHandle()
@ -56,17 +61,19 @@ namespace Ndk
void Entity::RemoveAllComponents() void Entity::RemoveAllComponents()
{ {
m_components.clear(); m_components.clear();
m_componentBits.Clear();
// On informe le monde que nous avons besoin d'une mise à jour // On informe le monde que nous avons besoin d'une mise à jour
m_world->MarkAsDirty(m_id); m_world->MarkAsDirty(m_id);
} }
void Entity::RemoveComponent(ComponentId componentId) void Entity::RemoveComponent(ComponentIndex index)
{ {
///DOC: N'a aucun effet si le component n'est pas présent ///DOC: N'a aucun effet si le component n'est pas présent
if (HasComponent(componentId)) if (HasComponent(index))
{ {
m_components[componentId].reset(); m_components[index].reset();
m_componentBits.Reset(index);
// On informe le monde que nous avons besoin d'une mise à jour // On informe le monde que nous avons besoin d'une mise à jour
m_world->MarkAsDirty(m_id); m_world->MarkAsDirty(m_id);
@ -83,15 +90,15 @@ namespace Ndk
m_valid = false; m_valid = false;
// On informe chaque système // On informe chaque système
for (SystemId systemId : m_systems) for (SystemIndex index = m_systemBits.FindFirst(); index != m_systemBits.npos; index = m_systemBits.FindNext(index))
{ {
if (m_world->HasSystem(systemId)) if (m_world->HasSystem(index))
{ {
BaseSystem& system = m_world->GetSystem(systemId); BaseSystem& system = m_world->GetSystem(index);
system.RemoveEntity(this); system.RemoveEntity(this);
} }
} }
m_systems.clear(); m_systemBits.Clear();
// On informe chaque handle de notre destruction pour éviter qu'il ne continue de pointer sur nous // On informe chaque handle de notre destruction pour éviter qu'il ne continue de pointer sur nous
for (EntityHandle* handle : m_handles) for (EntityHandle* handle : m_handles)

View File

@ -116,10 +116,8 @@ namespace Ndk
// Aucun intérêt de traiter une entité n'existant plus // Aucun intérêt de traiter une entité n'existant plus
if (entity.IsValid()) if (entity.IsValid())
{ {
for (auto& systemPair : m_systems) for (auto& system : m_systems)
{ {
BaseSystem* system = systemPair.second.get();
// L'entité est-elle enregistrée comme faisant partie du système ? // L'entité est-elle enregistrée comme faisant partie du système ?
bool partOfSystem = system->HasEntity(&entity); bool partOfSystem = system->HasEntity(&entity);
if (system->Filters(&entity)) if (system->Filters(&entity))