Support more than one bucket for given entity type

This commit is contained in:
mmcomando 2018-09-10 18:34:40 +02:00
parent a61a54b43f
commit 4d35bc2a1b
2 changed files with 44 additions and 11 deletions

View file

@ -182,15 +182,42 @@ class EntityManager
void addEntity(EntityTemplate* tmpl) void addEntity(EntityTemplate* tmpl)
{ {
if(tmpl.info.first_block is null) EntitiesBlock* previous_block;
{ EntitiesBlock* block=tmpl.info.first_with_free_space;//tmpl.info.first_block;
tmpl.info.first_block = cast(EntitiesBlock*) AlignedMallocator.instance.alignedAllocate(4096,4096);
*tmpl.info.first_block = EntitiesBlock(tmpl.info);
}
void* start = tmpl.info.first_block.dataBegin() + tmpl.info.first_block.entities_count * tmpl.info.size; // find block with enought space
while(1){
if(block is null)
{
block = cast(EntitiesBlock*) AlignedMallocator.instance.alignedAllocate(4096,4096);
*block = EntitiesBlock(tmpl.info);
if(previous_block is null)
{
tmpl.info.first_block=block;
}
else
{
previous_block.next_block=block;
}
tmpl.info.first_with_free_space=block;
break; // new block certainly has free space
}
// check if there is enought space
if(block.dataDelta() + (block.entities_count + 1) * tmpl.info.size > 4096 )
{
previous_block=block;
block=block.next_block;
continue;
}
tmpl.info.first_with_free_space=block;
break; // block exists and bounds check passed
}
void* start = block.dataBegin() + block.entities_count * tmpl.info.size;
memcpy(start, tmpl.entity_data.ptr, tmpl.info.size); memcpy(start, tmpl.entity_data.ptr, tmpl.info.size);
tmpl.info.first_block.entities_count++; block.entities_count++;
} }
struct CallData struct CallData
@ -213,12 +240,18 @@ class EntityManager
ushort alignment; ushort alignment;
ushort size; ushort size;
EntitiesBlock* first_block; EntitiesBlock* first_block;
EntitiesBlock* first_with_free_space; // a hint for allocations, should have empty space in it but doesn't have to
Vector!(CallData) callers; Vector!(CallData) callers;
} }
struct EntitiesBlock struct EntitiesBlock
{ {
uint dataDelta()
{
ushort dif = EntitiesBlock.sizeof;
alignNum(dif,type_data.alignment);
return dif;
}
void* dataBegin() void* dataBegin()
{ {
ushort dif = EntitiesBlock.sizeof; ushort dif = EntitiesBlock.sizeof;

View file

@ -59,6 +59,8 @@ unittest
void update(ref TestComp test, ref TestComp2 test2)//ref TestComp comp) void update(ref TestComp test, ref TestComp2 test2)//ref TestComp comp)
{ {
assert( cast(ptrdiff_t)&test % TestComp.alignof == 0 );
assert( cast(ptrdiff_t)&test2 % TestComp2.alignof == 0 );
import std.stdio; import std.stdio;
writeln("Jakis tekst! ",test.b); writeln("Jakis tekst! ",test.b);
test.a+=1000; test.a+=1000;
@ -106,8 +108,7 @@ unittest
EntityTemplate* tmpl = gEM.allocateTemplate(ids); EntityTemplate* tmpl = gEM.allocateTemplate(ids);
*cast(EntityID*)tmpl.entity_data.ptr = EntityID(1,1); *cast(EntityID*)tmpl.entity_data.ptr = EntityID(1,1);
gEM.addEntity(tmpl); foreach(i; 0..1_000_000)gEM.addEntity(tmpl);
gEM.addEntity(tmpl);
//assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+24)) == EntityID(1,1)); //assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+24)) == EntityID(1,1));
//assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+48)) == EntityID(1,1)); //assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+48)) == EntityID(1,1));
@ -117,6 +118,5 @@ unittest
import std.stdio; import std.stdio;
writeln((cast(uint*)tmpl.info.first_block)[0..48]); writeln((cast(uint*)tmpl.info.first_block)[0..48]);
gEM.freeTemplate(tmpl); gEM.freeTemplate(tmpl);
} }