Remade component ids

No longer based on incrementing counter


Former-commit-id: b875e17781d8bcda48ea9ada523adf0823b22a8b
This commit is contained in:
Lynix 2015-03-17 19:53:59 +01:00
parent 0ba034f7e9
commit bc40fbb02f
14 changed files with 83 additions and 69 deletions

View File

@ -0,0 +1,20 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#pragma once
#ifndef NDK_ALGORITHM_HPP
#define NDK_ALGORITHM_HPP
#include <NDK/Prerequesites.hpp>
namespace Ndk
{
template<unsigned int N> ComponentId BuildComponentId(const char (&id)[N]);
template<typename ComponentType> constexpr ComponentId GetComponentId();
}
#include <Ndk/Algorithm.inl>
#endif // NDK_ALGORITHM_HPP

View File

@ -0,0 +1,27 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Development Kit"
// For conditions of distribution and use, see copyright notice in Prerequesites.hpp
#include <Nazara/Core/Endianness.hpp>
namespace Ndk
{
///TODO: constexpr avec le C++14
template<unsigned int N>
ComponentId BuildComponentId(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;
}
template<typename ComponentType>
constexpr ComponentId GetComponentId()
{
return ComponentType::ComponentId;
}
}

View File

@ -14,20 +14,15 @@ namespace Ndk
class NDK_API BaseComponent class NDK_API BaseComponent
{ {
public: public:
BaseComponent(nzUInt32 componentId); BaseComponent(ComponentId componentId);
virtual ~BaseComponent(); virtual ~BaseComponent();
virtual BaseComponent* Clone() const = 0; virtual BaseComponent* Clone() const = 0;
nzUInt32 GetId() const; ComponentId GetId() const;
static nzUInt32 GetNextId();
protected: protected:
nzUInt32 m_componentId; ComponentId m_componentId;
private:
static nzUInt32 s_nextId;
}; };
} }

View File

@ -4,18 +4,13 @@
namespace Ndk namespace Ndk
{ {
inline BaseComponent::BaseComponent(nzUInt32 componentId) : inline BaseComponent::BaseComponent(ComponentId componentId) :
m_componentId(componentId) m_componentId(componentId)
{ {
} }
inline nzUInt32 BaseComponent::GetId() const inline ComponentId BaseComponent::GetId() const
{ {
return m_componentId; return m_componentId;
} }
inline nzUInt32 BaseComponent::GetNextId()
{
return s_nextId++;
}
} }

View File

@ -20,8 +20,6 @@ namespace Ndk
BaseComponent* Clone() const override; BaseComponent* Clone() const override;
}; };
template<typename ComponentType> constexpr nzUInt32 GetComponentId();
} }
#include <NDK/Component.inl> #include <NDK/Component.inl>

View File

@ -2,6 +2,7 @@
// 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
@ -23,10 +24,4 @@ namespace Ndk
return new ComponentType(static_cast<const ComponentType&>(*this)); return new ComponentType(static_cast<const ComponentType&>(*this));
} }
template<typename ComponentType>
constexpr nzUInt32 GetComponentId()
{
return ComponentType::ComponentId;
}
} }

View File

@ -11,6 +11,7 @@
#include <NDK/Component.hpp> #include <NDK/Component.hpp>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <unordered_map>
namespace Ndk namespace Ndk
{ {
@ -23,8 +24,6 @@ namespace Ndk
friend World; friend World;
public: public:
using Id = nzUInt32;
Entity(const Entity&) = delete; Entity(const Entity&) = delete;
Entity(Entity&& entity); Entity(Entity&& entity);
~Entity(); ~Entity();
@ -34,13 +33,12 @@ namespace Ndk
EntityHandle CreateHandle(); EntityHandle CreateHandle();
BaseComponent& GetComponent(nzUInt32 componentId); BaseComponent& GetComponent(ComponentId componentId);
template<typename ComponentType> ComponentType& GetComponent(); template<typename ComponentType> ComponentType& GetComponent();
const NzBitset<>& GetComponentBits() const; EntityId GetId() const;
Id GetId() const;
World* GetWorld() const; World* GetWorld() const;
bool HasComponent(nzUInt32 componentId) const; bool HasComponent(ComponentId componentId) const;
template<typename ComponentType> bool HasComponent() const; template<typename ComponentType> bool HasComponent() const;
void Kill(); void Kill();
@ -48,14 +46,14 @@ namespace Ndk
bool IsValid() const; bool IsValid() const;
void RemoveAllComponents(); void RemoveAllComponents();
void RemoveComponent(nzUInt32 componentId); void RemoveComponent(ComponentId componentId);
template<typename ComponentType> void RemoveComponent(); template<typename ComponentType> void RemoveComponent();
Entity& operator=(const Entity&) = delete; Entity& operator=(const Entity&) = delete;
Entity& operator=(Entity&&) = delete; Entity& operator=(Entity&&) = delete;
private: private:
Entity(World& world, Id id); Entity(World& world, EntityId id);
void Create(); void Create();
void Destroy(); void Destroy();
@ -63,10 +61,9 @@ namespace Ndk
void RegisterHandle(EntityHandle* handle); void RegisterHandle(EntityHandle* handle);
void UnregisterHandle(EntityHandle* handle); void UnregisterHandle(EntityHandle* handle);
std::vector<std::unique_ptr<BaseComponent>> m_components;
std::vector<EntityHandle*> m_handles; std::vector<EntityHandle*> m_handles;
Id m_id; std::unordered_map<ComponentId, std::unique_ptr<BaseComponent>> m_components;
NzBitset<> m_componentBits; EntityId m_id;
World* m_world; World* m_world;
bool m_valid; bool m_valid;
}; };

View File

@ -9,7 +9,7 @@
namespace Ndk namespace Ndk
{ {
inline Entity::Entity(World& world, Id id) : inline Entity::Entity(World& world, EntityId id) :
m_id(id), m_id(id),
m_world(&world) m_world(&world)
{ {
@ -25,7 +25,7 @@ namespace Ndk
return static_cast<ComponentType&>(AddComponent(std::move(ptr))); return static_cast<ComponentType&>(AddComponent(std::move(ptr)));
} }
inline BaseComponent& Entity::GetComponent(nzUInt32 componentId) inline BaseComponent& Entity::GetComponent(ComponentId componentId)
{ {
///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(componentId), "This component is not part of the entity");
@ -42,16 +42,11 @@ 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");
nzUInt32 componentId = GetComponentId<ComponentType>(); ComponentId componentId = GetComponentId<ComponentType>();
return static_cast<ComponentType&>(GetComponent(componentId)); return static_cast<ComponentType&>(GetComponent(componentId));
} }
inline const NzBitset<>& Entity::GetComponentBits() const inline EntityId Entity::GetId() const
{
return m_componentBits;
}
inline Entity::Id Entity::GetId() const
{ {
return m_id; return m_id;
} }
@ -61,9 +56,9 @@ namespace Ndk
return m_world; return m_world;
} }
inline bool Entity::HasComponent(nzUInt32 componentId) const inline bool Entity::HasComponent(ComponentId componentId) const
{ {
return m_components.size() > componentId && m_components[componentId]; return m_components.count(componentId) > 0;
} }
template<typename ComponentType> template<typename ComponentType>
@ -71,7 +66,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");
nzUInt32 componentId = GetComponentId<ComponentType>(); ComponentId componentId = GetComponentId<ComponentType>();
return HasComponent(componentId); return HasComponent(componentId);
} }
@ -80,7 +75,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");
nzUInt32 componentId = GetComponentId<ComponentType>(); ComponentId componentId = GetComponentId<ComponentType>();
RemoveComponent(componentId); RemoveComponent(componentId);
} }

View File

@ -55,4 +55,10 @@
#define NDK_API #define NDK_API
#endif #endif
namespace Ndk
{
using ComponentId = nzUInt32;
using EntityId = nzUInt32;
}
#endif // NDK_PREREQUESITES_HPP #endif // NDK_PREREQUESITES_HPP

View File

@ -29,13 +29,13 @@ namespace Ndk
void Clear(); void Clear();
const EntityHandle& GetEntity(Entity::Id id); const EntityHandle& GetEntity(EntityId id);
void KillEntity(const EntityHandle& entity); void KillEntity(const EntityHandle& entity);
void KillEntities(const EntityList& list); void KillEntities(const EntityList& list);
bool IsEntityValid(const EntityHandle& entity) const; bool IsEntityValid(const EntityHandle& entity) const;
bool IsEntityIdValid(Entity::Id id) const; bool IsEntityIdValid(EntityId id) const;
void Update(); void Update();
@ -51,7 +51,7 @@ namespace Ndk
unsigned int aliveIndex; unsigned int aliveIndex;
}; };
std::vector<Entity::Id> m_freeIdList; std::vector<EntityId> m_freeIdList;
std::vector<EntityBlock> m_entities; std::vector<EntityBlock> m_entities;
EntityList m_aliveEntities; EntityList m_aliveEntities;
NzBitset<nzUInt64> m_killedEntities; NzBitset<nzUInt64> m_killedEntities;

View File

@ -28,7 +28,7 @@ namespace Ndk
return entity.IsValid() && entity->GetWorld() == this && IsEntityIdValid(entity->GetId()); return entity.IsValid() && entity->GetWorld() == this && IsEntityIdValid(entity->GetId());
} }
inline bool World::IsEntityIdValid(Entity::Id id) const inline bool World::IsEntityIdValid(EntityId id) const
{ {
return id < m_entities.size() && m_entities[id].entity.IsValid(); return id < m_entities.size() && m_entities[id].entity.IsValid();
} }

View File

@ -7,6 +7,4 @@
namespace Ndk namespace Ndk
{ {
BaseComponent::~BaseComponent() = default; BaseComponent::~BaseComponent() = default;
nzUInt32 BaseComponent::s_nextId = 0;
} }

View File

@ -27,18 +27,10 @@ namespace Ndk
{ {
NazaraAssert(component, "Component must be valid"); NazaraAssert(component, "Component must be valid");
nzUInt32 componentId = component->GetId(); ComponentId componentId = component->GetId();
// Nous supprimons l'ancien component, s'il existe
RemoveComponent(componentId);
// Nous nous assurons que le vecteur de component est suffisamment grand pour contenir le nouveau component
if (m_components.size() <= componentId)
m_components.resize(componentId + 1);
// Affectation et retour du component // Affectation et retour du component
m_components[componentId] = std::move(component); m_components[componentId] = std::move(component);
m_componentBits.UnboundedSet(componentId);
return *m_components[componentId].get(); return *m_components[componentId].get();
} }
@ -61,17 +53,13 @@ namespace Ndk
void Entity::RemoveAllComponents() void Entity::RemoveAllComponents()
{ {
m_components.clear(); m_components.clear();
m_componentBits.Clear();
} }
void Entity::RemoveComponent(nzUInt32 componentId) void Entity::RemoveComponent(ComponentId componentId)
{ {
///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(componentId))
{
m_components[componentId].reset(); m_components[componentId].reset();
m_componentBits.Reset(componentId);
}
} }
void Entity::Create() void Entity::Create()

View File

@ -15,7 +15,7 @@ namespace Ndk
EntityHandle World::CreateEntity() EntityHandle World::CreateEntity()
{ {
Entity::Id id; EntityId id;
if (!m_freeIdList.empty()) if (!m_freeIdList.empty())
{ {
// On récupère un identifiant // On récupère un identifiant
@ -62,7 +62,7 @@ namespace Ndk
m_killedEntities.UnboundedSet(entity->GetId(), true); m_killedEntities.UnboundedSet(entity->GetId(), true);
} }
const EntityHandle& World::GetEntity(Entity::Id id) const EntityHandle& World::GetEntity(EntityId id)
{ {
if (IsEntityIdValid(id)) if (IsEntityIdValid(id))
return m_aliveEntities[m_entities[id].aliveIndex]; return m_aliveEntities[m_entities[id].aliveIndex];