From 17551b08a50d4e480796b0914407d11290e59611 Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 12 Sep 2018 14:01:35 +0200 Subject: [PATCH] -IDManager -times counting for tests --- source/ecs/entity.d | 7 ++++- source/ecs/id_manager.d | 65 +++++++++++++++++++++++++++++++++++++++++ source/ecs/manager.d | 19 ++++++++++-- tests/tests.d | 37 ++++++++++++++++++----- 4 files changed, 118 insertions(+), 10 deletions(-) create mode 100644 source/ecs/id_manager.d diff --git a/source/ecs/entity.d b/source/ecs/entity.d index 726e03b..a079857 100644 --- a/source/ecs/entity.d +++ b/source/ecs/entity.d @@ -5,12 +5,17 @@ import ecs.manager; struct EntityID { uint id; - uint id_count; + uint counter; } struct Entity { EntityID id; + + void updateID() + { + EntityManager.instance.id_manager.update(this); + } } struct EntityTemplate diff --git a/source/ecs/id_manager.d b/source/ecs/id_manager.d new file mode 100644 index 0000000..da31560 --- /dev/null +++ b/source/ecs/id_manager.d @@ -0,0 +1,65 @@ +module ecs.id_manager; + +import ecs.entity; +import ecs.vector; + +struct IDManager +{ + EntityID getNewID() + { + while(m_next_id >= m_ids_array.length)m_ids_array.add(Data()); + EntityID id; + id.id = m_next_id; + id.counter = m_ids_array[m_next_id].counter++; + m_next_id = m_ids_array[m_next_id].next_id; + if(m_next_id == uint.max)m_next_id = cast(uint)m_ids_array.length; + return id; + } + + void releaseID(EntityID id) + { + Data* data = &m_ids_array[id.id]; + if(data.counter != id.counter)return; + data.next_id = m_next_id; + data.entity = null; + m_next_id = id.id; + } + + void update(ref Entity entity) + { + m_ids_array[entity.id.id].entity = &entity; + } + + struct Data + { + uint counter = 0; + uint next_id = uint.max; + Entity* entity = null; + } + + private uint m_next_id = 0; + Vector!Data m_ids_array; +} + +unittest +{ + IDManager manager; + EntityID id1 = manager.getNewID(); + EntityID id2 = manager.getNewID(); + EntityID id3 = manager.getNewID(); + + assert(id1 == EntityID(0,1)); + assert(id2 == EntityID(1,1)); + assert(id3 == EntityID(2,1)); + + manager.releaseID(id2); + manager.releaseID(id1); + + id2 = manager.getNewID(); + id1 = manager.getNewID(); + + assert(id1 == EntityID(1,2)); + assert(id2 == EntityID(0,2)); + assert(id3 == EntityID(2,1)); + +} \ No newline at end of file diff --git a/source/ecs/manager.d b/source/ecs/manager.d index 82ec519..82a091c 100644 --- a/source/ecs/manager.d +++ b/source/ecs/manager.d @@ -12,6 +12,7 @@ import ecs.system; import ecs.entity; import ecs.vector; import ecs.hash_map; +import ecs.id_manager; alias gEM = EntityManager.instance; @@ -23,6 +24,12 @@ class EntityManager instance = Mallocator.instance.make!EntityManager; } + static void destory() + { + Mallocator.instance.dispose(instance); + instance = null; + } + void registerSystem(Sys)(int priority) { alias types = Parameters!(Sys.update); @@ -197,7 +204,7 @@ class EntityManager { if (block is null) { - block = cast(EntitiesBlock*) AlignedMallocator.instance.alignedAllocate(4096, 4096); + block = cast(EntitiesBlock*) AlignedMallocator.instance.alignedAllocate(page_size, page_size); *block = EntitiesBlock(tmpl.info); if (previous_block is null) { @@ -211,7 +218,7 @@ class EntityManager break; // new block certainly has free space } // check if there is enought space - if (block.dataDelta() + (block.entities_count + 1) * tmpl.info.size > 4096) + if (block.dataDelta() + (block.entities_count + 1) * tmpl.info.size > page_size) { previous_block = block; block = block.next_block; @@ -224,6 +231,9 @@ class EntityManager void* start = block.dataBegin() + block.entities_count * tmpl.info.size; memcpy(start, tmpl.entity_data.ptr, tmpl.info.size); + Entity* entity = cast(Entity*)start; + entity.id = id_manager.getNewID(); + entity.updateID(); block.entities_count++; } @@ -273,8 +283,13 @@ class EntityManager ///there is a loooot of data (4kB, pure magic) } + enum page_size = 4096; + enum pages_in_block = 128; + alias SytemFuncType = void function(ref EntityManager.CallData data, void* entity); + IDManager id_manager; + HashMap!(ushort[], EntityInfo*) entities_infos; HashMap!(string, uint) components_map; System[] systems; diff --git a/tests/tests.d b/tests/tests.d index fc1ffbb..bec6983 100644 --- a/tests/tests.d +++ b/tests/tests.d @@ -5,14 +5,11 @@ import ecs.events; import ecs.system; import ecs.entity; +import core.time; +import std.stdio; + int main() { - return 0; -} - -unittest -{ - alias SerializeVector = ubyte[]; struct TestComp @@ -99,24 +96,50 @@ unittest EntityManager.initialize(); assert(gEM !is null); + MonoTime time = MonoTime.currTime; + gEM.registerComponent!TestComp2; gEM.registerComponent!TestComp; + + ulong dur = (MonoTime.currTime - time).total!"usecs"; + writeln("Components register time: ",dur," usecs"); + + time = MonoTime.currTime; + gEM.registerSystem!TestSystem(0); gEM.registerSystem!TestSystem2(0); + dur = (MonoTime.currTime - time).total!"usecs"; + writeln("System register time: ",dur," usecs"); + + time = MonoTime.currTime; + ushort[2] ids = [0,1]; EntityTemplate* tmpl = gEM.allocateTemplate(ids); *cast(EntityID*)tmpl.entity_data.ptr = EntityID(1,1); + dur = (MonoTime.currTime - time).total!"usecs"; + writeln("Template allocating time: ",dur," usecs"); + + time = MonoTime.currTime; + foreach(i; 0..1_000_000)gEM.addEntity(tmpl); + dur = (MonoTime.currTime - time).total!"usecs"; + writeln("Entities adding: ",dur," usecs"); + //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)); + time = MonoTime.currTime; + gEM.update(); - gEM.update(); + + dur = (MonoTime.currTime - time).total!"usecs"; + writeln("Update time: ",dur," usecs"); import std.stdio; writeln((cast(uint*)tmpl.info.first_block)[0..48]); gEM.freeTemplate(tmpl); + return 0; } \ No newline at end of file