-call update by Systems instead of EntityTypes (version UpdateBySystems)
-memory packing (every block in EntityType except last one are always full)
This commit is contained in:
parent
fddfc78ec1
commit
3a767babc0
3 changed files with 232 additions and 92 deletions
3
dub.json
3
dub.json
|
|
@ -10,6 +10,9 @@
|
||||||
"dflags-posix-ldc": [
|
"dflags-posix-ldc": [
|
||||||
"-defaultlib=phobos2-ldc,druntime-ldc"
|
"-defaultlib=phobos2-ldc,druntime-ldc"
|
||||||
],
|
],
|
||||||
|
"versions": [
|
||||||
|
"UpdateBySystems"
|
||||||
|
],
|
||||||
"configurations" : [
|
"configurations" : [
|
||||||
{
|
{
|
||||||
"name" : "library",
|
"name" : "library",
|
||||||
|
|
|
||||||
|
|
@ -89,25 +89,27 @@ class EntityManager
|
||||||
{
|
{
|
||||||
static if (isFunction!(__traits(getMember, Sys.EntitiesData, member)))
|
static if (isFunction!(__traits(getMember, Sys.EntitiesData, member)))
|
||||||
static assert(0, "EntitiesData can't have any function!");
|
static assert(0, "EntitiesData can't have any function!");
|
||||||
else static if(member == "length")
|
else static if (member == "length")
|
||||||
{
|
{
|
||||||
static assert(isIntegral!(typeof(__traits(getMember,Sys.EntitiesData, member))),"EntitiesData 'length' member must be integral type.");
|
static assert(isIntegral!(typeof(__traits(getMember, Sys.EntitiesData,
|
||||||
static assert(typeof(__traits(getMember,Sys.EntitiesData, member)).sizeof > 1,"EntitiesData 'length' member can't be byte or ubyte.");
|
member))), "EntitiesData 'length' member must be integral type.");
|
||||||
|
static assert(typeof(__traits(getMember, Sys.EntitiesData, member))
|
||||||
|
.sizeof > 1, "EntitiesData 'length' member can't be byte or ubyte.");
|
||||||
}
|
}
|
||||||
else static if (!(isArray!(typeof(__traits(getMember,
|
else static if (!(isArray!(typeof(__traits(getMember,
|
||||||
Sys.EntitiesData, member)))))
|
Sys.EntitiesData, member)))))
|
||||||
static assert(0, "EntitiesData members should be arrays of elements!");
|
static assert(0, "EntitiesData members should be arrays of elements!");
|
||||||
}
|
}
|
||||||
|
|
||||||
string ret;// = "ushort comp;uint req;uint opt;uint absent;";
|
string ret; // = "ushort comp;uint req;uint opt;uint absent;";
|
||||||
|
|
||||||
uint req;
|
uint req;
|
||||||
uint opt;
|
uint opt;
|
||||||
uint absent;
|
uint absent;
|
||||||
foreach (member; __traits(allMembers, Sys.EntitiesData))
|
foreach (member; __traits(allMembers, Sys.EntitiesData))
|
||||||
{
|
{
|
||||||
if (member == "length" || is(typeof(__traits(getMember, Sys.EntitiesData,
|
if (member == "length" || is(typeof(__traits(getMember,
|
||||||
member)) == Entity[]) || is(typeof(__traits(getMember,
|
Sys.EntitiesData, member)) == Entity[]) || is(typeof(__traits(getMember,
|
||||||
Sys.EntitiesData, member)) == const(Entity)[]))
|
Sys.EntitiesData, member)) == const(Entity)[]))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -134,52 +136,66 @@ class EntityManager
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!has_att)req++;
|
if (!has_att)
|
||||||
|
req++;
|
||||||
//ret ~= "req++;";
|
//ret ~= "req++;";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static if(__traits(hasMember, Sys, "AbsentComponents"))
|
static if (__traits(hasMember, Sys, "AbsentComponents"))
|
||||||
{
|
{
|
||||||
static if(is(Sys.AbsentComponents == enum))
|
static if (is(Sys.AbsentComponents == enum))
|
||||||
{
|
{
|
||||||
absent += (Fields!(Sys.AbsentComponents)).length;//static assert(0,"Enum AbsentComponents are not implemented yet.");
|
absent += (Fields!(Sys.AbsentComponents)).length; //static assert(0,"Enum AbsentComponents are not implemented yet.");
|
||||||
}
|
}
|
||||||
else static if(__traits(compiles,allSameType!(string,typeof(Sys.AbsentComponents))) && allSameType!(string,typeof(Sys.AbsentComponents)) &&
|
else static if (__traits(compiles, allSameType!(string, typeof(Sys.AbsentComponents)))
|
||||||
isExpressions!(Sys.AbsentComponents))
|
&& allSameType!(string, typeof(Sys.AbsentComponents))
|
||||||
|
&& isExpressions!(Sys.AbsentComponents))
|
||||||
{
|
{
|
||||||
absent += Sys.AbsentComponents.length;
|
absent += Sys.AbsentComponents.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(req > 0)ret ~= "system.m_components = Mallocator.instance.makeArray!ushort("~req.to!string~");";
|
if (req > 0)
|
||||||
if(opt > 0)ret ~= "system.m_optional_components = Mallocator.instance.makeArray!ushort("~opt.to!string~");";
|
ret ~= "system.m_components = Mallocator.instance.makeArray!ushort("
|
||||||
if(absent > 0)ret ~= "system.m_absent_components = Mallocator.instance.makeArray!ushort("~absent.to!string~");";
|
~ req.to!string ~ ");";
|
||||||
ret ~= "ushort comp;";//uint opt = 0;uint req = 0;uint absent = 0;";
|
if (opt > 0)
|
||||||
|
ret ~= "system.m_optional_components = Mallocator.instance.makeArray!ushort("
|
||||||
|
~ opt.to!string ~ ");";
|
||||||
|
if (absent > 0)
|
||||||
|
ret ~= "system.m_absent_components = Mallocator.instance.makeArray!ushort("
|
||||||
|
~ absent.to!string ~ ");";
|
||||||
|
ret ~= "ushort comp;"; //uint opt = 0;uint req = 0;uint absent = 0;";
|
||||||
|
|
||||||
opt = 0;
|
opt = 0;
|
||||||
req = 0;
|
req = 0;
|
||||||
absent = 0;
|
absent = 0;
|
||||||
|
|
||||||
static if(__traits(hasMember, Sys, "AbsentComponents"))
|
static if (__traits(hasMember, Sys, "AbsentComponents"))
|
||||||
{
|
{
|
||||||
static if(is(Sys.AbsentComponents == enum))
|
static if (is(Sys.AbsentComponents == enum))
|
||||||
{
|
{
|
||||||
//static assert(0,"Enum AbsentComponents are not implemented yet.");
|
//static assert(0,"Enum AbsentComponents are not implemented yet.");
|
||||||
foreach(str;Fields!(Sys.AbsentComponents))ret ~= "system.m_absent_components["~(absent++).to!string~"] = components_map.get(\""~str.stringof~"\", ushort.max);";
|
foreach (str; Fields!(Sys.AbsentComponents))
|
||||||
|
ret ~= "system.m_absent_components[" ~ (absent++)
|
||||||
|
.to!string ~ "] = components_map.get(\""
|
||||||
|
~ str.stringof ~ "\", ushort.max);";
|
||||||
}
|
}
|
||||||
else static if(__traits(compiles,allSameType!(string,typeof(Sys.AbsentComponents))) && allSameType!(string,typeof(Sys.AbsentComponents)) &&
|
else static if (__traits(compiles, allSameType!(string, typeof(Sys.AbsentComponents)))
|
||||||
isExpressions!(Sys.AbsentComponents))
|
&& allSameType!(string, typeof(Sys.AbsentComponents))
|
||||||
|
&& isExpressions!(Sys.AbsentComponents))
|
||||||
{
|
{
|
||||||
foreach(str;Sys.AbsentComponents)ret ~= "system.m_absent_components["~(absent++).to!string~"] = components_map.get(\""~str~"\", ushort.max);";
|
foreach (str; Sys.AbsentComponents)
|
||||||
|
ret ~= "system.m_absent_components[" ~ (absent++)
|
||||||
|
.to!string ~ "] = components_map.get(\"" ~ str ~ "\", ushort.max);";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (member; __traits(allMembers, Sys.EntitiesData))
|
foreach (member; __traits(allMembers, Sys.EntitiesData))
|
||||||
{
|
{
|
||||||
if (member == "length" || is(typeof(__traits(getMember, Sys.EntitiesData,
|
if (member == "length" || is(typeof(__traits(getMember,
|
||||||
member)) == Entity[]) || is(typeof(__traits(getMember,
|
Sys.EntitiesData, member)) == Entity[]) || is(typeof(__traits(getMember,
|
||||||
Sys.EntitiesData, member)) == const(Entity)[]))
|
Sys.EntitiesData, member)) == const(Entity)[]))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -204,20 +220,22 @@ class EntityManager
|
||||||
{
|
{
|
||||||
if (att == "optional")
|
if (att == "optional")
|
||||||
{
|
{
|
||||||
ret ~= "system.m_optional_components["~(opt++).to!string~"] = comp;}";
|
ret ~= "system.m_optional_components[" ~ (opt++)
|
||||||
|
.to!string ~ "] = comp;}";
|
||||||
has_att = true;
|
has_att = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (att == "absent")
|
else if (att == "absent")
|
||||||
{
|
{
|
||||||
ret ~= "system.m_absent_components["~(absent++).to!string~"] = comp;}";
|
ret ~= "system.m_absent_components[" ~ (absent++)
|
||||||
|
.to!string ~ "] = comp;}";
|
||||||
has_att = true;
|
has_att = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!has_att)
|
if (!has_att)
|
||||||
{
|
{
|
||||||
ret ~= "system.m_components["~(req++).to!string~"] = comp;}";
|
ret ~= "system.m_components[" ~ (req++).to!string ~ "] = comp;}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -256,10 +274,9 @@ class EntityManager
|
||||||
ret ~= "input_data." ~ member
|
ret ~= "input_data." ~ member
|
||||||
~ " = (cast(Entity*) block.dataBegin())[0 .. block.entities_count];";
|
~ " = (cast(Entity*) block.dataBegin())[0 .. block.entities_count];";
|
||||||
}
|
}
|
||||||
else if(member == "length")
|
else if (member == "length")
|
||||||
{
|
{
|
||||||
ret ~= "input_data." ~ member
|
ret ~= "input_data." ~ member ~ " = block.entities_count;";
|
||||||
~ " = block.entities_count;";
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -392,6 +409,28 @@ class EntityManager
|
||||||
addEntityCaller(*info, cast(uint) systems.length - 1);
|
addEntityCaller(*info, cast(uint) systems.length - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version (UpdateBySystems)
|
||||||
|
{
|
||||||
|
bool added = false;
|
||||||
|
foreach (i, ref caller; system_callers)
|
||||||
|
{
|
||||||
|
if (systems[caller.system_id].priority > priority)
|
||||||
|
{
|
||||||
|
SystemCaller* sys_caller = Mallocator.instance.make!SystemCaller;
|
||||||
|
sys_caller.system_id = Sys.system_id;
|
||||||
|
system_callers.add(sys_caller, i);
|
||||||
|
added = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!added)
|
||||||
|
{
|
||||||
|
SystemCaller* sys_caller = Mallocator.instance.make!SystemCaller;
|
||||||
|
sys_caller.system_id = Sys.system_id;
|
||||||
|
system_callers.add(sys_caller);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateEntityCallers();
|
updateEntityCallers();
|
||||||
|
|
@ -491,6 +530,27 @@ class EntityManager
|
||||||
*Update systems. Should be called only between begin() and end().
|
*Update systems. Should be called only between begin() and end().
|
||||||
*/
|
*/
|
||||||
export void update()
|
export void update()
|
||||||
|
{
|
||||||
|
version (UpdateBySystems)
|
||||||
|
{
|
||||||
|
foreach (caller; system_callers)
|
||||||
|
{
|
||||||
|
System* sys = &systems[caller.system_id];
|
||||||
|
if (sys.enabled)
|
||||||
|
{
|
||||||
|
if (sys.m_begin)
|
||||||
|
sys.m_begin(sys.m_system_pointer);
|
||||||
|
foreach (info; caller.infos)
|
||||||
|
{
|
||||||
|
CallData data = CallData(caller.system_id, sys, info);
|
||||||
|
(cast(SytemFuncType) data.system.m_update)(data);
|
||||||
|
}
|
||||||
|
if (sys.m_end)
|
||||||
|
sys.m_end(sys.m_system_pointer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
foreach (info; &entities_infos.byValue)
|
foreach (info; &entities_infos.byValue)
|
||||||
{
|
{
|
||||||
|
|
@ -501,6 +561,7 @@ class EntityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void alignNum(ref ushort num, ushort alignment)
|
static void alignNum(ref ushort num, ushort alignment)
|
||||||
{
|
{
|
||||||
|
|
@ -630,6 +691,16 @@ class EntityManager
|
||||||
addEntityCaller(*info, i);
|
addEntityCaller(*info, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version (UpdateBySystems)
|
||||||
|
{
|
||||||
|
foreach (uint i, ref system; systems)
|
||||||
|
{
|
||||||
|
if (system.m_update is null)
|
||||||
|
continue;
|
||||||
|
addSystemCaller(*info, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateEntityCallers();
|
updateEntityCallers();
|
||||||
|
|
||||||
entities_infos.add(info.components, info);
|
entities_infos.add(info.components, info);
|
||||||
|
|
@ -648,18 +719,19 @@ class EntityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export void addEntityCaller(ref EntityInfo entity, uint system_id)
|
export void addSystemCaller(ref EntityInfo entity, uint system_id)
|
||||||
{
|
{
|
||||||
System* system = &systems[system_id];
|
System* system = &systems[system_id];
|
||||||
CallData call_data = CallData(system_id, system, &entity);
|
//CallData call_data = CallData(system_id, system, &entity);
|
||||||
|
|
||||||
if(system.m_absent_components)
|
if (system.m_absent_components)
|
||||||
{
|
{
|
||||||
foreach (id; system.m_absent_components)
|
foreach (id; system.m_absent_components)
|
||||||
{
|
{
|
||||||
foreach (id2; entity.components)
|
foreach (id2; entity.components)
|
||||||
{
|
{
|
||||||
if(id == id2)return;
|
if (id == id2)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -668,7 +740,53 @@ class EntityManager
|
||||||
{
|
{
|
||||||
foreach (i2, id2; entity.components)
|
foreach (i2, id2; entity.components)
|
||||||
{
|
{
|
||||||
if (id2 == id)goto is_;
|
if (id2 == id)
|
||||||
|
goto is_;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
is_:
|
||||||
|
}
|
||||||
|
|
||||||
|
uint index = 0;
|
||||||
|
for (; index < system_callers.length; index++)
|
||||||
|
{
|
||||||
|
if (system_callers[index].system_id == system_id)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
system_callers[index].infos.add(&entity);
|
||||||
|
/*for (; index < entity.callers.length; index++)
|
||||||
|
{
|
||||||
|
CallData* caller = &entity.callers[index];
|
||||||
|
if (caller.system.priority >= call_data.system.priority)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
entity.callers.add(call_data, index);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
export void addEntityCaller(ref EntityInfo entity, uint system_id)
|
||||||
|
{
|
||||||
|
System* system = &systems[system_id];
|
||||||
|
CallData call_data = CallData(system_id, system, &entity);
|
||||||
|
|
||||||
|
if (system.m_absent_components)
|
||||||
|
{
|
||||||
|
foreach (id; system.m_absent_components)
|
||||||
|
{
|
||||||
|
foreach (id2; entity.components)
|
||||||
|
{
|
||||||
|
if (id == id2)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (id; system.m_components)
|
||||||
|
{
|
||||||
|
foreach (i2, id2; entity.components)
|
||||||
|
{
|
||||||
|
if (id2 == id)
|
||||||
|
goto is_;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
is_:
|
is_:
|
||||||
|
|
@ -1002,7 +1120,7 @@ class EntityManager
|
||||||
private EntitiesBlock* findBlockWithFreeSpace(EntityInfo* info)
|
private EntitiesBlock* findBlockWithFreeSpace(EntityInfo* info)
|
||||||
{
|
{
|
||||||
EntitiesBlock* previous_block;
|
EntitiesBlock* previous_block;
|
||||||
EntitiesBlock* block = info.first_with_free_space;
|
EntitiesBlock* block = info.last_block;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
|
@ -1021,7 +1139,7 @@ class EntityManager
|
||||||
block.prev_block = previous_block;
|
block.prev_block = previous_block;
|
||||||
block.id = cast(ushort)(previous_block.id + 1);
|
block.id = cast(ushort)(previous_block.id + 1);
|
||||||
}
|
}
|
||||||
info.first_with_free_space = block;
|
info.last_block = block;
|
||||||
break; // new block certainly has free space
|
break; // new block certainly has free space
|
||||||
}
|
}
|
||||||
// check if there is enought space
|
// check if there is enought space
|
||||||
|
|
@ -1034,7 +1152,6 @@ class EntityManager
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
info.first_with_free_space = block;
|
|
||||||
break; // block exists and bounds check passed
|
break; // block exists and bounds check passed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1071,11 +1188,7 @@ class EntityManager
|
||||||
void* data_begin = block.dataBegin();
|
void* data_begin = block.dataBegin();
|
||||||
EntityInfo* info = block.type_info;
|
EntityInfo* info = block.type_info;
|
||||||
|
|
||||||
block.entities_count--;
|
info.last_block.entities_count--;
|
||||||
|
|
||||||
//set "first_with_free_space" if should it be
|
|
||||||
if (info.first_with_free_space.id > block.id)
|
|
||||||
info.first_with_free_space = block;
|
|
||||||
|
|
||||||
static if (EntityID.sizeof == 8)
|
static if (EntityID.sizeof == 8)
|
||||||
uint pos = cast(uint)((cast(void*) entity - data_begin) >> 3);
|
uint pos = cast(uint)((cast(void*) entity - data_begin) >> 3);
|
||||||
|
|
@ -1096,43 +1209,36 @@ class EntityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(block !is info.last_block || pos != block.entities_count)
|
||||||
|
{
|
||||||
|
foreach (comp; info.components)
|
||||||
|
{
|
||||||
|
void* src = cast(void*) info.last_block + info.deltas[comp];
|
||||||
|
void* dst = cast(void*) block + info.deltas[comp];
|
||||||
|
uint size = components[comp].size;
|
||||||
|
memcpy(dst + pos * size, src + info.last_block.entities_count * size, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
block = info.last_block;
|
||||||
|
entity.id = *cast(EntityID*)(block.dataBegin() + block.entities_count * EntityID.sizeof);
|
||||||
|
|
||||||
|
entity.updateID();
|
||||||
|
}
|
||||||
|
|
||||||
|
block = info.last_block;
|
||||||
if (block.entities_count == 0)
|
if (block.entities_count == 0)
|
||||||
{
|
{
|
||||||
|
info.last_block = block.prev_block;
|
||||||
if (info.first_block is block)
|
if (info.first_block is block)
|
||||||
{
|
{
|
||||||
info.first_block = block.next_block;
|
info.first_block = null;
|
||||||
}
|
|
||||||
if (info.first_with_free_space is block)
|
|
||||||
{
|
|
||||||
info.first_with_free_space = block.next_block; //info.first_block;
|
|
||||||
}
|
}
|
||||||
if (block.prev_block)
|
if (block.prev_block)
|
||||||
{
|
{
|
||||||
block.prev_block.next_block = block.next_block;
|
block.prev_block.next_block = null;
|
||||||
}
|
|
||||||
if (block.next_block)
|
|
||||||
{
|
|
||||||
block.next_block.prev_block = block.prev_block;
|
|
||||||
}
|
}
|
||||||
allocator.freeBlock(block);
|
allocator.freeBlock(block);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos == block.entities_count)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (comp; info.components)
|
|
||||||
{
|
|
||||||
void* ptr = cast(void*) block + info.deltas[comp];
|
|
||||||
uint size = components[comp].size;
|
|
||||||
memcpy(ptr + pos * size, ptr + block.entities_count * size, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
entity.id = *cast(EntityID*)(data_begin + block.entities_count * EntityID.sizeof);
|
|
||||||
|
|
||||||
//update pointer for moved entity ID
|
|
||||||
//entity = cast(Entity*) dst;
|
|
||||||
entity.updateID();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************************************************
|
/************************************************************************************************************************
|
||||||
|
|
@ -1211,23 +1317,39 @@ class EntityManager
|
||||||
updateBlocks();
|
updateBlocks();
|
||||||
removeEntities();
|
removeEntities();
|
||||||
changeEntites();
|
changeEntites();
|
||||||
|
|
||||||
|
version (UpdateBySystems)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
foreach (ref system; instance.systems)
|
foreach (ref system; instance.systems)
|
||||||
{
|
{
|
||||||
if (system.m_begin)
|
if (system.m_begin)
|
||||||
system.m_begin(system.m_system_pointer);
|
system.m_begin(system.m_system_pointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************************************************************
|
/************************************************************************************************************************
|
||||||
*End of update process. Should be called after every update function.
|
*End of update process. Should be called after every update function.
|
||||||
*/
|
*/
|
||||||
export void end()
|
export void end()
|
||||||
|
{
|
||||||
|
version (UpdateBySystems)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
foreach (ref system; instance.systems)
|
foreach (ref system; instance.systems)
|
||||||
{
|
{
|
||||||
if (system.m_end)
|
if (system.m_end)
|
||||||
system.m_end(system.m_system_pointer);
|
system.m_end(system.m_system_pointer);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateBlocks();
|
updateBlocks();
|
||||||
removeEntities();
|
removeEntities();
|
||||||
changeEntites();
|
changeEntites();
|
||||||
|
|
@ -1262,6 +1384,12 @@ class EntityManager
|
||||||
*/
|
*/
|
||||||
struct EntityInfo
|
struct EntityInfo
|
||||||
{
|
{
|
||||||
|
///Returns number of blocks
|
||||||
|
uint blocksCount()
|
||||||
|
{
|
||||||
|
return last_block.id;
|
||||||
|
}
|
||||||
|
|
||||||
///entity components
|
///entity components
|
||||||
ushort[] components;
|
ushort[] components;
|
||||||
|
|
||||||
|
|
@ -1279,8 +1407,8 @@ class EntityManager
|
||||||
|
|
||||||
///pointer to first block/page
|
///pointer to first block/page
|
||||||
EntitiesBlock* first_block;
|
EntitiesBlock* first_block;
|
||||||
///a hint for allocations
|
///pointer to last block
|
||||||
EntitiesBlock* first_with_free_space; // a hint for allocations, should have empty space in it but doesn't have to
|
EntitiesBlock* last_block;
|
||||||
///array of CallData. Contain data for System calls.
|
///array of CallData. Contain data for System calls.
|
||||||
Vector!(CallData) callers;
|
Vector!(CallData) callers;
|
||||||
}
|
}
|
||||||
|
|
@ -1335,6 +1463,15 @@ class EntityManager
|
||||||
EntityManager.EntityInfo* info;
|
EntityManager.EntityInfo* info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SystemCaller
|
||||||
|
{
|
||||||
|
uint system_id;
|
||||||
|
System* system;
|
||||||
|
Vector!(EntityInfo*) infos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector!(SystemCaller*) system_callers;
|
||||||
|
|
||||||
alias SytemFuncType = void function(ref EntityManager.CallData data);
|
alias SytemFuncType = void function(ref EntityManager.CallData data);
|
||||||
|
|
||||||
//alias sendSelfEvent = instance.event_manager.sendSelfEvent;
|
//alias sendSelfEvent = instance.event_manager.sendSelfEvent;
|
||||||
|
|
@ -1357,7 +1494,7 @@ class EntityManager
|
||||||
Vector!ubyte change_entities_list;
|
Vector!ubyte change_entities_list;
|
||||||
|
|
||||||
HashMap!(ushort[], EntityInfo*) entities_infos;
|
HashMap!(ushort[], EntityInfo*) entities_infos;
|
||||||
HashMap!(const (char)[], ushort) systems_map;
|
HashMap!(const(char)[], ushort) systems_map;
|
||||||
HashMap!(string, ushort) components_map;
|
HashMap!(string, ushort) components_map;
|
||||||
HashMap!(string, ushort) events_map;
|
HashMap!(string, ushort) events_map;
|
||||||
Vector!System systems;
|
Vector!System systems;
|
||||||
|
|
|
||||||
|
|
@ -324,14 +324,14 @@ import std.meta;
|
||||||
|
|
||||||
//foreach(i; 0..1_000_000)gEM.removeEntity(gEM.addEntity(tmpl).id);
|
//foreach(i; 0..1_000_000)gEM.removeEntity(gEM.addEntity(tmpl).id);
|
||||||
|
|
||||||
EntityID[1000] idss;
|
EntityID[5000] idss;
|
||||||
|
|
||||||
foreach (i; 0 .. 1_000)
|
foreach (i; 0 .. 200)
|
||||||
{
|
{
|
||||||
gEM.begin();
|
gEM.begin();
|
||||||
foreach (j; 0 .. 1_000)
|
foreach (j; 0 .. 5_000)
|
||||||
idss[j] = gEM.addEntity(tmpl).id;
|
idss[j] = gEM.addEntity(tmpl).id;
|
||||||
foreach (j; 0 .. 1_000)
|
foreach (j; 0 .. 5_000)
|
||||||
gEM.removeEntity(idss[j]);
|
gEM.removeEntity(idss[j]);
|
||||||
gEM.end();
|
gEM.end();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue