(World) Optimized entities handling a lot

Former-commit-id: f05f3bb7bf321d30fd51f504ace95aa0ea9f7f8d
This commit is contained in:
Lynix
2015-03-16 22:14:18 +01:00
parent b30298b6ab
commit 3694857d30
3 changed files with 55 additions and 36 deletions

View File

@@ -31,13 +31,15 @@ namespace Ndk
m_entities.push_back(Entity(*this, id));
}
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);
Entity& entity = m_entities[id].entity;
entity.Create();
return entity;
EntityHandle handle = entity.CreateHandle();
m_aliveEntities.push_back(handle);
m_entities[id].aliveIndex = m_aliveEntities.size()-1;
return handle;
}
void World::Clear()
@@ -49,7 +51,7 @@ namespace Ndk
m_entities.clear();
m_aliveEntities.clear();
m_killedEntities.clear();
m_killedEntities.Clear();
}
void World::KillEntity(const EntityHandle& entity)
@@ -57,13 +59,13 @@ namespace Ndk
///DOC: Ignoré si l'entité est invalide
if (IsEntityValid(entity))
m_killedEntities.emplace_back(entity);
m_killedEntities.UnboundedSet(entity->GetId(), true);
}
EntityHandle World::GetEntity(Entity::Id id)
{
if (IsEntityIdValid(id))
return m_entities[id].CreateHandle();
return m_aliveEntities[m_entities[id].aliveIndex];
else
{
NazaraError("Invalid ID");
@@ -73,33 +75,36 @@ namespace Ndk
void World::Update()
{
if (!m_killedEntities.empty())
for (unsigned int i = m_killedEntities.FindFirst(); i != m_killedEntities.npos; i = m_killedEntities.FindNext(i))
{
for (unsigned int i = 0; i < m_killedEntities.size(); ++i)
EntityBlock& block = m_entities[i];
Entity& entity = block.entity;
NazaraAssert(entity.IsValid(), "Entity must be valid");
// Remise en file d'attente de l'identifiant d'entité
m_freeIdList.push_back(entity.GetId());
// Destruction de l'entité (invalidation du handle par la même occasion)
entity.Destroy();
// Nous allons sortir le handle de la liste des entités vivantes
// en swappant le handle avec le dernier handle, avant de pop
NazaraAssert(block.aliveIndex < m_aliveEntities.size(), "Alive index out of range");
if (block.aliveIndex < m_aliveEntities.size()-1) // S'il ne s'agit pas du dernier handle
{
const EntityHandle& entity = m_killedEntities[i];
EntityHandle& lastHandle = m_aliveEntities.back();
EntityHandle& myHandle = m_aliveEntities[block.aliveIndex];
for (unsigned int j = 0; j < m_aliveEntities.size(); ++j)
{
if (entity == m_aliveEntities[j])
{
// Remise en file d'attente de l'identifiant d'entité
m_freeIdList.push_back(entity->GetId());
myHandle = std::move(lastHandle);
// Destruction de l'entité (invalidation du handle par la même occasion)
entity->Destroy();
// Suppression de l'entité des deux tableaux
m_aliveEntities.erase(m_aliveEntities.begin() + j);
m_killedEntities.erase(m_killedEntities.begin() + i);
// Correction des indices (pour ne pas sauter une case)
i--;
j--;
break;
}
}
// On n'oublie pas de corriger l'indice associé à l'entité
m_entities[myHandle->GetId()].aliveIndex = block.aliveIndex;
}
m_aliveEntities.pop_back();
}
m_killedEntities.Reset();
}
}