diff --git a/source/ecs/block_allocator.d b/source/ecs/block_allocator.d index d2272dd..2894f61 100644 --- a/source/ecs/block_allocator.d +++ b/source/ecs/block_allocator.d @@ -10,7 +10,15 @@ struct BlockAllocator//(uint block_size, uint blocks_in_allocation) private uint block_size; private uint blocks_in_allocation; + struct BlockPointers + { + void*[32] blocks; + uint numberof = 0; + BlockPointers* next_pointers = null; + } + void* next_block = null; + BlockPointers* pointers = null; void* getBlock() nothrow @nogc { @@ -31,6 +39,16 @@ struct BlockAllocator//(uint block_size, uint blocks_in_allocation) { next_block = cast(void*) AlignedMallocator.instance.alignedAllocate( block_size * blocks_in_allocation, block_size); + + if(pointers is null)pointers = Mallocator.instance.make!BlockPointers; + if(pointers.numberof >= 32) + { + BlockPointers* new_pointers = Mallocator.instance.make!BlockPointers; + new_pointers.next_pointers = pointers; + pointers = new_pointers; + } + pointers.blocks[pointers.numberof++] = next_block; + foreach (i; 0 .. blocks_in_allocation - 1) { void** pointer = cast(void**)(next_block + i * block_size); @@ -40,4 +58,18 @@ struct BlockAllocator//(uint block_size, uint blocks_in_allocation) next_block + (blocks_in_allocation - 1) * block_size); *pointer = null; } + + void freeMemory() nothrow @nogc + { + while(pointers) + { + foreach(i;0..pointers.numberof) + { + AlignedMallocator.instance.dispose(pointers.blocks[i]); + } + BlockPointers* next_pointers = pointers.next_pointers; + Mallocator.instance.dispose(pointers); + pointers = next_pointers; + } + } } diff --git a/source/ecs/core.d b/source/ecs/core.d index 8f34fc0..64dceba 100644 --- a/source/ecs/core.d +++ b/source/ecs/core.d @@ -8,7 +8,8 @@ static struct ECS mixin template System(uint jobs_count = 32) { __gshared ushort system_id; - EntityManager.Job[] _ecs_jobs; + uint __ecs_jobs_count = jobs_count; + /*EntityManager.Job[] _ecs_jobs; void __ecsInitialize() nothrow @nogc { @@ -16,6 +17,13 @@ static struct ECS import std.experimental.allocator; _ecs_jobs = Mallocator.instance.makeArray!(EntityManager.Job)(jobs_count); } + + void __ecsDeinitialize() nothrow @nogc + { + import std.experimental.allocator.mallocator; + import std.experimental.allocator; + Mallocator.instance.dispose(_ecs_jobs); + }*/ } mixin template Component() diff --git a/source/ecs/events.d b/source/ecs/events.d index ca9bade..47d9415 100644 --- a/source/ecs/events.d +++ b/source/ecs/events.d @@ -175,15 +175,7 @@ struct EventManager void allocateData(uint threads_count) nothrow @nogc { - if(events) - { - foreach(ref event;events) - { - Mallocator.instance.dispose(event.blocks); - Mallocator.instance.dispose(event.first_blocks); - } - Mallocator.instance.dispose(events); - } + disposeData(); events = Mallocator.instance.makeArray!EventData(gEM.events.length); foreach(i,ref event;events) { @@ -196,8 +188,44 @@ struct EventManager } } + private void disposeData() nothrow @nogc + { + if(events) + { + foreach(ref event;events) + { + foreach(first_block; event.first_blocks) + { + EventBlock* block = first_block; + EventBlock* next_block; + if(block)next_block = first_block.next; + while(block) + { + Mallocator.instance.dispose(block); + block = next_block; + if(block)next_block = block.next; + } + } + + Mallocator.instance.dispose(event.blocks); + Mallocator.instance.dispose(event.first_blocks); + } + Mallocator.instance.dispose(events); + } + allocator.freeMemory(); + } + + ~this() nothrow @nogc + { + disposeData(); + /*foreach(i,ref event;events) + { + EventBlock* block = event.first_blocks; + }*/ + } + ///Single page size. Must be power of two. - enum events_block_size = 1 << 12; + enum events_block_size = 1 << 14; ///Number of pages in block. enum events_blocks_in_allocation = 128; diff --git a/source/ecs/id_manager.d b/source/ecs/id_manager.d index 07566d3..3ee7f1c 100644 --- a/source/ecs/id_manager.d +++ b/source/ecs/id_manager.d @@ -154,6 +154,24 @@ begin: add_mutex = Mallocator.instance.make!Mutex(); } + void deinitialize() @trusted @nogc + { + if(m_ids_array)Mallocator.instance.dispose(m_ids_array); + if(m_free_stack)Mallocator.instance.dispose(m_free_stack); + if(m_blocks) + { + foreach(ref block;m_blocks) + { + if(block.data)block.free(); + } + Mallocator.instance.dispose(m_blocks); + } + if(add_mutex) + { + Mallocator.instance.dispose(cast(void*)add_mutex); //workaround for compiler bug + } + } + void optimize() nothrow @nogc { if(m_stack_top < -1)m_stack_top = -1; @@ -176,7 +194,7 @@ begin: begin += 65536; } memcpy(cast(void*)m_ids_array.ptr + begin * Data.sizeof, m_blocks[m_blocks_count-1].data.ptr, (m_last_id - begin) * Data.sizeof); - foreach(block;m_blocks[1..m_blocks_count])block.free(); + foreach(ref block;m_blocks[1..m_blocks_count])block.free(); m_blocks_count = 1; } } @@ -193,9 +211,10 @@ begin: { assert(data !is null); Mallocator.instance.dispose(data); + data = null; } - Data[] data; //65536 + Data[] data = null; //65536 } private static struct Data diff --git a/source/ecs/manager.d b/source/ecs/manager.d index 1197767..19d7cd1 100644 --- a/source/ecs/manager.d +++ b/source/ecs/manager.d @@ -20,6 +20,7 @@ import ecs.block_allocator; import ecs.hash_map; import ecs.id_manager; import ecs.vector; +import ecs.simple_vector; import ecs.events; import ecs.traits; @@ -36,7 +37,17 @@ export class EntityManager export static void initialize(uint threads_count) { if (instance is null) + { instance = Mallocator.instance.make!EntityManager(threads_count); + + with(instance) + { + UpdatePass* pass = Mallocator.instance.make!UpdatePass; + pass.name = Mallocator.instance.makeArray("update"); + passes.add(pass); + passes_map.add(cast(string) pass.name, cast(ushort)(passes.length - 1)); + } + } } export static void destroy() @@ -44,19 +55,58 @@ export class EntityManager if (instance is null) return; - foreach (ref system; instance.systems) + with(instance) { - system.disable(); - } + foreach (ref system; systems) + { + system.disable(); + if (system.m_destroy) + (cast(void function(void*)) system.m_destroy)(system.m_system_pointer); - foreach (ref system; instance.systems) - { - if (system.m_destroy) - (cast(void function(void*)) system.m_destroy)(system.m_system_pointer); + if(system.jobs)Mallocator.instance.dispose(system.jobs); + if(system.m_read_only_components)Mallocator.instance.dispose(system.m_read_only_components); + if(system.m_modified_components)Mallocator.instance.dispose(system.m_modified_components); + if(system.m_components)Mallocator.instance.dispose(system.m_components); + if(system.m_excluded_components)Mallocator.instance.dispose(system.m_excluded_components); + if(system.m_optional_components)Mallocator.instance.dispose(system.m_optional_components); + if(system.name)Mallocator.instance.dispose(system.name); + if(system.m_event_callers)Mallocator.instance.dispose(system.m_event_callers); + + if(system.m_system_pointer)Mallocator.instance.dispose(system.m_system_pointer); + } + + foreach(EntityInfo* info;&entities_infos.byValue) + { + //if(info.components)Mallocator.instance.dispose(info.components); + + Mallocator.instance.dispose(info); + } + + foreach(UpdatePass* pass; passes) + { + Mallocator.instance.dispose(pass); + } + passes.clear(); + + foreach(ComponentInfo info; components) + { + if(info.init_data)Mallocator.instance.dispose(info.init_data); + } + + foreach(EventInfo info; events) + { + if(info.callers)Mallocator.instance.dispose(info.callers); + } + + foreach(name; &components_map.byKey) + { + if(name)Mallocator.instance.dispose(name); + } } Mallocator.instance.dispose(instance); instance = null; + } /************************************************************************************************************************ @@ -198,12 +248,16 @@ export class EntityManager entity_block_alloc_mutex = Mallocator.instance.make!Mutex; //event_manager = EventManager(this); //event_manager.manager = this; + } - UpdatePass* pass = Mallocator.instance.make!UpdatePass; - pass.name = Mallocator.instance.makeArray("update"); - passes.add(pass); + ~this() + { + id_manager.deinitialize(); - passes_map.add(cast(string) pass.name, cast(ushort)(passes.length - 1)); + if(threads)Mallocator.instance.dispose(threads); + if(entity_block_alloc_mutex)Mallocator.instance.dispose(entity_block_alloc_mutex); + + allocator.freeMemory(); } /************************************************************************************************************************ @@ -451,7 +505,7 @@ export class EntityManager enum ComponentsIndices components_info = getComponentsInfo(); - static void genCompList()(ref System system, ref HashMap!(const(char)[], ushort) components_map) + static void genCompList()(ref System system, ref HashMap!(char[], ushort) components_map) { foreach (member; __traits(allMembers, Sys.EntitiesData)) @@ -661,12 +715,13 @@ export class EntityManager system.m_system_pointer = cast(void*) Mallocator.instance.make!Sys; system.m_priority = priority; - (cast(Sys*) system.m_system_pointer).__ecsInitialize(); - system.jobs = (cast(Sys*) system.m_system_pointer)._ecs_jobs; + //(cast(Sys*) system.m_system_pointer).__ecsInitialize(); + //system.jobs = (cast(Sys*) system.m_system_pointer)._ecs_jobs; + system.jobs = Mallocator.instance.makeArray!(Job)((cast(Sys*) system.m_system_pointer).__ecs_jobs_count); genCompList(system, components_map); - ushort sys_id = systems_map.get(Sys.stringof, ushort.max); + ushort sys_id = systems_map.get(cast(char[])Sys.stringof, ushort.max); if (sys_id < systems.length) { system.enable(); @@ -761,7 +816,7 @@ export class EntityManager info.init_data = Mallocator.instance.makeArray!ubyte(Comp.sizeof); *cast(Comp*) info.init_data.ptr = Comp.init; // = Comp(); - ushort comp_id = components_map.get(Comp.stringof, ushort.max); + ushort comp_id = components_map.get(cast(char[])Comp.stringof, ushort.max); if (comp_id < components.length) { Comp.component_id = comp_id; @@ -771,7 +826,7 @@ export class EntityManager { components.add(info); Comp.component_id = cast(ushort)(components.length - 1); - const(char)[] name = Mallocator.instance.makeArray(Comp.stringof); + char[] name = Mallocator.instance.makeArray(Comp.stringof); components_map.add(name, cast(ushort)(components.length - 1)); } } @@ -1331,9 +1386,9 @@ export class EntityManager ThreadData* data = &threads[thread_id]; uint num = cast(uint) del_ids.length; data.change_entities_list.add(0); - data.change_entities_list.add((cast(ubyte*)&entity_id)[0 .. 8]); - data.change_entities_list.add((cast(ubyte*)&num)[0 .. 4]); - data.change_entities_list.add(cast(ubyte[]) del_ids); + data.change_entities_list.add((cast(ubyte*)&entity_id)[0 .. EntityID.sizeof]); + data.change_entities_list.add((cast(ubyte*)&num)[0 .. uint.sizeof]); + data.change_entities_list.add((cast(ubyte*)del_ids.ptr)[0 .. num * 2]); } private void __removeComponents(EntityID entity_id, ushort[] del_ids) @@ -1349,7 +1404,9 @@ export class EntityManager ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length)))[0 .. info.components.length]; - uint j = 0; + EntityInfo* new_info = info; + + /*uint j = 0; uint k = 0; foreach (id; info.components) { @@ -1362,15 +1419,23 @@ export class EntityManager else if (del_ids[k] == info.components[j]) { k++; + new_info = new_info.getNewInfoAdd(del_ids[k]); } else ids[j++] = id; } if (j == info.components.length) - return; + return;*/ - EntityInfo* new_info = getEntityInfo(ids[0 .. j]); + foreach(id;del_ids) + { + new_info = new_info.getNewInfoRemove(id); + } + + if(new_info == info)return; + + //EntityInfo* new_info = getEntityInfo(ids[0 .. j]); EntitiesBlock* new_block = findBlockWithFreeSpace(new_info); @@ -1459,8 +1524,8 @@ export class EntityManager return; EntitiesBlock* block = getMetaData(entity); EntityInfo* info = block.type_info; - ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length + num)))[0 - .. info.components.length + num]; + /*ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length + num)))[0 + .. info.components.length + num];*/ /*ushort[num] new_ids; static foreach (i, comp; Components) @@ -1498,7 +1563,9 @@ export class EntityManager } } - uint j = 0; + EntityInfo* new_info = info; + + /* uint j = 0; uint k = 0; uint len = 0; //foreach (ref id; ids) @@ -1515,6 +1582,7 @@ export class EntityManager else if (j >= info.components.length) { *id = new_ids[k++]; + new_info = new_info.getNewInfoAdd(*id); //continue; } else if (new_ids[k] == info.components[j]) @@ -1523,18 +1591,26 @@ export class EntityManager k++; } /*debug if (new_ids[k] == info.components[j]) - assert(0, "Trying to add already existing component!");*/ + assert(0, "Trying to add already existing component!");//* else if (new_ids[k] < info.components[j]) { *id = new_ids[k++]; + new_info = new_info.getNewInfoAdd(*id); } else *id = info.components[j++]; } if (len == info.components.length) - return; + return;*/ - EntityInfo* new_info = getEntityInfo(ids[0 .. len]); + foreach(id;new_ids) + { + new_info = new_info.getNewInfoAdd(id); + } + + if(new_info == info)return; + + //EntityInfo* new_info = getEntityInfo(ids[0 .. len]); EntitiesBlock* new_block = findBlockWithFreeSpace(new_info); @@ -1544,8 +1620,8 @@ export class EntityManager new_entity.id = entity.id; new_entity.updateID(); - j = 0; - k = 0; + uint j = 0; + uint k = 0; static if (EntityID.sizeof == 8) uint ind = cast(uint)((cast(void*) entity - block.dataBegin()) >> 3); else @@ -1562,7 +1638,7 @@ export class EntityManager } } - foreach (ref id; ids[0 .. len]) + foreach (ref id; new_info.components)//ids[0 .. len]) { void* dst = cast(void*) new_block + new_info.deltas[id] + ( new_block.entities_count /*+ new_block.added_count*/ ) * components[id].size; @@ -1646,9 +1722,9 @@ export class EntityManager pointers[i] = ∁ }*/ ThreadData* data = &threads[thread_id]; - data.change_entities_list.add(1); - data.change_entities_list.add((cast(ubyte*)&entity_id)[0 .. 8]); - data.change_entities_list.add((cast(ubyte*)&num)[0 .. 4]); + data.change_entities_list.add(cast(ubyte)1u); + data.change_entities_list.add((cast(ubyte*)&entity_id)[0 .. EntityID.sizeof]); + data.change_entities_list.add((cast(ubyte*)&num)[0 .. uint.sizeof]); data.change_entities_list.add(cast(ubyte[]) new_ids); static foreach (i, comp; comps) { @@ -1903,6 +1979,7 @@ export class EntityManager { uint index = 0; uint len = cast(uint) thread.change_entities_list.length; + void*[32] pointers;// = (cast(void**) alloca(num * (void*).sizeof))[0 .. num]; while (index < len) { if (!thread.change_entities_list[index++]) @@ -1911,8 +1988,8 @@ export class EntityManager index += EntityID.sizeof; uint num = *cast(uint*)&thread.change_entities_list[index]; index += uint.sizeof; - ushort[] ids = (cast(ushort*) alloca(num * ushort.sizeof))[0 .. num]; - ids[0 .. $] = (cast(ushort*)&thread.change_entities_list[index])[0 .. num]; + ushort[] ids;// = (cast(ushort*) alloca(num * ushort.sizeof))[0 .. num]; + ids = (cast(ushort*)&thread.change_entities_list[index])[0 .. num]; index += ushort.sizeof * num; __removeComponents(id, ids); } @@ -1922,16 +1999,16 @@ export class EntityManager index += EntityID.sizeof; uint num = *cast(uint*)&thread.change_entities_list[index]; index += uint.sizeof; - ushort[] ids = (cast(ushort*) alloca(num * ushort.sizeof))[0 .. num]; - ids[0 .. $] = (cast(ushort*)&thread.change_entities_list[index])[0 .. num]; + ushort[] ids;// = (cast(ushort*) alloca(num * ushort.sizeof))[0 .. num]; + ids = (cast(ushort*)&thread.change_entities_list[index])[0 .. num]; index += ushort.sizeof * num; - void*[] pointers = (cast(void**) alloca(num * (void*).sizeof))[0 .. num]; + //void*[] pointers = (cast(void**) alloca(num * (void*).sizeof))[0 .. num]; foreach (i; 0 .. num) { pointers[i] = &thread.change_entities_list[index]; index += components[ids[i]].size; } - __addComponents(id, ids, pointers); + __addComponents(id, ids, pointers[0..num]); } } thread.change_entities_list.clear(); @@ -2361,6 +2438,93 @@ export class EntityManager } } + EntityInfo* getNewInfoAdd(ushort id) + { + if(comp_add_info.length < id) + { + EntityInfo*[] new_infos = Mallocator.instance.makeArray!(EntityInfo*)(instance.components.length); + if(comp_add_info !is null) + { + new_infos[0 .. comp_add_info.length] = comp_add_info[0 .. $]; + Mallocator.instance.dispose(comp_add_info); + } + comp_add_info = new_infos; + } + if(comp_add_info[id])return comp_add_info[id]; + + ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (components.length + 1)))[0 + .. components.length + 1]; + uint len = 0; + + foreach(comp; components) + { + if(id > comp) + { + ids[len++] = comp; + } + else if(id == comp)return &this; + else + { + ids[len++] = id; + ids[len++] = comp; + } + } + if(id > components[$ - 1])ids[len++] = id; + + assert(len == components.length + 1); + + EntityInfo* new_info = instance.getEntityInfo(ids[0 .. len]); + + comp_add_info[id] = new_info; + return new_info; + } + + EntityInfo* getNewInfoRemove(ushort id) + { + if(comp_rem_info.length < id) + { + EntityInfo*[] new_infos = Mallocator.instance.makeArray!(EntityInfo*)(instance.components.length); + if(comp_rem_info !is null) + { + new_infos[0 .. comp_rem_info.length] = comp_rem_info[0 .. $]; + Mallocator.instance.dispose(comp_rem_info); + } + comp_rem_info = new_infos; + } + if(comp_rem_info[id])return comp_rem_info[id]; + + ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (components.length - 1)))[0 + .. components.length - 1]; + uint len = 0; + + foreach(comp; components) + { + if(id != comp) + { + ids[len++] = comp; + } + } + if(len == components.length)return &this; + + assert(len == components.length - 1); + + EntityInfo* new_info = instance.getEntityInfo(ids[0 .. len]); + + comp_rem_info[id] = new_info; + return new_info; + } + + ~this() + { + if(components)Mallocator.instance.dispose(components); + if(deltas)Mallocator.instance.dispose(deltas); + if(tmpl_deltas)Mallocator.instance.dispose(tmpl_deltas); + if(systems)Mallocator.instance.dispose(systems); + if(add_listeners)Mallocator.instance.dispose(add_listeners); + if(remove_listeners)Mallocator.instance.dispose(remove_listeners); + if(change_listeners)Mallocator.instance.dispose(change_listeners); + } + ///entity components ushort[] components; @@ -2369,6 +2533,11 @@ export class EntityManager ///deltas in memory for components in EntityTemplate ushort[] tmpl_deltas; + ///cached new infos after adding component + EntityInfo*[] comp_add_info; + ///cached new infos after removing component + EntityInfo*[] comp_rem_info; + ///alignment of whole entity ushort alignment; //unused in linear-layout ///size of entity (with alignment respect) @@ -2497,6 +2666,9 @@ export class EntityManager if (dependencies) { Mallocator.instance.dispose(dependencies); + } + if(exclusion) + { Mallocator.instance.dispose(exclusion); } if (job_group.dependencies) @@ -2514,7 +2686,8 @@ export class EntityManager struct ThreadData { Vector!EntityID entities_to_remove; - Vector!ubyte change_entities_list; + //Vector!ubyte change_entities_list; + SimpleVector change_entities_list; Vector!(EntitiesBlock*) blocks_to_update; } @@ -2525,6 +2698,11 @@ export class EntityManager assert(name); if (name) Mallocator.instance.dispose(name); + foreach(caller; system_callers) + { + Mallocator.instance.dispose(caller); + } + system_callers.clear(); } char[] name; @@ -2555,8 +2733,8 @@ export class EntityManager uint delegate() m_thread_id_func; HashMap!(ushort[], EntityInfo*) entities_infos; - HashMap!(const(char)[], ushort) systems_map; - HashMap!(const(char)[], ushort) components_map; + HashMap!(char[], ushort) systems_map; + HashMap!(char[], ushort) components_map; HashMap!(const(char)[], ushort) events_map; HashMap!(const(char)[], ushort) passes_map; Vector!System systems; @@ -2575,6 +2753,15 @@ export class EntityManager uint allocated = 0; } + ~this() + { + foreach(block;blocks) + { + Mallocator.instance.dispose(block); + } + blocks.clear(); + } + Vector!(Block*) blocks; uint id; diff --git a/source/ecs/simple_vector.d b/source/ecs/simple_vector.d new file mode 100644 index 0000000..1751040 --- /dev/null +++ b/source/ecs/simple_vector.d @@ -0,0 +1,66 @@ +module ecs.simple_vector; + +import std.experimental.allocator; +import std.experimental.allocator.mallocator; + +import core.stdc.string; + +struct SimpleVector +{ + + @disable this(this); + + void add(ubyte el) nothrow @nogc + { + while(used >= data.length) + { + if(data is null)data = Mallocator.instance.makeArray!ubyte(1024); + else Mallocator.instance.expandArray(data,data.length); + } + data[used++] = el; + } + + void add(ubyte[] el) nothrow @nogc + { + while(used + el.length >= data.length) + { + if(data is null)data = Mallocator.instance.makeArray!ubyte(1024); + else Mallocator.instance.expandArray(data,data.length); + } + memcpy(data.ptr + used, el.ptr, el.length); + used += el.length; + } + + size_t length() nothrow @nogc + { + return used; + } + + export ref ubyte opIndex(size_t pos) nothrow @nogc + { + return data[pos]; + } + + export ubyte[] opSlice() nothrow @nogc + { + return data[0 .. used]; + } + + export ubyte[] opSlice(size_t x, size_t y) nothrow @nogc + { + return data[x .. y]; + } + + export size_t opDollar() nothrow @nogc + { + return used; + } + + void clear() nothrow @nogc + { + used = 0; + } + + ubyte[] data = null; + size_t used = 0; +} \ No newline at end of file diff --git a/source/ecs/system.d b/source/ecs/system.d index 765c380..e033147 100644 --- a/source/ecs/system.d +++ b/source/ecs/system.d @@ -97,7 +97,7 @@ package: int m_pass; ///system name - const(char)[] name; + char[] name; ///required components ushort[] m_components; diff --git a/tests/tests.d b/tests/tests.d index db85ba7..edd8b16 100644 --- a/tests/tests.d +++ b/tests/tests.d @@ -1,5 +1,8 @@ module tests.tests; +import std.experimental.allocator; +import std.experimental.allocator.mallocator; + import ecs.entity; import ecs.events; import ecs.manager; @@ -136,18 +139,22 @@ struct ChangeTestSystem void onAddEntity(EntitiesData data) { + //printf("Entity added! ID: "); foreach (i; 0 .. data.length) - writeln("Entity added! ID: ", data.entites[i].id.id); + printf("Entity added! ID: %u\n",data.entites[i].id); + //writeln("Entity added! ID: ", data.entites[i].id); } void onRemoveEntity(EntitiesData data) { - writeln("Entity removed! ID: ", data.entites[0].id); + //writeln("Entity removed! ID: ", data.entites[0].id); + printf("Entity removed! ID: %u\n",data.entites[0].id); } void onChangeEntity(EntitiesData data) { - writeln("Entity changed! ID: ", data.entites[0].id); + //writeln("Entity changed! ID: ", data.entites[0].id); + printf("Entity changed! ID: %u\n",data.entites[0].id); } bool onBegin() @@ -532,7 +539,8 @@ int main() //foreach(i; 0..1_000_000)gEM.removeEntity(gEM.addEntity(tmpl).id); - EntityID[5000] idss; + EntityID[] idss = Mallocator.instance.makeArray!EntityID(5000);//[5000] + scope(exit)Mallocator.instance.dispose(idss); foreach (i; 0 .. 200) { @@ -563,7 +571,7 @@ int main() //foreach(j; 0..1_000)gEM.addEntity(tmpl); gEM.beginRegister(); - gEM.registerSystem!TestSystem2(0); + //gEM.registerSystem!TestSystem2(0); gEM.endRegister(); //gEM.generateDependencies(); @@ -575,10 +583,12 @@ int main() time = MonoTime.currTime; + EntityID[] entities = Mallocator.instance.makeArray!EntityID(1_000_000); foreach (i; 0 .. 500_000) { entity2 = gEM.addEntity(tmpl); - gEM.addEntity(tmpl2); + entities[i*2] = entity2.id; + entities[i*2+1] = gEM.addEntity(tmpl2).id; } gEM.commit(); @@ -587,6 +597,32 @@ int main() time = MonoTime.currTime; + foreach (i; 0 .. 1_000_000) + { + EntityManager.instance.addComponents(entities[i],TestComp5()); + if((i & 0x00FFFF) == 0)gEM.commit(); + } + + gEM.commit(); + dur = (MonoTime.currTime - time).total!"usecs"; + writeln("Components adding: ", dur, " usecs"); + + time = MonoTime.currTime; + + foreach (i; 0 .. 1_000_000) + { + EntityManager.instance.removeComponents!TestComp5(entities[i]); + //if((i & 0x00FFFF) == 0)gEM.commit(); + } + + gEM.commit(); + dur = (MonoTime.currTime - time).total!"usecs"; + writeln("Components removing: ", dur, " usecs"); + + Mallocator.instance.dispose(entities); + + time = MonoTime.currTime; + gEM.begin(); //gEM.updateMT(); gEM.update(); @@ -653,13 +689,16 @@ int main() gEM.removeComponents!(TestComp4)(entity.id); - gEM.commit(); + gEM.commit();//*/ writeEntityComponents(gEM.getEntity(entity.id)); //import std.stdio; //writeln((cast(uint*)tmpl.info.first_block)[0..48]); gEM.freeTemplate(tmpl); + gEM.freeTemplate(tmpl2); EntityManager.destroy(); + + return 0; }