diff --git a/dub.json b/dub.json index 03ad2af..6812a0d 100755 --- a/dub.json +++ b/dub.json @@ -7,6 +7,9 @@ "copyright": "Copyright © 2017-2018, Michał Masiukiewicz, Dawid Masiukiewicz", "license": "BSD", "sourcePaths" : ["source\/"], + "dflags-posix-ldc": [ + "-defaultlib=phobos2-ldc,druntime-ldc" + ], "configurations" : [ { "name" : "library", diff --git a/source/ecs/block_allocator.d b/source/ecs/block_allocator.d index cfb1d13..30afcc8 100644 --- a/source/ecs/block_allocator.d +++ b/source/ecs/block_allocator.d @@ -7,7 +7,7 @@ import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator; struct BlockAllocator(uint block_size, uint blocks_in_allocation) { - void* next_block; + void* next_block = null; void* getBlock() { diff --git a/source/ecs/entity.d b/source/ecs/entity.d index 3b8f59c..5e85211 100644 --- a/source/ecs/entity.d +++ b/source/ecs/entity.d @@ -20,9 +20,15 @@ struct Entity T* getComponent(T)() { EntityManager.EntitiesBlock* block = gEM.getMetaData(&this); - EntityManager.EntityInfo* info = block.type_data; - if(T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0)return null; - return cast(T*)(cast(void*)&this + info.deltas[T.component_id]); + EntityManager.EntityInfo* info = block.type_info; + if (T.component_id >= info.deltas.length || info.deltas[T.component_id] == 0) + return null; + + static if (EntityID.sizeof == 8) + uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) >> 3); + else + uint ind = cast(uint)((cast(void*)&this - block.dataBegin()) / EntityID.sizeof()); + return cast(T*)(cast(void*)block + info.deltas[T.component_id] + ind * T.sizeof); } } @@ -33,6 +39,7 @@ export struct EntityTemplate T* getComponent(T)() { - return cast(T*)(entity_data.ptr + info.deltas[T.component_id]); + if(T.component_id >= info.tmpl_deltas.length)return null; + return cast(T*)(entity_data.ptr + info.tmpl_deltas[T.component_id]); } } diff --git a/source/ecs/id_manager.d b/source/ecs/id_manager.d index 60f9d5c..86542e3 100644 --- a/source/ecs/id_manager.d +++ b/source/ecs/id_manager.d @@ -31,7 +31,7 @@ struct IDManager void update(ref Entity entity) { - m_ids_array[entity.id.id].entity = &entity; + if(entity.id.counter == m_ids_array[entity.id.id].counter)m_ids_array[entity.id.id].entity = &entity; } export Entity* getEntityPointer(EntityID id) diff --git a/source/ecs/manager.d b/source/ecs/manager.d index 9b4c724..2ba41fa 100644 --- a/source/ecs/manager.d +++ b/source/ecs/manager.d @@ -72,7 +72,22 @@ class EntityManager alias storages = ParameterStorageClassTuple!(Sys.update); static string genCall()() { - string ret = "s.update(*cast(Entity*)data_pointer,"; + string ret; + { + uint i = 0; + uint opt = 0; + static foreach (param; (Parameters!(Sys.update))[1 .. $]) + { + i++; + if (isPointer!param) + { + ret ~= "if(opt_array" ~ opt.to!string ~ " !is null)opt_ptr" + ~ opt.to!string ~ " = &opt_array" ~ opt.to!string ~ "[i];"; + opt++; + } + } + } + /*foreach (i; 1 .. (Parameters!(Sys.update)).length) { ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (i - 1) @@ -81,24 +96,57 @@ class EntityManager uint i = 0; uint req = 0; uint opt = 0; + ret ~= "s.update(id_array[i],"; static foreach (param; (Parameters!(Sys.update))[1 .. $]) { i++; if (isPointer!param) { - ret ~= "cast(types[" ~ i.to!string ~ "])(optional_pointers[" ~ (opt++) - .to!string ~ "]),"; + ret ~= "opt_ptr" ~ (opt++).to!string ~ ","; } else { - ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (req++) - .to!string ~ "]),"; + ret ~= "array" ~ (req++).to!string ~ "[i],"; } } + + ret ~= ");"; return ret; } + static string genArrays()() + { + string ret; + + uint i = 0; + uint req = 0; + uint opt = 0; + static foreach (param; (Parameters!(Sys.update))[1 .. $]) + { + i++; + if (isPointer!param) + { + ret ~= "PointerTarget!(types[" ~ i.to!string + ~ "])[] opt_array" ~ opt.to!string ~ " = null;"; + ret ~= "if(info.deltas[types[" ~ i.to!string ~ "].component_id] != 0)opt_array" + ~ opt.to!string ~ " + = (cast(types[" ~ i.to!string ~ "])(cast(void*)block + info.deltas[types[" + ~ i.to!string ~ "].component_id]))[0..block.entities_count];"; + ret ~= "types[" ~ i.to!string ~ "] opt_ptr" ~ opt.to!string ~ ";"; + opt++; + } + else + { + ret ~= "types[" ~ i.to!string ~ "][] array" ~ req.to!string ~ " = (cast(types[" + ~ i.to!string ~ "]*)(cast(void*)block + info.deltas[types[" + ~ i.to!string ~ "].component_id]))[0..block.entities_count];"; + req++; + } + } + return ret; + } + static string genCompList()() { string ret = "ushort comp;uint req;uint opt;"; @@ -154,30 +202,21 @@ class EntityManager EntitiesBlock* block = data.info.first_block; while (block !is null) { - uint size = block.type_data.size; - void* data_pointer = block.dataBegin(); - foreach (i, ref pointer; pointers) - { - pointer = data_pointer + data.deltas[i]; - } - foreach (i, ref pointer; optional_pointers) - { - uint ind = cast(uint)(i + pointers.length); - if (data.deltas[ind] != uint.max) - pointer = data_pointer + data.deltas[ind]; - else - pointer = null; - } + EntityInfo* info = block.type_info; + Entity[] id_array = (cast(Entity*) block.dataBegin())[0 + .. block.entities_count]; + mixin(genArrays()); foreach (i; 0 .. block.entities_count) { mixin(genCall()); - data_pointer += size; //data.info.size; - foreach (ref pointer; pointers) + //data_pointer += EntityID.sizeof; //data.info.size; + /*foreach (ref pointer; pointers) pointer += size; foreach (ref pointer; optional_pointers) if (pointer != null) - pointer += size; + pointer += size;*/ } + block = block.next_block; } @@ -225,12 +264,19 @@ class EntityManager if (sys_id < systems.length) { system.enable(); + + /*if (systems[sys_id].m_destroy) + systems[sys_id].m_destroy(systems[sys_id].m_system_pointer);*/ + if (system.m_create) + system.m_create(system.m_system_pointer); + systems[sys_id] = system; Sys.system_id = sys_id; } else { - systems_map.add(Sys.stringof, cast(ushort) systems.length); + string name = Mallocator.instance.makeArray(Sys.stringof); + systems_map.add(name, cast(ushort) systems.length); systems.add(system); @@ -257,7 +303,7 @@ class EntityManager Sys* getSystem(Sys)() { - return cast(Sys*) systems[Sys.system_id].system_pointer; + return cast(Sys*) systems[Sys.system_id].m_system_pointer; } void registerComponent(Comp)() @@ -290,12 +336,14 @@ class EntityManager if (comp_id < components.length) { Comp.component_id = comp_id; + components[comp_id] = info; } else { components.add(info); Comp.component_id = cast(ushort)(components.length - 1); - components_map.add(Comp.stringof, cast(ushort)(components.length - 1)); + string name = Mallocator.instance.makeArray(Comp.stringof); + components_map.add(name, cast(ushort)(components.length - 1)); } } @@ -352,6 +400,11 @@ class EntityManager num = cast(ushort)((num + alignment - 1) & (-cast(int) alignment)); //num += alignment - (num & (alignment - 1)); } + static ushort alignedNum(ushort num, ushort alignment) + { + return cast(ushort)((num + alignment - 1) & (-cast(int) alignment)); + } + extern (C) static int compareUShorts(const void* a, const void* b) { ushort _a = *cast(ushort*) a; @@ -395,10 +448,11 @@ class EntityManager //fill components with default data foreach (comp; info.components) { - temp.entity_data[info.deltas[comp] .. info.deltas[comp] + components[comp].size] + temp.entity_data[info.tmpl_deltas[comp] .. info.tmpl_deltas[comp] + components[comp].size] = components[comp].init_data; } + return temp; } @@ -415,15 +469,43 @@ class EntityManager info.size = EntityID.sizeof; info.alignment = EntityID.alignof; + info.tmpl_deltas = Mallocator.instance.makeArray!ushort(ids[$ - 1] + 1); + uint components_size = EntityID.sizeof; + foreach (i, id; ids) { info.alignment = max(info.alignment, components[id].alignment); alignNum(info.size, components[id].alignment); - info.deltas[id] = info.size; + info.tmpl_deltas[id] = info.size; info.size += components[id].size; + components_size += components[id].size; } alignNum(info.size, info.alignment); + /**/ + + uint block_memory = cast(uint)( + page_size - EntitiesBlock.sizeof - (info.size - components_size)); + //uint entity_comps_size = EntityID.sizeof; + uint mem_begin = EntitiesBlock.sizeof; + + /*foreach (id; ids) + { + entity_comps_size += components[id].size; + }*/ + + uint entites_in_block = block_memory / info.size; //entity_comps_size; + info.max_entities = cast(ushort) entites_in_block; + ushort current_delta = cast(ushort)(mem_begin + entites_in_block * EntityID.sizeof); + + foreach (i, id; ids) + { + alignNum(current_delta, components[id].alignment); + info.deltas[id] = cast(ushort) current_delta; + current_delta += entites_in_block * components[id].size; + } + + foreach (uint i, ref system; systems) { if (system.m_update is null) @@ -497,7 +579,6 @@ class EntityManager delta_id++; } - call_data.deltas = Mallocator.instance.makeArray(deltas); //Mallocator.instance.makeArray!ushort(system.m_components.length); uint index = 0; @@ -527,9 +608,10 @@ class EntityManager private void __removeComponents(EntityID entity_id, ushort[] del_ids) { Entity* entity = id_manager.getEntityPointer(entity_id); - if(!entity)return; + if (!entity) + return; EntitiesBlock* block = getMetaData(entity); - EntityInfo* info = block.type_data; + EntityInfo* info = block.type_info; qsort(del_ids.ptr, del_ids.length, ushort.sizeof, &compareUShorts); @@ -561,16 +643,21 @@ class EntityManager EntitiesBlock* new_block = findBlockWithFreeSpace(new_info); - void* start = new_block.dataBegin() + new_block.entities_count * new_info.size; - + void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof; + Entity* new_entity = cast(Entity*) start; new_entity.id = entity.id; new_entity.updateID(); + static if (EntityID.sizeof == 8) + uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) >> 3); + else + uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) / EntityID.sizeof()); foreach (comp; new_info.components) { - memcpy(cast(void*) new_entity + new_info.deltas[comp], - cast(void*) entity + info.deltas[comp], components[comp].size); + uint comp_size = components[comp].size; + memcpy(cast(void*) new_block + new_info.deltas[comp] + new_block.entities_count * comp_size, + cast(void*) block + info.deltas[comp] + ind * comp_size, comp_size); } new_block.entities_count++; @@ -598,9 +685,10 @@ class EntityManager { uint num = cast(uint) new_ids.length; Entity* entity = id_manager.getEntityPointer(entity_id); - if(!entity)return; + if (!entity) + return; EntitiesBlock* block = getMetaData(entity); - EntityInfo* info = block.type_data; + EntityInfo* info = block.type_info; ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length + num)))[0 .. info.components.length + num]; /*ushort[num] new_ids; @@ -668,47 +756,49 @@ class EntityManager EntitiesBlock* new_block = findBlockWithFreeSpace(new_info); - void* start = new_block.dataBegin() + new_block.entities_count * new_info.size; + //removeEntityNoID(entity, block); + void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof; + Entity* new_entity = cast(Entity*) start; new_entity.id = entity.id; new_entity.updateID(); - new_block.entities_count++; - - //removeEntityNoID(entity, block); j = 0; k = 0; + static if (EntityID.sizeof == 8) + uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) >> 3); + else + uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) / EntityID.sizeof()); foreach (ref id; ids) { + void* dst = cast(void*) new_block + new_info.deltas[id] + ( + new_block.entities_count + new_block.added_count) * components[id].size; + uint size = components[id].size; if (k >= new_ids.length) { - memcpy(cast(void*) new_entity + new_info.deltas[id], - cast(void*) entity + info.deltas[info.components[j]], - components[info.components[j]].size); //id = info.components[j++]; + memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size); j++; } else if (j >= info.components.length) { - memcpy(cast(void*) new_entity + new_info.deltas[id], - data_pointers[k], components[new_ids[k]].size); //id = new_ids[k++]; + memcpy(dst, data_pointers[k], size); k++; } else if (id == new_ids[k]) { - memcpy(cast(void*) new_entity + new_info.deltas[id], - data_pointers[k], components[new_ids[k]].size); //id = new_ids[k++]; + memcpy(dst, data_pointers[k], size); k++; } else { - memcpy(cast(void*) new_entity + new_info.deltas[id], - cast(void*) entity + info.deltas[info.components[j]], - components[info.components[j]].size); //id = info.components[j++]; + memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size); j++; } } + + new_block.entities_count++; removeEntityNoID(entity, block); } @@ -717,7 +807,7 @@ class EntityManager const uint num = Components.length; Entity* entity = id_manager.getEntityPointer(entity_id); EntitiesBlock* block = getMetaData(entity); - EntityInfo* info = block.type_data; + EntityInfo* info = block.type_info; ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length + num)))[0 .. info.components.length + num]; ushort[num] new_ids; @@ -755,10 +845,18 @@ class EntityManager export ref Entity addEntity(EntityTemplate* tmpl) { EntitiesBlock* block = findBlockWithFreeSpace(tmpl.info); + uint id = (block.entities_count + block.added_count); + EntityInfo* info = tmpl.info; + + void* data_begin = block.dataBegin(); + void* start = data_begin + EntityID.sizeof * id; + //memcpy(data_begin + EntityID.sizeof * id, tmpl.entity_data.ptr, EntityID.sizeof); + foreach (i, comp; info.components) + { + memcpy(cast(void*) block + info.deltas[comp] + components[comp].size * id, + tmpl.entity_data.ptr + info.tmpl_deltas[comp], components[comp].size); + } - void* start = block.dataBegin() + (block.entities_count + block.added_count) - * tmpl.info.size; - memcpy(start, tmpl.entity_data.ptr, tmpl.info.size); if (!block.added_count) blocks_to_update.add(block); @@ -791,14 +889,15 @@ class EntityManager { previous_block.next_block = block; block.prev_block = previous_block; - block.id = previous_block.id + 1; + block.id = cast(ushort)(previous_block.id + 1); } 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 + block.added_count + 1) * info.size > page_size) + /*if (block.dataDelta() + ( + block.entities_count + block.added_count + 1) * info.size > page_size)*/ + if (block.entities_count + block.added_count >= block.type_info.max_entities) { previous_block = block; block = block.next_block; @@ -834,41 +933,49 @@ class EntityManager { //pos is Entity number in block void* data_begin = block.dataBegin(); - uint pos = cast(int)(cast(void*) entity - data_begin) / block.type_data.size; + EntityInfo* info = block.type_info; block.entities_count--; //set "first_with_free_space" if should it be - if (block.type_data.first_with_free_space.id > block.id) - block.type_data.first_with_free_space = block; + if (info.first_with_free_space.id > block.id) + info.first_with_free_space = block; + + 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()); if (call_destructors) { - void* data = data_begin + pos * block.type_data.size; - foreach (comp; block.type_data.components) + //void* data = data_begin + pos * info.size; + foreach (comp; info.components) { if (components[comp].destroy_callback) { - components[comp].destroy_callback(data + block.type_data.deltas[comp]); + //components[comp].destroy_callback(data + info.deltas[comp]); + components[comp].destroy_callback(cast( + void*) block + info.deltas[comp] + pos * components[comp].size); } } } + if (block.entities_count == 0) { - if (block.type_data.first_block is block) + if (info.first_block is block) { - block.type_data.first_block = block.next_block; + info.first_block = block.next_block; } - if (block.type_data.first_with_free_space is block) + if (info.first_with_free_space is block) { - block.type_data.first_with_free_space = block.next_block;//block.type_data.first_block; + info.first_with_free_space = block.next_block; //info.first_block; } if (block.prev_block) { block.prev_block.next_block = block.next_block; } - if(block.next_block) + if (block.next_block) { block.next_block.prev_block = block.prev_block; } @@ -879,14 +986,17 @@ class EntityManager if (pos == block.entities_count) return; - //copy memory of last entity to position of removed entity - void* src = data_begin + block.entities_count * block.type_data.size; - void* dst = data_begin + pos * block.type_data.size; + 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); + } - memcpy(dst, src, block.type_data.size); + entity.id = *cast(EntityID*)(data_begin + block.entities_count * EntityID.sizeof); //update pointer for moved entity ID - entity = cast(Entity*) dst; + //entity = cast(Entity*) dst; entity.updateID(); } @@ -981,7 +1091,7 @@ class EntityManager removeEntities(); changeEntites(); - clearEvents(); + //clearEvents(); } struct ComponentInfo @@ -1006,12 +1116,19 @@ class EntityManager { ///entity components ushort[] components; - ///deltas in memory for components + + ///deltas in memory for components in EntitiesBlock ushort[] deltas; + ///deltas in memory for components in EntityTemplate + ushort[] tmpl_deltas; + ///alignment of whole entity - ushort alignment; + ushort alignment; //unused in linear-layout ///size of entity (with alignment respect) ushort size; + ///max number of entities in block + ushort max_entities; + ///pointer to first block/page EntitiesBlock* first_block; ///a hint for allocations @@ -1029,7 +1146,7 @@ class EntityManager uint dataDelta() { ushort dif = EntitiesBlock.sizeof; - alignNum(dif, type_data.alignment); + alignNum(dif, type_info.alignment); return dif; } @@ -1037,23 +1154,24 @@ class EntityManager export void* dataBegin() { ushort dif = EntitiesBlock.sizeof; - alignNum(dif, type_data.alignment); return cast(void*)&this + dif; } ///pointer to Entity type info - EntityInfo* type_data = null; + EntityInfo* type_info = null; ///number of entities in block ushort entities_count = 0; ///number of new entities in block ushort added_count = 0; ///block id - uint id = 0; + ushort id = 0; + ///maximum number of entities in block + //ushort max_entities = 0; ///pointer to next block/page EntitiesBlock* next_block = null; ///pointer to next block/page EntitiesBlock* prev_block = null; - //there is a loooot of data (4kB, pure magic) + //there is a loooot of data (some kB of memory, pure magic) } /************************************************************************************************************************ @@ -1068,7 +1186,7 @@ class EntityManager ///poiner to Entity type info EntityManager.EntityInfo* info; ///deltas for components - ushort[] deltas; + ushort[] deltas; //unused in linear-layout } alias SytemFuncType = void function(ref EntityManager.CallData data, void* entity); @@ -1078,7 +1196,7 @@ class EntityManager //alias event_manager this; ///Single page size. Must be power of two. - enum page_size = 4096; + enum page_size = 32768; //4096; ///Number of pages in block. enum pages_in_block = 128; diff --git a/source/ecs/vector.d b/source/ecs/vector.d index aeb0a9d..ef6a238 100644 --- a/source/ecs/vector.d +++ b/source/ecs/vector.d @@ -194,7 +194,7 @@ public: } export ref T opIndex(size_t elemNum) { - assert(elemNum < used, "Range violation [index]"); + debug assert(elemNum < used, "Range violation [index]"); return array.ptr[elemNum]; } diff --git a/tests/tests.d b/tests/tests.d index c4840ba..5fc09f9 100644 --- a/tests/tests.d +++ b/tests/tests.d @@ -23,11 +23,11 @@ int main() float a; } - struct TestComp + static struct TestComp { __gshared ushort component_id; - int a; - ulong b; + int a = 1; + ulong b = 2; static void serializeComponent(SerializeVector output) { @@ -40,11 +40,11 @@ int main() } } - struct TestComp2 + static struct TestComp2 { __gshared ushort component_id; - int b; - int a; + int b = 3; + int a = 4; static void serializeComponent(ref TestComp comp, SerializeVector output) { @@ -57,11 +57,11 @@ int main() } } - struct TestComp3 + static struct TestComp3 { __gshared ushort component_id; - uint gg; //good game - uint bg; //bad game + uint gg = 5; //good game + uint bg = 6; //bad game void serializeComponent(SerializeVector output) { @@ -74,11 +74,15 @@ int main() } } - struct TestComp4 + static struct TestComp4 { __gshared ushort component_id; - uint gg; //good game - uint bg; //bad game + uint gg = 7; //good game + uint bg = 8; //bad game + ulong a = 9; + ulong b = 10; + ulong c = 11; + ulong g = 12; static void serializeComponent(ref TestComp comp, SerializeVector output) { @@ -107,12 +111,12 @@ int main() void onBegin() { - writeln("On Test System begin."); + //writeln("On Test System begin."); } void onEnd() { - writeln("On Test System end."); + //writeln("On Test System end."); } void initialize(ref Entity entity, ref TestComp comp) @@ -127,7 +131,7 @@ int main() @("optional") TestComp3* test3; } - void update(ref Entity entity, ref TestComp test, ref TestComp2 test2, TestComp3* test3) //ref TestComp comp) + void update(ref Entity entity, ref TestComp test, ref TestComp2 test2)//, TestComp3* test3) //ref TestComp comp) { assert(cast(size_t)&test % TestComp.alignof == 0); assert(cast(size_t)&test2 % TestComp2.alignof == 0); @@ -141,8 +145,12 @@ int main() test2.a = 8; //writeln("Jakis tekst! ",test2.b); //writeln("Low priority tekst! "); - if (test3) + /*if (test3) + { test3.gg = 200; + test3.bg += 1; + }*/ + } void handleEvent(TestEvent event, ref TestComp test, ref TestComp2 test2, TestComp3* test3) @@ -209,6 +217,21 @@ int main() }*/ } + void writeEntityComponents(Entity* entity) + { + write(entity.id); + TestComp* test_comp = entity.getComponent!TestComp; + if(test_comp)write(*test_comp); + TestComp2* test_comp2 = entity.getComponent!TestComp2; + if(test_comp2)write(*test_comp2); + TestComp3* test_comp3 = entity.getComponent!TestComp3; + if(test_comp3)write(*test_comp3); + TestComp4* test_comp4 = entity.getComponent!TestComp4; + if(test_comp4)write(*test_comp4); + writeln(); + //writeln((cast(uint*) pp)[0 .. 14], " ", pp); + } + EntityManager.initialize(); assert(gEM !is null); @@ -237,14 +260,26 @@ int main() time = MonoTime.currTime; + //ushort[3] ids = [TestComp2.component_id, TestComp.component_id, TestComp4.component_id]; ushort[2] ids = [TestComp2.component_id, TestComp.component_id]; EntityTemplate* tmpl = gEM.allocateTemplate(ids); + + //ushort[3] ids2 = [TestComp3.component_id, TestComp.component_id, TestComp4.component_id]; + ushort[2] ids2 = [TestComp3.component_id, TestComp.component_id]; + EntityTemplate* tmpl2 = gEM.allocateTemplate(ids2); //writeln(tmpl.info.components[]); - *cast(EntityID*) tmpl.entity_data.ptr = EntityID(1, 1); + //*cast(EntityID*) tmpl.entity_data.ptr = EntityID(1, 1); dur = (MonoTime.currTime - time).total!"usecs"; writeln("Template allocating: ", dur, " usecs"); + Entity entity; + + { + entity = gEM.addEntity(tmpl); + writeEntityComponents(gEM.getEntity(entity.id)); + } + time = MonoTime.currTime; //foreach(i; 0..1_000_000)gEM.addEntity(tmpl); @@ -255,12 +290,17 @@ int main() foreach (i; 0 .. 1_000) { + gEM.begin(); foreach (j; 0 .. 1_000) idss[j] = gEM.addEntity(tmpl).id; foreach (j; 0 .. 1_000) gEM.removeEntity(idss[j]); + gEM.end(); } + dur = (MonoTime.currTime - time).total!"usecs"; + writeln("Entities adding: ", dur, " usecs"); + uint blocks = 0; foreach (info; &gEM.entities_infos.byValue) { @@ -273,13 +313,6 @@ int main() } writeln("Entities blocks: ", blocks); - /*Entity entity = gEM.addEntity(tmpl); - gEM.removeEntity(entity.id); - gEM.addEntity(tmpl);*/ - - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Entities adding: ", dur, " usecs"); - //foreach(j; 0..1_000)gEM.addEntity(tmpl); gEM.registerSystem!TestSystem2(0); @@ -287,43 +320,70 @@ int main() //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)); + foreach (i; 0 .. 500_000) + { + gEM.addEntity(tmpl); + gEM.addEntity(tmpl2); + } + time = MonoTime.currTime; - //gEM.update(); - - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Update: ", dur, " usecs"); - - Entity entity = gEM.addEntity(tmpl); - gEM.begin(); gEM.update(); gEM.end(); - Entity* pp = gEM.getEntity(entity.id); - writeln((cast(uint*) pp)[0 .. 14], " ", pp); + dur = (MonoTime.currTime - time).total!"usecs"; + writeln("Update: ", dur, " usecs"); + + time = MonoTime.currTime; + + gEM.begin(); + gEM.update(); + gEM.end(); + + dur = (MonoTime.currTime - time).total!"usecs"; + writeln("Update: ", dur, " usecs"); + + time = MonoTime.currTime; + + gEM.begin(); + gEM.update(); + gEM.end(); + + dur = (MonoTime.currTime - time).total!"usecs"; + writeln("Update: ", dur, " usecs"); + + writeEntityComponents(gEM.getEntity(entity.id)); + + entity = gEM.addEntity(tmpl); + + gEM.begin(); + gEM.update(); + gEM.end(); + + //Entity* pp;// = gEM.getEntity(entity.id); + //writeln((cast(uint*) pp)[0 .. 14], " ", pp); + writeEntityComponents(gEM.getEntity(entity.id)); gEM.addEntity(tmpl); + gEM.addComponents(entity.id, TestComp4()); gEM.addComponents(entity.id, TestComp3()); gEM.begin(); gEM.update(); gEM.end(); - pp = gEM.getEntity(entity.id); + writeEntityComponents(gEM.getEntity(entity.id)); - writeln((cast(uint*) pp)[0 .. 14], " ", pp); - - //gEM.removeComponents!(TestComp)(entity.id); + gEM.removeComponents!(TestComp)(entity.id); + gEM.addComponents(entity.id, TestComp()); gEM.begin(); gEM.update(); gEM.end(); - pp = gEM.getEntity(entity.id); - - writeln((cast(uint*) pp)[0 .. 14], " ", pp); + writeEntityComponents(gEM.getEntity(entity.id)); //import std.stdio; //writeln((cast(uint*)tmpl.info.first_block)[0..48]); @@ -331,4 +391,4 @@ int main() EntityManager.destroy(); return 0; -} +} \ No newline at end of file