Re-remade component and system ids
Former-commit-id: 98b76695cca904c55c7333801c3cdf693da15086
This commit is contained in:
parent
3fd217b8a3
commit
6d1ac4fe18
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ namespace Ndk
|
||||||
{
|
{
|
||||||
template<typename SystemType>
|
template<typename SystemType>
|
||||||
System<SystemType>::System() :
|
System<SystemType>::System() :
|
||||||
BaseSystem(GetSystemId<SystemType>())
|
BaseSystem(GetSystemIndex<SystemType>())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue