Improved interface

EntityHandle are no longer required to pass Entity as arguments
World::CreateEntity() now returns a const EntityHandle&

Former-commit-id: 6fc53ce5759a2a508094bdc61b4471f13f0844ec
This commit is contained in:
Lynix 2015-03-18 00:49:44 +01:00
parent e91313b62d
commit be8f6edeb4
9 changed files with 117 additions and 33 deletions

View File

@ -27,13 +27,13 @@ namespace Ndk
virtual BaseSystem* Clone() const = 0; virtual BaseSystem* Clone() const = 0;
bool Filters(const EntityHandle& entity) const; bool Filters(const Entity* entity) const;
const std::vector<EntityHandle>& GetEntities() const; const std::vector<EntityHandle>& GetEntities() const;
SystemId GetId() const; SystemId GetId() const;
World& GetWorld() const; World& GetWorld() const;
bool HasEntity(const EntityHandle& entity) const; bool HasEntity(const Entity* entity) const;
protected: protected:
template<typename ComponentType> void Excludes(); template<typename ComponentType> void Excludes();
@ -45,12 +45,12 @@ namespace Ndk
void RequiresComponent(ComponentId componentId); void RequiresComponent(ComponentId componentId);
private: private:
void AddEntity(const EntityHandle& entity); void AddEntity(Entity* entity);
virtual void OnEntityAdded(const EntityHandle& entity); virtual void OnEntityAdded(Entity* entity);
virtual void OnEntityRemoved(const EntityHandle& entity); virtual void OnEntityRemoved(Entity* entity);
void RemoveEntity(const EntityHandle& entity); void RemoveEntity(Entity* entity);
void SetWorld(World& world); void SetWorld(World& world);

View File

@ -27,8 +27,11 @@ namespace Ndk
return *m_world; return *m_world;
} }
inline bool BaseSystem::HasEntity(const EntityHandle& entity) const inline bool BaseSystem::HasEntity(const Entity* entity) const
{ {
if (!entity)
return false;
return m_entityBits.UnboundedTest(entity->GetId()); return m_entityBits.UnboundedTest(entity->GetId());
} }
@ -72,9 +75,11 @@ namespace Ndk
m_requiredComponents.insert(componentId); m_requiredComponents.insert(componentId);
} }
inline void BaseSystem::AddEntity(const EntityHandle& entity) inline void BaseSystem::AddEntity(Entity* entity)
{ {
m_entities.push_back(entity); NazaraAssert(entity, "Invalid entity");
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_systemId);
@ -82,9 +87,11 @@ namespace Ndk
OnEntityAdded(entity); OnEntityAdded(entity);
} }
inline void BaseSystem::RemoveEntity(const EntityHandle& entity) inline void BaseSystem::RemoveEntity(Entity* entity)
{ {
auto it = std::find(m_entities.begin(), m_entities.end(), entity); NazaraAssert(entity, "Invalid entity");
auto it = std::find(m_entities.begin(), m_entities.end(), *entity);
NazaraAssert(it != m_entities.end(), "Entity is not part of this system"); NazaraAssert(it != m_entities.end(), "Entity is not part of this system");
// Pour éviter de déplacer beaucoup de handles, on swap le dernier avec celui à supprimer // Pour éviter de déplacer beaucoup de handles, on swap le dernier avec celui à supprimer

View File

@ -44,11 +44,28 @@ namespace Ndk
friend std::ostream& operator<<(std::ostream& out, const EntityHandle& handle); friend std::ostream& operator<<(std::ostream& out, const EntityHandle& handle);
friend bool operator==(const EntityHandle& lhs, const EntityHandle& rhs); friend bool operator==(const EntityHandle& lhs, const EntityHandle& rhs);
friend bool operator==(const Entity& lhs, const EntityHandle& rhs);
friend bool operator==(const EntityHandle& lhs, const Entity& rhs);
friend bool operator!=(const EntityHandle& lhs, const EntityHandle& rhs); friend bool operator!=(const EntityHandle& lhs, const EntityHandle& rhs);
friend bool operator!=(const Entity& lhs, const EntityHandle& rhs);
friend bool operator!=(const EntityHandle& lhs, const Entity& rhs);
friend bool operator<(const EntityHandle& lhs, const EntityHandle& rhs); friend bool operator<(const EntityHandle& lhs, const EntityHandle& rhs);
friend bool operator<(const Entity& lhs, const EntityHandle& rhs);
friend bool operator<(const EntityHandle& lhs, const Entity& rhs);
friend bool operator<=(const EntityHandle& lhs, const EntityHandle& rhs); friend bool operator<=(const EntityHandle& lhs, const EntityHandle& rhs);
friend bool operator<=(const Entity& lhs, const EntityHandle& rhs);
friend bool operator<=(const EntityHandle& lhs, const Entity& rhs);
friend bool operator>(const EntityHandle& lhs, const EntityHandle& rhs); friend bool operator>(const EntityHandle& lhs, const EntityHandle& rhs);
friend bool operator>(const Entity& lhs, const EntityHandle& rhs);
friend bool operator>(const EntityHandle& lhs, const Entity& rhs);
friend bool operator>=(const EntityHandle& lhs, const EntityHandle& rhs); friend bool operator>=(const EntityHandle& lhs, const EntityHandle& rhs);
friend bool operator>=(const Entity& lhs, const EntityHandle& rhs);
friend bool operator>=(const EntityHandle& lhs, const Entity& rhs);
private: private:
void OnEntityDestroyed(); void OnEntityDestroyed();

View File

@ -149,30 +149,90 @@ namespace Ndk
return lhs.m_entity == rhs.m_entity; return lhs.m_entity == rhs.m_entity;
} }
inline bool operator==(const Entity& lhs, const EntityHandle& rhs)
{
return &lhs == rhs.m_entity;
}
inline bool operator==(const EntityHandle& lhs, const Entity& rhs)
{
return lhs.m_entity == &rhs;
}
inline bool operator!=(const EntityHandle& lhs, const EntityHandle& rhs) inline bool operator!=(const EntityHandle& lhs, const EntityHandle& rhs)
{ {
return !(lhs == rhs); return !(lhs == rhs);
} }
inline bool operator!=(const Entity& lhs, const EntityHandle& rhs)
{
return !(lhs == rhs);
}
inline bool operator!=(const EntityHandle& lhs, const Entity& rhs)
{
return !(lhs == rhs);
}
inline bool operator<(const EntityHandle& lhs, const EntityHandle& rhs) inline bool operator<(const EntityHandle& lhs, const EntityHandle& rhs)
{ {
return lhs.m_entity < rhs.m_entity; return lhs.m_entity < rhs.m_entity;
} }
inline bool operator<(const Entity& lhs, const EntityHandle& rhs)
{
return &lhs < rhs.m_entity;
}
inline bool operator<(const EntityHandle& lhs, const Entity& rhs)
{
return lhs.m_entity < &rhs;
}
inline bool operator<=(const EntityHandle& lhs, const EntityHandle& rhs) inline bool operator<=(const EntityHandle& lhs, const EntityHandle& rhs)
{ {
return !(lhs > rhs); return !(lhs > rhs);
} }
inline bool operator<=(const Entity& lhs, const EntityHandle& rhs)
{
return !(lhs > rhs);
}
inline bool operator<=(const EntityHandle& lhs, const Entity& rhs)
{
return !(lhs > rhs);
}
inline bool operator>(const EntityHandle& lhs, const EntityHandle& rhs) inline bool operator>(const EntityHandle& lhs, const EntityHandle& rhs)
{ {
return rhs < lhs; return rhs < lhs;
} }
inline bool operator>(const Entity& lhs, const EntityHandle& rhs)
{
return rhs < lhs;
}
inline bool operator>(const EntityHandle& lhs, const Entity& rhs)
{
return rhs < lhs;
}
inline bool operator>=(const EntityHandle& lhs, const EntityHandle& rhs) inline bool operator>=(const EntityHandle& lhs, const EntityHandle& rhs)
{ {
return !(lhs < rhs); return !(lhs < rhs);
} }
inline bool operator>=(const Entity& lhs, const EntityHandle& rhs)
{
return !(lhs < rhs);
}
inline bool operator>=(const EntityHandle& lhs, const Entity& rhs)
{
return !(lhs < rhs);
}
} }
namespace std namespace std

View File

@ -32,7 +32,7 @@ namespace Ndk
BaseSystem& AddSystem(std::unique_ptr<BaseSystem>&& system); BaseSystem& AddSystem(std::unique_ptr<BaseSystem>&& system);
template<typename SystemType, typename... Args> SystemType& AddSystem(Args&&... args); template<typename SystemType, typename... Args> SystemType& AddSystem(Args&&... args);
EntityHandle CreateEntity(); const EntityHandle& CreateEntity();
EntityList CreateEntities(unsigned int count); EntityList CreateEntities(unsigned int count);
void Clear(); void Clear();
@ -44,10 +44,10 @@ namespace Ndk
bool HasSystem(SystemId systemId) const; bool HasSystem(SystemId systemId) const;
template<typename SystemType> bool HasSystem() const; template<typename SystemType> bool HasSystem() const;
void KillEntity(const EntityHandle& entity); void KillEntity(Entity* entity);
void KillEntities(const EntityList& list); void KillEntities(const EntityList& list);
bool IsEntityValid(const EntityHandle& entity) const; bool IsEntityValid(const Entity* entity) const;
bool IsEntityIdValid(EntityId id) const; bool IsEntityIdValid(EntityId id) const;
void RemoveAllSystems(); void RemoveAllSystems();

View File

@ -84,9 +84,9 @@ namespace Ndk
KillEntity(entity); KillEntity(entity);
} }
inline bool World::IsEntityValid(const EntityHandle& entity) const inline bool World::IsEntityValid(const Entity* entity) const
{ {
return entity.IsValid() && entity->GetWorld() == this && IsEntityIdValid(entity->GetId()); return entity && entity->GetWorld() == this && IsEntityIdValid(entity->GetId());
} }
inline bool World::IsEntityIdValid(EntityId id) const inline bool World::IsEntityIdValid(EntityId id) const

View File

@ -12,8 +12,11 @@ namespace Ndk
entity->UnregisterSystem(m_systemId); entity->UnregisterSystem(m_systemId);
} }
bool BaseSystem::Filters(const EntityHandle& entity) const bool BaseSystem::Filters(const Entity* entity) const
{ {
if (!entity)
return false;
for (ComponentId component : m_requiredComponents) for (ComponentId component : m_requiredComponents)
{ {
if (!entity->HasComponent(component)) if (!entity->HasComponent(component))
@ -29,12 +32,12 @@ namespace Ndk
return true; return true;
} }
void BaseSystem::OnEntityAdded(const EntityHandle& entity) void BaseSystem::OnEntityAdded(Entity* entity)
{ {
NazaraUnused(entity); NazaraUnused(entity);
} }
void BaseSystem::OnEntityRemoved(const EntityHandle& entity) void BaseSystem::OnEntityRemoved(Entity* entity)
{ {
NazaraUnused(entity); NazaraUnused(entity);
} }

View File

@ -45,7 +45,7 @@ namespace Ndk
void Entity::Kill() void Entity::Kill()
{ {
m_world->KillEntity(CreateHandle()); m_world->KillEntity(this);
} }
bool Entity::IsValid() const bool Entity::IsValid() const
@ -88,7 +88,7 @@ namespace Ndk
if (m_world->HasSystem(systemId)) if (m_world->HasSystem(systemId))
{ {
BaseSystem& system = m_world->GetSystem(systemId); BaseSystem& system = m_world->GetSystem(systemId);
system.RemoveEntity(CreateHandle()); system.RemoveEntity(this);
} }
} }
m_systems.clear(); m_systems.clear();

View File

@ -13,7 +13,7 @@ namespace Ndk
Clear(); Clear();
} }
EntityHandle World::CreateEntity() const EntityHandle& World::CreateEntity()
{ {
EntityId id; EntityId id;
if (!m_freeIdList.empty()) if (!m_freeIdList.empty())
@ -35,11 +35,10 @@ namespace Ndk
Entity& entity = m_entities[id].entity; Entity& entity = m_entities[id].entity;
entity.Create(); entity.Create();
EntityHandle handle = entity.CreateHandle(); m_aliveEntities.emplace_back(&entity);
m_aliveEntities.push_back(handle);
m_entities[id].aliveIndex = m_aliveEntities.size()-1; m_entities[id].aliveIndex = m_aliveEntities.size()-1;
return handle; return m_aliveEntities.back();
} }
void World::Clear() void World::Clear()
@ -54,7 +53,7 @@ namespace Ndk
m_killedEntities.Clear(); m_killedEntities.Clear();
} }
void World::KillEntity(const EntityHandle& entity) void World::KillEntity(Entity* entity)
{ {
///DOC: Ignoré si l'entité est invalide ///DOC: Ignoré si l'entité est invalide
@ -111,9 +110,7 @@ namespace Ndk
{ {
NazaraAssert(i < m_entities.size(), "Entity index out of range"); NazaraAssert(i < m_entities.size(), "Entity index out of range");
EntityBlock& block = m_entities[i]; Entity& entity = m_entities[i].entity;
Entity& entity = block.entity;
EntityHandle& handle = m_aliveEntities[block.aliveIndex];
// 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())
@ -123,20 +120,20 @@ namespace Ndk
BaseSystem* system = systemPair.second.get(); 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(handle); bool partOfSystem = system->HasEntity(&entity);
if (system->Filters(handle)) if (system->Filters(&entity))
{ {
// L'entité doit faire partie du système, est-ce que c'est déjà le cas ? // L'entité doit faire partie du système, est-ce que c'est déjà le cas ?
if (!partOfSystem) if (!partOfSystem)
// Non, rajoutons-là // Non, rajoutons-là
system->AddEntity(handle); system->AddEntity(&entity);
} }
else else
{ {
// L'entité ne doit pas faire partie du système, était-ce le cas ? // L'entité ne doit pas faire partie du système, était-ce le cas ?
if (partOfSystem) if (partOfSystem)
// Oui, enlevons-là // Oui, enlevons-là
system->RemoveEntity(handle); system->RemoveEntity(&entity);
} }
} }
} }