From cb9eaad123d4c79b6e401220f24142763d412144 Mon Sep 17 00:00:00 2001 From: Mergul Date: Sat, 18 Apr 2020 19:16:45 +0200 Subject: [PATCH] More tests: -removed some unused code -fixed bug with struct destructors (Mallocator called __dtor instead of __xdtor) -added unittests for events -addded _d_eh_personality null implementation as LDC betterC bug workaround --- source/ecs/events.d | 16 +---- source/ecs/manager.d | 5 +- source/ecs/std.d | 6 +- tests/basic.d | 141 ++++++++++++++++++++++++++++++++++++++++++- tests/runner.d | 11 ++++ 5 files changed, 160 insertions(+), 19 deletions(-) diff --git a/source/ecs/events.d b/source/ecs/events.d index 7186d13..317b2f0 100644 --- a/source/ecs/events.d +++ b/source/ecs/events.d @@ -95,7 +95,7 @@ package struct EventManager void clearEvents() nothrow @nogc { - uint threads_count = cast(uint)manager.threads.length; + //uint threads_count = cast(uint)manager.threads.length; foreach(ref event;events) { foreach(ref first_block; event.first_blocks) @@ -133,23 +133,11 @@ package struct EventManager private void disposeData() nothrow @nogc { + clearEvents(); 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.dispose(block); - block = next_block; - if(block)next_block = block.next; - } - } - Mallocator.dispose(event.blocks); Mallocator.dispose(event.first_blocks); } diff --git a/source/ecs/manager.d b/source/ecs/manager.d index c3c615c..49662dc 100644 --- a/source/ecs/manager.d +++ b/source/ecs/manager.d @@ -3138,12 +3138,13 @@ export struct EntityManager struct EntitiesBlock { ///return distance (in bytes) from begin of block to data - export uint dataDelta() nothrow @nogc pure + ///TODO: probably to remove. It's used by old code if I remeber correctly. + /*export uint dataDelta() nothrow @nogc pure { ushort dif = EntitiesBlock.sizeof; alignNum(dif, type_info.alignment); return dif; - } + }*/ ///return pointer to first element in block export void* dataBegin() nothrow @nogc pure diff --git a/source/ecs/std.d b/source/ecs/std.d index a3a4f5e..6077ede 100644 --- a/source/ecs/std.d +++ b/source/ecs/std.d @@ -187,13 +187,15 @@ static struct Mallocator static void dispose(T)(T object) nothrow @nogc { - static if(__traits(hasMember, T, "__dtor"))object.__dtor(); + static if(__traits(hasMember, T, "__xdtor"))object.__xdtor(); + else static if(__traits(hasMember, T, "__dtor"))object.__dtor(); free(cast(void*)object); } static void alignDispose(T)(T object) { - static if(__traits(hasMember, T, "__dtor"))object.__dtor(); + static if(__traits(hasMember, T, "__xdtor"))object.__xdtor(); + else static if(__traits(hasMember, T, "__dtor"))object.__dtor(); version(Posix)free(cast(void*)object); else version(Windows)_aligned_free(cast(void*)object); else version(ECSEmscripten)free(cast(void*)object); diff --git a/tests/basic.d b/tests/basic.d index f0ab2ef..38b5605 100644 --- a/tests/basic.d +++ b/tests/basic.d @@ -311,7 +311,7 @@ unittest void onDestroy() { - (*destroy)++; + if(destroy)(*destroy)++; } void onEnable() @@ -456,6 +456,7 @@ unittest gEM.end(); assert(system.end == 4); ecs_system.enable(); + system.destroy = null; } @("CustomPass") @@ -852,4 +853,142 @@ unittest gEM.commit(); entity = gEM.getEntity(id); assert(entity is null); +} + +@("EventCallbacks") +unittest +{ + struct ETest + { + mixin ECS.Event; + } + + struct ETest2 + { + mixin ECS.Event; + int super_liczba = 0; + } + + struct TestSystem + { + mixin ECS.System; + + struct EntitiesData + { + int length; + Entity[] entity; + @readonly CLong[] long_; + @optional CInt[] int_; + } + + void onUpdate(EntitiesData data) + { + + } + + void handleEvent(Entity* entity, ETest event) + { + CLong* long_ = entity.getComponent!CLong; + CInt* int_ = entity.getComponent!CInt; + *long_ += 16; + if(int_)*int_ += 6; + } + + void handleEvent(Entity* entity, ETest2 event) + { + CLong* long_ = entity.getComponent!CLong; + CInt* int_ = entity.getComponent!CInt; + *long_ += event.super_liczba * 2; + if(int_)*int_ += event.super_liczba * 4; + } + } + + struct TestSystem2 + { + mixin ECS.System; + + struct EntitiesData + { + int length; + Entity[] entity; + CShort[] short_; + @optional CInt[] int_; + } + + void handleEvent(Entity* entity, ETest event) + { + CShort* short_ = entity.getComponent!CShort; + CInt* int_ = entity.getComponent!CInt; + *short_ += 8; + if(int_)*int_ += 2; + } + + void handleEvent(Entity* entity, ETest2 event) + { + CShort* short_ = entity.getComponent!CShort; + CInt* int_ = entity.getComponent!CInt; + *short_ += event.super_liczba; + if(int_)*int_ *= event.super_liczba; + } + } + + gEM.beginRegister(); + + gEM.registerEvent!ETest; + gEM.registerEvent!ETest2; + + gEM.registerSystem!TestSystem2(1); + gEM.registerSystem!TestSystem(0); + + gEM.endRegister(); + + ushort[1] ids = [CLong.component_id]; + EntityTemplate* tmpl = gEM.allocateTemplate(ids); + scope (exit) gEM.freeTemplate(tmpl); + ushort[1] ids2 = [CShort.component_id]; + EntityTemplate* tmpl2 = gEM.allocateTemplate(ids2); + scope (exit) gEM.freeTemplate(tmpl2); + + Entity* entity = gEM.addEntity(tmpl); + EntityID id = entity.id; + assert(*entity.getComponent!CLong == 10); + Entity* entity2 = gEM.addEntity(tmpl2); + EntityID id2 = entity2.id; + assert(*entity2.getComponent!CShort == 12); + + gEM.sendEvent(id,ETest()); + gEM.sendEvent(id,ETest2(id,10)); + gEM.sendEvent(id2,ETest()); + gEM.sendEvent(id2,ETest2(id2,12)); + gEM.commit(); + + entity = gEM.getEntity(id); + entity2 = gEM.getEntity(id2); + assert(*entity.getComponent!CLong == 46); + assert(*entity2.getComponent!CShort == 32); + + gEM.addComponents(id, CInt(2), CShort(1)); + gEM.sendEvent(id,ETest()); + gEM.sendEvent(id,ETest2(id,2)); + gEM.commit(); + + entity = gEM.getEntity(id); + assert(*entity.getComponent!CLong == 66); + assert(*entity.getComponent!CInt == 36); + + //test for multiple event blocks + long result = *entity.getComponent!CLong; + foreach(i;0..10000) + { + gEM.sendEvent(id,ETest()); + gEM.sendEvent(id,ETest2(id,4)); + result += 16; + result += 8; + } + gEM.commit(); + entity = gEM.getEntity(id); + assert(*entity.getComponent!CLong == result); + + //cover funcion to clearEvents before destroying manager + gEM.sendEvent(id,ETest()); } \ No newline at end of file diff --git a/tests/runner.d b/tests/runner.d index 9f219bd..5eaf99b 100644 --- a/tests/runner.d +++ b/tests/runner.d @@ -385,3 +385,14 @@ extern (C) int main(int argc, char** args) else return 1; } + +version (D_BetterC) +{ + version(LDC) + { + extern (C) __gshared int _d_eh_personality(int, int, size_t, void*, void*) + { + return 0; + } + } +} \ No newline at end of file