From a080a6d415eafa881edf2fd423e1c45f9e204df3 Mon Sep 17 00:00:00 2001 From: Mergul Date: Sat, 28 Mar 2020 22:34:11 +0100 Subject: [PATCH] -fixed bug with adding components -optimize adding and removing components --- dub.json | 3 -- source/ecs/manager.d | 90 ++++++++++++++++++++++++++++++-------------- 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/dub.json b/dub.json index 87b9b7b..02ea4b2 100755 --- a/dub.json +++ b/dub.json @@ -7,9 +7,6 @@ "copyright": "Copyright © 2018-2019, Michał Masiukiewicz, Dawid Masiukiewicz", "license": "BSD", "sourcePaths" : ["source\/"], - "dflagss": [ - "-betterC" - ], "excludedSourceFiles":[ "source\/ecs\/traits.d" ], diff --git a/source/ecs/manager.d b/source/ecs/manager.d index 747e1ed..ae94cf7 100644 --- a/source/ecs/manager.d +++ b/source/ecs/manager.d @@ -1499,6 +1499,15 @@ export struct EntityManager addSystemCaller(*info, cast(uint) i); } + info.comp_add_info = Mallocator.makeArray!(EntityInfo*)(instance.components.length); + info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(instance.components.length, info); + + foreach(comp; info.components) + { + info.comp_add_info[comp] = info; + info.comp_rem_info[comp] = null; + } + entities_infos.add(info.components, info); generateListeners(info); @@ -1762,10 +1771,22 @@ export struct EntityManager EntitiesBlock* block = getMetaData(entity); EntityInfo* info = block.type_info; - qsort(del_ids.ptr, del_ids.length, ushort.sizeof, &compareUShorts); + //remove non-existing components + uint num = cast(uint)del_ids.length; + foreach_reverse(i; 0 .. num) + { + if(info.deltas.length <= del_ids[i] || info.deltas[del_ids[i]] == 0) + { + num--; + del_ids[i] = del_ids[num]; + } + } + + if(num == 0)return; + del_ids = del_ids[0 .. num]; - ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length)))[0 - .. info.components.length]; + //sort components + qsort(del_ids.ptr, del_ids.length, ushort.sizeof, &compareUShorts); EntityInfo* new_info = info; @@ -1774,10 +1795,8 @@ export struct EntityManager new_info = new_info.getNewInfoRemove(id); } - if (new_info == info) - return; - - //EntityInfo* new_info = getEntityInfo(ids[0 .. j]); + /*if (new_info == info) + return;*/ EntitiesBlock* new_block = findBlockWithFreeSpace(new_info); @@ -1785,7 +1804,7 @@ export struct EntityManager Entity* new_entity = cast(Entity*) start; new_entity.id = entity.id; - id_manager.update(*new_entity); //new_entity.updateID(); + id_manager.update(*new_entity); uint ind = block.entityIndex(entity); @@ -1864,6 +1883,18 @@ export struct EntityManager EntitiesBlock* block = getMetaData(entity); EntityInfo* info = block.type_info; + foreach_reverse(i; 0 .. num) + { + if(info.deltas.length > new_ids[i] && info.deltas[new_ids[i]] != 0) + { + num--; + new_ids[i] = new_ids[num]; + } + } + + if(num == 0)return; + new_ids = new_ids[0 .. num]; + foreach (int i; 0 .. num) { ushort min = new_ids[i]; @@ -1893,9 +1924,10 @@ export struct EntityManager { new_info = new_info.getNewInfoAdd(id); } - - if (new_info == info) - return; + + assert(new_info != info); + /*if (new_info == info) + return;*/ //EntityInfo* new_info = getEntityInfo(ids[0 .. len]); @@ -1922,28 +1954,25 @@ export struct EntityManager } } - foreach (ref id; new_info.components) //ids[0 .. len]) + foreach (id; new_info.components) //ids[0 .. len]) { void* dst = cast(void*) new_block + new_info.deltas[id] + ( new_block.entities_count) * components[id].size; uint size = components[id].size; + if (k >= new_ids.length) { memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size); j++; } - else if (j >= info.components.length) - { - memcpy(dst, data_pointers[k], size); - k++; - } - else if (id == new_ids[k]) + else if (j >= info.components.length || id == new_ids[k]) { memcpy(dst, data_pointers[k], size); k++; } else { + assert(id != new_ids[0]); memcpy(dst, cast(void*) block + info.deltas[id] + ind * size, size); j++; } @@ -1987,11 +2016,11 @@ export struct EntityManager void addComponents(Components...)(const EntityID entity_id, Components comps) nothrow @nogc { const uint num = Components.length; - Entity* entity = id_manager.getEntityPointer(entity_id); - 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]; + //Entity* entity = id_manager.getEntityPointer(entity_id); + //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[num] new_ids; static foreach (i, comp; Components) @@ -2763,7 +2792,7 @@ export struct EntityManager EntityInfo* getNewInfoAdd(ushort id) { - if (comp_add_info.length < id) + if (comp_add_info.length <= id) { EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)( instance.components.length); @@ -2789,12 +2818,15 @@ export struct EntityManager { ids[len++] = comp; } - else if (id == comp) - return &this; else { ids[len++] = id; ids[len++] = comp; + foreach (comp2; components[len - 1 .. $]) + { + ids[len++] = comp2; + } + break; } } if (id > components[$ - 1]) @@ -2802,7 +2834,7 @@ export struct EntityManager assert(len == components.length + 1); - EntityInfo* new_info = instance.getEntityInfo(ids[0 .. len]); + EntityInfo* new_info = instance.getEntityInfo(ids);//[0 .. len]); comp_add_info[id] = new_info; return new_info; @@ -2810,10 +2842,10 @@ export struct EntityManager EntityInfo* getNewInfoRemove(ushort id) { - if (comp_rem_info.length < id) + if (comp_rem_info.length <= id) { EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)( - instance.components.length); + instance.components.length, &this); if (comp_rem_info !is null) { //new_infos[0 .. comp_rem_info.length] = comp_rem_info[0 .. $];