bubel-ecs/source/ecs/id_manager.d
2018-10-01 19:40:24 +02:00

105 lines
3.1 KiB
D

module ecs.id_manager;
import ecs.entity;
import ecs.vector;
/************************************************************************************************************************
*IDManager is responsible for assignment and removing IDs. IDs are unique throughtout a whole duration of the program.
*/
struct IDManager
{
/************************************************************************************************************************
*Get new ID.
*/
EntityID getNewID()
{
if (m_next_id >= m_ids_array.length)
m_ids_array.add(Data());
EntityID id;
id.id = m_next_id;
id.counter = /*++*/m_ids_array[m_next_id].counter;
m_next_id = m_ids_array[m_next_id].next_id;
if (m_next_id == uint.max)
m_next_id = cast(uint) m_ids_array.length;
return id;
}
/************************************************************************************************************************
*Release ID.
*/
void releaseID(EntityID id)
{
Data* data = &m_ids_array[id.id];
if (data.counter != id.counter)
return;
data.counter++;
data.next_id = m_next_id;
data.entity = null;
m_next_id = id.id;
}
/************************************************************************************************************************
*Update pointer to entity. The purpose of this function is to ensure that pointer to entity is always correct.
*/
void update(ref Entity entity)
{
if(entity.id.counter == m_ids_array[entity.id.id].counter)m_ids_array[entity.id.id].entity = &entity;
}
/************************************************************************************************************************
*Returns pointer to entity.
*/
export Entity* getEntityPointer(EntityID id)
{
Data* data = &m_ids_array[id.id];
if (data.counter != id.counter)
return null;
else
return data.entity;
}
/************************************************************************************************************************
*Check if entity with specified ID exist.
*/
export bool isExist(EntityID id)
{
Data* data = &m_ids_array[id.id];
return data.counter == id.counter;
}
private static struct Data
{
uint counter = 0;
uint next_id = uint.max;
Entity* entity = null;
}
private:
uint m_next_id;
Vector!Data m_ids_array;
}
unittest
{
IDManager manager;
EntityID id1 = manager.getNewID();
EntityID id2 = manager.getNewID();
EntityID id3 = manager.getNewID();
assert(id1 == EntityID(0, 1));
assert(id2 == EntityID(1, 1));
assert(id3 == EntityID(2, 1));
manager.releaseID(id2);
manager.releaseID(id1);
id2 = manager.getNewID();
id1 = manager.getNewID();
assert(id1 == EntityID(1, 2));
assert(id2 == EntityID(0, 2));
assert(id3 == EntityID(2, 1));
assert(manager.isExist(id3));
assert(!manager.isExist(EntityID(0, 1)));
}