-added pure annotation for some functions

-addEntity now returns pointer instead of reference (it's has more sense)
-added function addEntityCopy(EntityID) which adds copy of entity with it's whole data
This commit is contained in:
Mergul 2019-08-10 16:20:50 +00:00
parent 8318d2efb4
commit 1be08eb534
2 changed files with 94 additions and 55 deletions

View file

@ -1056,7 +1056,7 @@ export class EntityManager
m_dispatch_jobs = func; m_dispatch_jobs = func;
} }
static void alignNum(ref ushort num, ushort alignment) nothrow @nogc static void alignNum(ref ushort num, ushort alignment) nothrow @nogc pure
{ {
num = cast(ushort)((num + alignment - 1) & (-cast(int) alignment)); //num += alignment - (num & (alignment - 1)); num = cast(ushort)((num + alignment - 1) & (-cast(int) alignment)); //num += alignment - (num & (alignment - 1));
} }
@ -1459,10 +1459,7 @@ export class EntityManager
new_entity.id = entity.id; new_entity.id = entity.id;
new_entity.updateID(); new_entity.updateID();
static if (EntityID.sizeof == 8) uint ind = block.entityIndex(entity);
uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) >> 3);
else
uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) / EntityID.sizeof());
if (info.remove_listeners) if (info.remove_listeners)
{ {
@ -1636,10 +1633,7 @@ export class EntityManager
uint j = 0; uint j = 0;
uint k = 0; uint k = 0;
static if (EntityID.sizeof == 8) uint ind = block.entityIndex(entity);
uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) >> 3);
else
uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) / EntityID.sizeof());
if (info.remove_listeners) if (info.remove_listeners)
{ {
@ -1761,12 +1755,66 @@ export class EntityManager
} }
/************************************************************************************************************************ /************************************************************************************************************************
*Add entity to system. *Add copy of entity to system and returns pointer to it. Added copy has same data as copied entity. Returen pointer is
*valid only before one from commit(), begin() or end() will be called. To save entity to further use you should save ID
*instead of pointer.
* *
*Params: *Params:
*tmpl = pointer entity template allocated by EntityManager. *tmpl = pointer entity template allocated by EntityManager.
*/ */
export ref Entity addEntity(EntityTemplate* tmpl) export Entity* addEntityCopy(EntityID id)
{
Entity* entity = getEntity(id);
EntitiesBlock* block = getMetaData(entity);
EntityInfo* info = block.type_info;
ushort index = block.entityIndex(entity);
ushort new_index = 0;
EntitiesBlock* new_block;
do
{
new_block = findBlockWithFreeSpaceMT(info);
new_index = new_block.added_count.atomicOp!"+="(1);
}
while (new_block.entities_count + new_index > info.max_entities);
ushort new_id = cast(ushort)(new_block.entities_count + new_index - 1);
const void* data_begin = new_block.dataBegin();
const void* start = data_begin + EntityID.sizeof * new_id;
foreach (i, comp; info.components)
{
memcpy(cast(void*) new_block + info.deltas[comp] + components[comp].size * new_id,
cast(void*) block + info.deltas[comp] + components[comp].size * index, components[comp].size);
if (components[comp].create_callback)
{
components[comp].create_callback(
cast(void*) block + info.deltas[comp] + new_id * components[comp].size);
}
}
if (new_index == 1)
threads[thread_id].blocks_to_update.add(new_block);
Entity* new_entity = cast(Entity*) start;
//add_mutex.lock_nothrow();
new_entity.id = id_manager.getNewID();
//add_mutex.unlock_nothrow();
new_entity.updateID();
return new_entity;
}
/************************************************************************************************************************
*Add entity to system. Returen pointer is valid only before one from commit(), begin() or end() will be called. To save entity to further
*use you should save ID instead of pointer.
*
*Params:
*tmpl = pointer entity template allocated by EntityManager.
*/
export Entity* addEntity(EntityTemplate* tmpl)
{ {
EntityInfo* info = tmpl.info; EntityInfo* info = tmpl.info;
@ -1806,7 +1854,7 @@ export class EntityManager
//add_mutex.unlock_nothrow(); //add_mutex.unlock_nothrow();
entity.updateID(); entity.updateID();
return *entity; return entity;
} }
/************************************************************************************************************************ /************************************************************************************************************************
@ -1903,11 +1951,7 @@ export class EntityManager
EntityInfo* info = block.type_info; EntityInfo* info = block.type_info;
if (info.remove_listeners) if (info.remove_listeners)
{ {
void* data_begin = block.dataBegin(); uint pos = block.entityIndex(entity);
static if (EntityID.sizeof == 8)
uint pos = cast(uint)((cast(void*) entity - data_begin) >> 3);
else
uint pos = cast(uint)((cast(void*) entity - data_begin) / EntityID.sizeof());
callRemoveEntityListeners(info, block, pos, pos + 1); callRemoveEntityListeners(info, block, pos, pos + 1);
} }
@ -1920,16 +1964,11 @@ export class EntityManager
private void removeEntityNoID(Entity* entity, EntitiesBlock* block, private void removeEntityNoID(Entity* entity, EntitiesBlock* block,
bool call_destructors = false) nothrow @nogc bool call_destructors = false) nothrow @nogc
{ {
//pos is Entity number in block
void* data_begin = block.dataBegin();
EntityInfo* info = block.type_info; EntityInfo* info = block.type_info;
info.last_block.entities_count--; info.last_block.entities_count--;
static if (EntityID.sizeof == 8) uint pos = block.entityIndex(entity);
uint pos = cast(uint)((cast(void*) entity - data_begin) >> 3);
else
uint pos = cast(uint)((cast(void*) entity - data_begin) / EntityID.sizeof());
if (call_destructors) if (call_destructors)
{ {
@ -2173,14 +2212,7 @@ export class EntityManager
EntityID entity_id = *cast(EntityID*) event_pointer; EntityID entity_id = *cast(EntityID*) event_pointer;
Entity* entity = id_manager.getEntityPointer(entity_id); Entity* entity = id_manager.getEntityPointer(entity_id);
call_data.block = getMetaData(entity); call_data.block = getMetaData(entity);
call_data.id = call_data.block.entityIndex(entity);
static if (EntityID.sizeof == 8)
call_data.id = cast(ushort)(
(cast(void*) entity - call_data.block.dataBegin()) >> 3);
else
call_data.id = cast(ushort)(
(cast(void*) entity - call_data.block.dataBegin()) / EntityID
.sizeof);
foreach (caller; events[i].callers) foreach (caller; events[i].callers)
{ {
@ -2580,7 +2612,7 @@ export class EntityManager
struct EntitiesBlock struct EntitiesBlock
{ {
///return distance (in bytes) from begin of block to data ///return distance (in bytes) from begin of block to data
export uint dataDelta() nothrow @nogc export uint dataDelta() nothrow @nogc pure
{ {
ushort dif = EntitiesBlock.sizeof; ushort dif = EntitiesBlock.sizeof;
alignNum(dif, type_info.alignment); alignNum(dif, type_info.alignment);
@ -2588,12 +2620,20 @@ export class EntityManager
} }
///return pointer to first element in block ///return pointer to first element in block
export void* dataBegin() nothrow @nogc export void* dataBegin() nothrow @nogc pure
{ {
ushort dif = EntitiesBlock.sizeof; ushort dif = EntitiesBlock.sizeof;
return cast(void*)&this + dif; return cast(void*)&this + dif;
} }
export ushort entityIndex(Entity* entity) nothrow @nogc pure
{
static if (EntityID.sizeof == 8)
return cast(ushort)((cast(void*) entity - dataBegin()) >> 3);
else
return cast(ushort)((cast(void*) entity - dataBegin()) / EntityID.sizeof());
}
///pointer to Entity type info ///pointer to Entity type info
EntityInfo* type_info = null; EntityInfo* type_info = null;
///number of entities in block ///number of entities in block

View file

@ -526,13 +526,13 @@ int main()
dur = (MonoTime.currTime - time).total!"usecs"; dur = (MonoTime.currTime - time).total!"usecs";
writeln("Template allocating: ", dur, " usecs"); writeln("Template allocating: ", dur, " usecs");
Entity entity; EntityID entity;
{ {
entity = gEM.addEntity(tmpl); entity = gEM.addEntity(tmpl).id;
writeEntityComponents(gEM.getEntity(entity.id)); writeEntityComponents(gEM.getEntity(entity));
EntityManager.EntitiesBlock* block = EntityManager.instance.getMetaData( EntityManager.EntitiesBlock* block = EntityManager.instance.getMetaData(
gEM.getEntity(entity.id)); gEM.getEntity(entity));
EntityManager.EntityInfo* info = block.type_info; EntityManager.EntityInfo* info = block.type_info;
writeln(info.add_listeners); writeln(info.add_listeners);
//if(info)assert(0); //if(info)assert(0);
@ -586,15 +586,15 @@ int main()
//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));
Entity entity2; EntityID entity2;
time = MonoTime.currTime; time = MonoTime.currTime;
EntityID[] entities = Mallocator.instance.makeArray!EntityID(1_000_000); EntityID[] entities = Mallocator.instance.makeArray!EntityID(1_000_000);
foreach (i; 0 .. 500_000) foreach (i; 0 .. 500_000)
{ {
entity2 = gEM.addEntity(tmpl); entity2 = gEM.addEntity(tmpl).id;
entities[i*2] = entity2.id; entities[i*2] = entity2;
entities[i*2+1] = gEM.addEntity(tmpl2).id; entities[i*2+1] = gEM.addEntity(tmpl2).id;
} }
@ -638,7 +638,7 @@ int main()
dur = (MonoTime.currTime - time).total!"usecs"; dur = (MonoTime.currTime - time).total!"usecs";
writeln("Update: ", dur, " usecs"); writeln("Update: ", dur, " usecs");
writeEntityComponents(gEM.getEntity(entity2.id)); writeEntityComponents(gEM.getEntity(entity2));
time = MonoTime.currTime; time = MonoTime.currTime;
@ -650,7 +650,7 @@ int main()
dur = (MonoTime.currTime - time).total!"usecs"; dur = (MonoTime.currTime - time).total!"usecs";
writeln("Update: ", dur, " usecs"); writeln("Update: ", dur, " usecs");
writeEntityComponents(gEM.getEntity(entity2.id)); writeEntityComponents(gEM.getEntity(entity2));
time = MonoTime.currTime; time = MonoTime.currTime;
@ -662,9 +662,9 @@ int main()
dur = (MonoTime.currTime - time).total!"usecs"; dur = (MonoTime.currTime - time).total!"usecs";
writeln("Update: ", dur, " usecs"); writeln("Update: ", dur, " usecs");
writeEntityComponents(gEM.getEntity(entity2.id)); writeEntityComponents(gEM.getEntity(entity2));
entity = gEM.addEntity(tmpl); entity = gEM.addEntity(tmpl).id;
gEM.begin(); gEM.begin();
gEM.update(); gEM.update();
@ -672,40 +672,39 @@ int main()
//Entity* pp;// = gEM.getEntity(entity.id); //Entity* pp;// = gEM.getEntity(entity.id);
//writeln((cast(uint*) pp)[0 .. 14], " ", pp); //writeln((cast(uint*) pp)[0 .. 14], " ", pp);
writeEntityComponents(gEM.getEntity(entity.id)); writeEntityComponents(gEM.getEntity(entity));
gEM.addEntity(tmpl); gEM.addEntity(tmpl);
gEM.addEntityCopy(entity);
gEM.addComponents(entity.id, TestComp4()); gEM.addComponents(entity, TestComp4());
gEM.addComponents(entity.id, TestComp3()); gEM.addComponents(entity, TestComp3());
gEM.begin(); gEM.begin();
gEM.update(); gEM.update();
gEM.end(); gEM.end();
writeEntityComponents(gEM.getEntity(entity.id)); writeEntityComponents(gEM.getEntity(entity));
gEM.removeComponents!(TestComp)(entity.id); gEM.removeComponents!(TestComp)(entity);
gEM.addComponents(entity.id, TestComp()); gEM.addComponents(entity, TestComp());
gEM.addComponents(entity.id, TestComp5()); gEM.addComponents(entity, TestComp5());
gEM.begin(); gEM.begin();
gEM.update(); gEM.update();
gEM.update("fixed"); gEM.update("fixed");
gEM.end(); gEM.end();
gEM.removeComponents!(TestComp4)(entity.id); gEM.removeComponents!(TestComp4)(entity);
gEM.commit();//*/ gEM.commit();//*/
writeEntityComponents(gEM.getEntity(entity.id)); writeEntityComponents(gEM.getEntity(entity));
//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);
gEM.freeTemplate(tmpl2); gEM.freeTemplate(tmpl2);
EntityManager.destroy(); EntityManager.destroy();
return 0; return 0;
} }