-some usefull functions for IDManager

-added EntityManager.removeEntity(EntityID)
-EntitiesBlock now has ID usefull for updating first_free_block in EntityInfo
This commit is contained in:
Mergul 2018-09-12 17:38:41 +02:00
parent ae53e13d42
commit d3222eefbb
4 changed files with 109 additions and 25 deletions

View file

@ -54,7 +54,7 @@ class EntityManager
string ret;
foreach (i, param; Parameters!(Sys.update))
{
ret ~= "system.components[" ~ i.to!string
ret ~= "system.m_components[" ~ i.to!string
~ "] = components_map.get(types[" ~ i.to!string ~ "].stringof);\n";
}
return ret;
@ -66,7 +66,7 @@ class EntityManager
{
static if (hasMember!(Sys, "update"))
{
Sys* s = cast(Sys*) data.system.system_pointer;
Sys* s = cast(Sys*) data.system.m_system_pointer;
EntitiesBlock* block = data.info.first_block;
while (block !is null)
@ -83,7 +83,7 @@ class EntityManager
}
}
system.update = &callUpdate;
system.m_update = &callUpdate;
}
static if (hasMember!(Sys, "onEnable"))
@ -110,9 +110,9 @@ class EntityManager
system.m_disable = &callDisable;
}
system.system_pointer = cast(void*) Mallocator.instance.make!Sys;
system.m_system_pointer = cast(void*) Mallocator.instance.make!Sys;
system.components = Mallocator.instance.makeArray!uint(types.length);
system.m_components = Mallocator.instance.makeArray!uint(types.length);
mixin(genCompList());
systems.add(system);
@ -142,7 +142,7 @@ class EntityManager
foreach (data; info.callers)
{
if (data.system.enabled)
(cast(SytemFuncType) data.system.update)(data, null); //caller(call_data,null);
(cast(SytemFuncType) data.system.m_update)(data, null); //caller(call_data,null);
}
}
}
@ -176,7 +176,7 @@ class EntityManager
foreach (ref system; systems)
{
if (system.update is null)
if (system.m_update is null)
continue;
addEntityCaller(*info, system);
}
@ -193,9 +193,9 @@ class EntityManager
void addEntityCaller(ref EntityInfo entity, ref System system)
{
CallData call_data = CallData(&system, &entity, null);
ushort[] deltas = (cast(ushort*) alloca(system.components.length * ushort.sizeof))[0
.. system.components.length];
foreach (i, id; system.components)
ushort[] deltas = (cast(ushort*) alloca(system.m_components.length * ushort.sizeof))[0
.. system.m_components.length];
foreach (i, id; system.m_components)
{
deltas[i] = ushort.max;
foreach (i2, id2; entity.components)
@ -214,7 +214,7 @@ class EntityManager
}
if (deltas)
{
call_data.deltas = Mallocator.instance.makeArray(deltas); //Mallocator.instance.makeArray!ushort(system.components.length);
call_data.deltas = Mallocator.instance.makeArray(deltas); //Mallocator.instance.makeArray!ushort(system.m_components.length);
entity.callers.add(call_data);
}
}
@ -225,7 +225,7 @@ class EntityManager
Mallocator.instance.dispose(template_);
}
void addEntity(EntityTemplate* tmpl)
ref Entity addEntity(EntityTemplate* tmpl)
{
EntitiesBlock* previous_block;
EntitiesBlock* block = tmpl.info.first_with_free_space; //tmpl.info.first_block;
@ -241,10 +241,12 @@ class EntityManager
if (previous_block is null)
{
tmpl.info.first_block = block;
block.id = 0;
}
else
{
previous_block.next_block = block;
block.id = previous_block.id + 1;
}
tmpl.info.first_with_free_space = block;
break; // new block certainly has free space
@ -267,6 +269,37 @@ class EntityManager
entity.id = id_manager.getNewID();
entity.updateID();
block.entities_count++;
return *entity;
}
void removeEntity(EntityID id)
{
Entity* entity = id_manager.getEntityPointer(id);
if(entity is null)return;
EntitiesBlock* block = getMetaData(entity);
id_manager.releaseID(id);
void* data_begin = block.dataBegin();
uint pos = cast(int)(cast(void*)entity - data_begin) / block.type_data.size;
block.entities_count--;
if(block.type_data.first_with_free_space.id > block.id)block.type_data.first_with_free_space = block;
if(pos == block.entities_count)return;
void* src = data_begin + block.entities_count * block.type_data.size;
void* dst = data_begin + pos * block.type_data.size;
memcpy(dst,src,block.type_data.size);
entity = cast(Entity*) dst;
entity.updateID();
}
EntitiesBlock* getMetaData(void* pointer)
{
return cast(EntitiesBlock*)(cast(size_t) pointer & (~cast(size_t)(page_size - 1)));
}
struct ComponentInfo
@ -304,6 +337,7 @@ class EntityManager
EntityInfo* type_data;
uint entities_count;
uint id;
EntitiesBlock* next_block;
///there is a loooot of data (4kB, pure magic)
}
@ -317,7 +351,9 @@ class EntityManager
alias SytemFuncType = void function(ref EntityManager.CallData data, void* entity);
///Single page size. Must be power of two.
enum page_size = 4096;
///Number of pages in block.
enum pages_in_block = 128;
IDManager id_manager;