Remade Entities
Former-commit-id: 25f7bc84279fdf58b44cf78e2d94b4cbb78a8410
This commit is contained in:
parent
1d79efeb7f
commit
3a18035989
|
|
@ -8,57 +8,50 @@
|
||||||
#define NDK_ENTITY_HPP
|
#define NDK_ENTITY_HPP
|
||||||
|
|
||||||
#include <NDK/Prerequesites.hpp>
|
#include <NDK/Prerequesites.hpp>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
namespace Ndk
|
namespace Ndk
|
||||||
{
|
{
|
||||||
|
class EntityHandle;
|
||||||
class World;
|
class World;
|
||||||
|
|
||||||
class NDK_API Entity
|
class NDK_API Entity
|
||||||
{
|
{
|
||||||
|
friend EntityHandle;
|
||||||
friend World;
|
friend World;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class Id;
|
using Id = nzUInt32;
|
||||||
|
|
||||||
Entity();
|
Entity(const Entity&) = delete;
|
||||||
Entity(const Entity&) = default;
|
Entity(Entity&& entity);
|
||||||
~Entity() = default;
|
~Entity();
|
||||||
|
|
||||||
void Kill();
|
EntityHandle CreateHandle();
|
||||||
|
|
||||||
Id GetId() const;
|
Id GetId() const;
|
||||||
World* GetWorld() const;
|
World* GetWorld() const;
|
||||||
|
|
||||||
|
void Kill();
|
||||||
|
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
|
|
||||||
Entity& operator=(const Entity&) = default;
|
Entity& operator=(const Entity&) = delete;
|
||||||
|
Entity& operator=(Entity&&) = delete;
|
||||||
bool operator==(const Entity& other) const;
|
|
||||||
bool operator!=(const Entity& other) const;
|
|
||||||
|
|
||||||
// Identifiant
|
|
||||||
struct Id
|
|
||||||
{
|
|
||||||
struct Part
|
|
||||||
{
|
|
||||||
nzUInt32 counter, index;
|
|
||||||
};
|
|
||||||
|
|
||||||
union
|
|
||||||
{
|
|
||||||
Part part;
|
|
||||||
nzUInt64 value;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool operator==(const Id& other) const;
|
|
||||||
bool operator!=(const Id& other) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Entity(Id id, World* world);
|
Entity(World& world, Id id);
|
||||||
|
|
||||||
|
void Create();
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
|
void RegisterHandle(EntityHandle* handle);
|
||||||
|
void UnregisterHandle(EntityHandle* handle);
|
||||||
|
|
||||||
|
std::set<EntityHandle*> m_handles;
|
||||||
Id m_id;
|
Id m_id;
|
||||||
World* m_world;
|
World* m_world;
|
||||||
|
bool m_valid;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,9 @@
|
||||||
|
|
||||||
namespace Ndk
|
namespace Ndk
|
||||||
{
|
{
|
||||||
inline Entity::Entity() :
|
inline Entity::Entity(World& world, Id id) :
|
||||||
m_world(nullptr)
|
|
||||||
{
|
|
||||||
m_id.value = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Entity::Entity(Id id, World* world) :
|
|
||||||
m_id(id),
|
m_id(id),
|
||||||
m_world(world)
|
m_world(&world)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,23 +22,13 @@ namespace Ndk
|
||||||
return m_world;
|
return m_world;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Entity::operator==(const Entity& other) const
|
inline void Entity::RegisterHandle(EntityHandle* handle)
|
||||||
{
|
{
|
||||||
return m_world == other.m_world && m_id == other.m_id;
|
m_handles.insert(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool Entity::operator!=(const Entity& other) const
|
inline void Entity::UnregisterHandle(EntityHandle* handle)
|
||||||
{
|
{
|
||||||
return !operator==(other);
|
m_handles.erase(handle);
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Entity::Id::operator==(const Id& other) const
|
|
||||||
{
|
|
||||||
return value == other.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Entity::Id::operator!=(const Id& other) const
|
|
||||||
{
|
|
||||||
return !operator==(other);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
// 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_ENTITYHANDLE_HPP
|
||||||
|
#define NDK_ENTITYHANDLE_HPP
|
||||||
|
|
||||||
|
#include <NDK/Prerequesites.hpp>
|
||||||
|
#include <NDK/Entity.hpp>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace Ndk
|
||||||
|
{
|
||||||
|
class Entity;
|
||||||
|
|
||||||
|
class EntityHandle
|
||||||
|
{
|
||||||
|
friend Entity;
|
||||||
|
|
||||||
|
public:
|
||||||
|
EntityHandle();
|
||||||
|
explicit EntityHandle(Entity* entity);
|
||||||
|
EntityHandle(const EntityHandle& handle);
|
||||||
|
EntityHandle(EntityHandle&& handle);
|
||||||
|
~EntityHandle();
|
||||||
|
|
||||||
|
Entity* GetEntity() const;
|
||||||
|
|
||||||
|
bool IsValid() const;
|
||||||
|
|
||||||
|
void Reset(Entity* entity = nullptr);
|
||||||
|
void Reset(const EntityHandle& handle);
|
||||||
|
void Reset(EntityHandle&& handle);
|
||||||
|
|
||||||
|
EntityHandle& Swap(EntityHandle& handle);
|
||||||
|
|
||||||
|
operator bool() const;
|
||||||
|
operator Entity*() const;
|
||||||
|
Entity* operator->() const;
|
||||||
|
|
||||||
|
EntityHandle& operator=(Entity* entity);
|
||||||
|
EntityHandle& operator=(const EntityHandle& handle);
|
||||||
|
EntityHandle& operator=(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 EntityHandle& lhs, const EntityHandle& rhs);
|
||||||
|
friend bool operator<=(const EntityHandle& lhs, const EntityHandle& rhs);
|
||||||
|
friend bool operator>(const EntityHandle& lhs, const EntityHandle& rhs);
|
||||||
|
friend bool operator>=(const EntityHandle& lhs, const EntityHandle& rhs);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void OnEntityDestroyed();
|
||||||
|
void OnEntityMoved(Entity* newEntity);
|
||||||
|
|
||||||
|
Entity* m_entity;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
void swap(Ndk::EntityHandle& lhs, Ndk::EntityHandle& rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <NDK/EntityHandle.inl>
|
||||||
|
|
||||||
|
#endif // NDK_ENTITYHANDLE_HPP
|
||||||
|
|
@ -0,0 +1,177 @@
|
||||||
|
// 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 <functional>
|
||||||
|
|
||||||
|
namespace Ndk
|
||||||
|
{
|
||||||
|
inline EntityHandle::EntityHandle() :
|
||||||
|
m_entity(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
inline EntityHandle::EntityHandle(Entity* entity) :
|
||||||
|
EntityHandle()
|
||||||
|
{
|
||||||
|
Reset(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline EntityHandle::EntityHandle(const EntityHandle& handle) :
|
||||||
|
EntityHandle()
|
||||||
|
{
|
||||||
|
Reset(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline EntityHandle::EntityHandle(EntityHandle&& handle) :
|
||||||
|
EntityHandle()
|
||||||
|
{
|
||||||
|
Reset(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline EntityHandle::~EntityHandle()
|
||||||
|
{
|
||||||
|
Reset(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Entity* EntityHandle::GetEntity() const
|
||||||
|
{
|
||||||
|
return m_entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool EntityHandle::IsValid() const
|
||||||
|
{
|
||||||
|
return m_entity != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void EntityHandle::Reset(Entity* entity)
|
||||||
|
{
|
||||||
|
// Si nous avions déjà une entité, nous devons l'informer que nous ne pointons plus vers elle
|
||||||
|
if (m_entity)
|
||||||
|
m_entity->UnregisterHandle(this);
|
||||||
|
|
||||||
|
m_entity = entity;
|
||||||
|
if (m_entity)
|
||||||
|
// On informe la nouvelle entité que nous pointons vers elle
|
||||||
|
m_entity->RegisterHandle(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void EntityHandle::Reset(const EntityHandle& handle)
|
||||||
|
{
|
||||||
|
Reset(handle.GetEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void EntityHandle::Reset(EntityHandle&& handle)
|
||||||
|
{
|
||||||
|
Reset(handle.GetEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline EntityHandle& EntityHandle::Swap(EntityHandle& handle)
|
||||||
|
{
|
||||||
|
std::swap(m_entity, handle.m_entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline EntityHandle::operator bool() const
|
||||||
|
{
|
||||||
|
return IsValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline EntityHandle::operator Entity*() const
|
||||||
|
{
|
||||||
|
return m_entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Entity* EntityHandle::operator->() const
|
||||||
|
{
|
||||||
|
return m_entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline EntityHandle& EntityHandle::operator=(Entity* entity)
|
||||||
|
{
|
||||||
|
Reset(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline EntityHandle& EntityHandle::operator=(const EntityHandle& handle)
|
||||||
|
{
|
||||||
|
Reset(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline EntityHandle& EntityHandle::operator=(EntityHandle&& handle)
|
||||||
|
{
|
||||||
|
Reset(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void EntityHandle::OnEntityDestroyed()
|
||||||
|
{
|
||||||
|
// Un raccourci, un appel à Reset nous enlèverait de la liste des handles que nous ne pouvons pas modifier
|
||||||
|
// maintenant car elle est actuellement parcourue
|
||||||
|
m_entity = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void EntityHandle::OnEntityMoved(Entity* newEntity)
|
||||||
|
{
|
||||||
|
// L'entité a été déplacée (peut arriver lors d'un changement de taille du conteneur du monde)
|
||||||
|
// nous mettons à jour notre pointeur
|
||||||
|
m_entity = newEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream& operator<<(std::ostream& out, const EntityHandle& handle)
|
||||||
|
{
|
||||||
|
out << "EntityHandle(";
|
||||||
|
if (handle.IsValid())
|
||||||
|
out << "Entity(" << handle->GetId() << ")";
|
||||||
|
else
|
||||||
|
out << "Null entity";
|
||||||
|
|
||||||
|
out << ')';
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const EntityHandle& lhs, const EntityHandle& rhs)
|
||||||
|
{
|
||||||
|
return lhs.m_entity == rhs.m_entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(const EntityHandle& lhs, const EntityHandle& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator<(const EntityHandle& lhs, const EntityHandle& rhs)
|
||||||
|
{
|
||||||
|
return lhs.m_entity < rhs.m_entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator<=(const EntityHandle& lhs, const EntityHandle& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs > rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator>(const EntityHandle& lhs, const EntityHandle& rhs)
|
||||||
|
{
|
||||||
|
return rhs < lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator>=(const EntityHandle& lhs, const EntityHandle& rhs)
|
||||||
|
{
|
||||||
|
return !(lhs < rhs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template<>
|
||||||
|
struct hash<Ndk::EntityHandle>
|
||||||
|
{
|
||||||
|
size_t operator()(const Ndk::EntityHandle& handle) const
|
||||||
|
{
|
||||||
|
return hash<Ndk::Entity*>()(handle.GetEntity());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void swap(Ndk::EntityHandle& lhs, Ndk::EntityHandle& rhs)
|
||||||
|
{
|
||||||
|
lhs.Swap(rhs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,39 +10,41 @@
|
||||||
#include <Nazara/Core/NonCopyable.hpp>
|
#include <Nazara/Core/NonCopyable.hpp>
|
||||||
#include <NDK/Prerequesites.hpp>
|
#include <NDK/Prerequesites.hpp>
|
||||||
#include <NDK/Entity.hpp>
|
#include <NDK/Entity.hpp>
|
||||||
|
#include <NDK/EntityHandle.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Ndk
|
namespace Ndk
|
||||||
{
|
{
|
||||||
|
class EntityHandle;
|
||||||
|
|
||||||
class NDK_API World : NzNonCopyable
|
class NDK_API World : NzNonCopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using EntityList = std::vector<Entity>;
|
using EntityList = std::vector<EntityHandle>;
|
||||||
|
|
||||||
World();
|
World() = default;
|
||||||
~World() = default;
|
~World();
|
||||||
|
|
||||||
Entity CreateEntity();
|
EntityHandle CreateEntity();
|
||||||
EntityList CreateEntities(unsigned int count);
|
EntityList CreateEntities(unsigned int count);
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
void KillEntity(Entity& entity);
|
void KillEntity(Entity* entity);
|
||||||
void KillEntities(EntityList& list);
|
void KillEntities(const EntityList& list);
|
||||||
|
|
||||||
Entity GetEntity(Entity::Id id);
|
Entity* GetEntity(Entity::Id id);
|
||||||
|
|
||||||
bool IsEntityValid(const Entity& entity) const;
|
bool IsEntityValid(Entity* entity) const;
|
||||||
bool IsEntityIdValid(Entity::Id id) const;
|
bool IsEntityIdValid(Entity::Id id) const;
|
||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<nzUInt32> m_entitiesCounter;
|
|
||||||
std::vector<Entity::Id> m_freeIdList;
|
std::vector<Entity::Id> m_freeIdList;
|
||||||
|
std::vector<Entity> m_entities;
|
||||||
EntityList m_aliveEntities;
|
EntityList m_aliveEntities;
|
||||||
EntityList m_killedEntities;
|
EntityList m_killedEntities;
|
||||||
nzUInt32 m_nextIndex;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,40 +4,31 @@
|
||||||
|
|
||||||
namespace Ndk
|
namespace Ndk
|
||||||
{
|
{
|
||||||
inline World::World() :
|
|
||||||
m_nextIndex(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline World::EntityList World::CreateEntities(unsigned int count)
|
inline World::EntityList World::CreateEntities(unsigned int count)
|
||||||
{
|
{
|
||||||
EntityList list;
|
EntityList list;
|
||||||
list.reserve(count);
|
list.reserve(count);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
list.push_back(CreateEntity());
|
list.emplace_back(CreateEntity());
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void World::KillEntities(EntityList& list)
|
inline void World::KillEntities(const EntityList& list)
|
||||||
{
|
{
|
||||||
m_killedEntities.reserve(m_killedEntities.size() + list.size());
|
m_killedEntities.reserve(m_killedEntities.size() + list.size());
|
||||||
for (Entity& entity : list)
|
for (const EntityHandle& entity : list)
|
||||||
KillEntity(entity);
|
KillEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool World::IsEntityValid(const Entity& entity) const
|
inline bool World::IsEntityValid(Entity* entity) const
|
||||||
{
|
{
|
||||||
///DOC: Cette méthode vérifie également l'appartenance de l'entité au monde (et est donc plus sûre)
|
return entity != nullptr && entity->GetWorld() == this && IsEntityIdValid(entity->GetId());
|
||||||
return entity.GetWorld() == this && IsEntityIdValid(entity.GetId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool World::IsEntityIdValid(Entity::Id id) const
|
inline bool World::IsEntityIdValid(Entity::Id id) const
|
||||||
{
|
{
|
||||||
///DOC: Il est possible que si l'identifiant vienne d'un autre monde, il soit considéré valide
|
return id < m_entities.size() && m_entities[id].IsValid();
|
||||||
/// alors qu'aucune entité de ce monde-ci ne l'utilise (encore)
|
|
||||||
|
|
||||||
return m_entitiesCounter[id.part.index] == id.part.counter;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,52 @@
|
||||||
// This file was automatically generated on 26 May 2014 at 01:05:31
|
// This file was automatically generated on 26 May 2014 at 01:05:31
|
||||||
|
|
||||||
#include <NDK/Entity.hpp>
|
#include <NDK/Entity.hpp>
|
||||||
|
#include <NDK/EntityHandle.hpp>
|
||||||
#include <NDK/World.hpp>
|
#include <NDK/World.hpp>
|
||||||
|
|
||||||
namespace Ndk
|
namespace Ndk
|
||||||
{
|
{
|
||||||
|
Entity::Entity(Entity&& entity) :
|
||||||
|
m_handles(std::move(entity.m_handles)),
|
||||||
|
m_id(entity.m_id),
|
||||||
|
m_world(entity.m_world),
|
||||||
|
m_valid(entity.m_valid)
|
||||||
|
{
|
||||||
|
for (EntityHandle* handle : m_handles)
|
||||||
|
handle->OnEntityMoved(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Entity::~Entity()
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityHandle Entity::CreateHandle()
|
||||||
|
{
|
||||||
|
return EntityHandle(this);
|
||||||
|
}
|
||||||
|
|
||||||
void Entity::Kill()
|
void Entity::Kill()
|
||||||
{
|
{
|
||||||
m_world->KillEntity(*this);
|
m_world->KillEntity(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Entity::IsValid() const
|
bool Entity::IsValid() const
|
||||||
{
|
{
|
||||||
return m_world != nullptr && m_world->IsEntityIdValid(m_id);
|
return m_valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::Create()
|
||||||
|
{
|
||||||
|
m_valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Entity::Destroy()
|
||||||
|
{
|
||||||
|
m_valid = false;
|
||||||
|
|
||||||
|
// On informe chaque handle de notre destruction pour éviter qu'il ne continue de pointer sur nous
|
||||||
|
for (EntityHandle* handle : m_handles)
|
||||||
|
handle->OnEntityDestroyed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,13 @@
|
||||||
|
|
||||||
namespace Ndk
|
namespace Ndk
|
||||||
{
|
{
|
||||||
Entity World::CreateEntity()
|
World::~World()
|
||||||
|
{
|
||||||
|
// La destruction doit se faire dans un ordre précis
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityHandle World::CreateEntity()
|
||||||
{
|
{
|
||||||
Entity::Id id;
|
Entity::Id id;
|
||||||
if (!m_freeIdList.empty())
|
if (!m_freeIdList.empty())
|
||||||
|
|
@ -16,19 +22,17 @@ namespace Ndk
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// On alloue un nouvel identifiant
|
// On alloue une nouvelle entité
|
||||||
m_entitiesCounter.resize(m_entitiesCounter.size() + 1);
|
id = m_entities.size();
|
||||||
|
|
||||||
auto& counter = m_entitiesCounter.back();
|
// Impossible d'utiliser emplace_back à cause de la portée
|
||||||
counter = 1;
|
m_entities.push_back(Entity(*this, id));
|
||||||
|
|
||||||
id.part.counter = counter;
|
|
||||||
id.part.index = m_nextIndex;
|
|
||||||
|
|
||||||
m_nextIndex++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity entity(id, this);
|
EntityHandle entity = m_entities[id].CreateHandle();
|
||||||
|
|
||||||
|
// On initialise l'entité et on l'ajoute à la liste des entités vivantes
|
||||||
|
entity->Create();
|
||||||
m_aliveEntities.push_back(entity);
|
m_aliveEntities.push_back(entity);
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
|
|
@ -36,33 +40,32 @@ namespace Ndk
|
||||||
|
|
||||||
void World::Clear()
|
void World::Clear()
|
||||||
{
|
{
|
||||||
///DOC: Les handles existants avant Clear ne sont plus garantis de ne pas être réutilisés
|
///DOC: Tous les handles sont correctement invalidés
|
||||||
/// et devraient être détruits avant la création d'une nouvelle entité.
|
|
||||||
|
// Destruction des entités d'abord, et des handles ensuite
|
||||||
|
// ceci pour éviter que les handles n'informent les entités inutilement lors de leur destruction
|
||||||
|
m_entities.clear();
|
||||||
|
|
||||||
m_aliveEntities.clear();
|
m_aliveEntities.clear();
|
||||||
m_entitiesCounter.clear();
|
|
||||||
m_freeIdList.clear();
|
|
||||||
m_killedEntities.clear();
|
m_killedEntities.clear();
|
||||||
|
|
||||||
m_nextIndex = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::KillEntity(Entity& entity)
|
void World::KillEntity(Entity* entity)
|
||||||
{
|
{
|
||||||
///DOC: Ignoré si l'entité est invalide
|
///DOC: Ignoré si l'entité est invalide
|
||||||
|
|
||||||
if (IsEntityValid(entity))
|
if (IsEntityValid(entity))
|
||||||
m_killedEntities.push_back(entity);
|
m_killedEntities.emplace_back(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity World::GetEntity(Entity::Id id)
|
Entity* World::GetEntity(Entity::Id id)
|
||||||
{
|
{
|
||||||
if (IsEntityIdValid(id))
|
if (IsEntityIdValid(id))
|
||||||
return Entity(id, this);
|
return &m_entities[id];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NazaraError("Invalid ID");
|
NazaraError("Invalid ID");
|
||||||
return Entity();
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,19 +75,17 @@ namespace Ndk
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < m_killedEntities.size(); ++i)
|
for (unsigned int i = 0; i < m_killedEntities.size(); ++i)
|
||||||
{
|
{
|
||||||
Entity::Id e1 = m_aliveEntities[i].GetId();
|
EntityHandle entity = m_killedEntities[i];
|
||||||
|
|
||||||
for (unsigned int j = 0; j < m_aliveEntities.size(); ++j)
|
for (unsigned int j = 0; j < m_aliveEntities.size(); ++j)
|
||||||
{
|
{
|
||||||
Entity::Id e2 = m_killedEntities[j].GetId();
|
if (entity == m_aliveEntities[j])
|
||||||
if (e1 == e2)
|
|
||||||
{
|
{
|
||||||
// Remise en file de l'identifiant d'entité
|
// Remise en file d'attente de l'identifiant d'entité
|
||||||
nzUInt32& counter = m_entitiesCounter[e1.part.index];
|
m_freeIdList.push_back(entity->GetId());
|
||||||
counter++;
|
|
||||||
|
|
||||||
e1.part.counter = counter;
|
// Destruction de l'entité (invalidation du handle par la même occasion)
|
||||||
m_freeIdList.push_back(e1);
|
entity->Destroy();
|
||||||
|
|
||||||
// Suppression de l'entité des deux tableaux
|
// Suppression de l'entité des deux tableaux
|
||||||
m_aliveEntities.erase(m_aliveEntities.begin() + j);
|
m_aliveEntities.erase(m_aliveEntities.begin() + j);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue