From 45110e236c2f1d1fef965b06ae05ea415c2e4da0 Mon Sep 17 00:00:00 2001 From: Mergul Date: Thu, 20 Sep 2018 19:12:53 +0200 Subject: [PATCH] -fixed removingComponents issue (object was transferred to another block, but count of entities in block doesn't increase) -functions to get System by ID or ECS System by Type -added system_id to system -fixed issue with registering systems without update() function --- source/ecs/manager.d | 200 ++++++++++++++++++++++++------------------- tests/tests.d | 7 ++ 2 files changed, 118 insertions(+), 89 deletions(-) diff --git a/source/ecs/manager.d b/source/ecs/manager.d index 4c245f6..8477254 100644 --- a/source/ecs/manager.d +++ b/source/ecs/manager.d @@ -57,102 +57,88 @@ class EntityManager void registerSystem(Sys)(int priority) { - alias types = Parameters!(Sys.update); - alias storages = ParameterStorageClassTuple!(Sys.update); - alias STC = ParameterStorageClass; System system; - static string genCall()() + static if (!(hasMember!(Sys, "system_id")) || !is(typeof(Sys.system_id) == ushort)) { - string ret = "s.update(*cast(Entity*)data_pointer,"; - /*foreach (i; 1 .. (Parameters!(Sys.update)).length) - { - ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (i - 1) - .to!string ~ "]),"; - }*/ - uint i = 0; - uint req = 0; - uint opt = 0; - static foreach (param; (Parameters!(Sys.update))[1 .. $]) - { - i++; - if (isPointer!param) - { - ret ~= "cast(types[" ~ i.to!string ~ "])(optional_pointers[" ~ (opt++) - .to!string ~ "]),"; - } - else - { - ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (req++) - .to!string ~ "]),"; - } - } - ret ~= ");"; - return ret; - } - - static string genCompList()() - { - string ret = "ushort comp;uint req;uint opt;"; - foreach (i; 1 .. (Parameters!(Sys.update)).length) - { - ret ~= " - static if(isPointer!(types[" ~ i.to!string - ~ "]))opt++; - else static if(storages[" ~ i.to!string ~ "] == STC.ref_)req++;\n - else static assert(0,\"Can't register system \\\"" ~ Sys.stringof - ~ "\\\". Unsupported parameter type \\\"\"~types[" - ~ i.to!string ~ "].stringof~\"\\\".\");"; - } - ret ~= "system.m_components = Mallocator.instance.makeArray!ushort(req);"; - ret ~= "system.m_optional_components = Mallocator.instance.makeArray!ushort(opt);"; - ret ~= "opt = 0;req = 0;"; - foreach (i; 1 .. (Parameters!(Sys.update)).length) - { - ret ~= " - static if(isPointer!(types[" ~ i.to!string - ~ "])) - { - comp = components_map.get(PointerTarget!(types[" ~ i.to!string ~ "]).stringof, ushort.max);\n - if(comp == ushort.max)assert(0,\"Can't register system \\\"" ~ Sys.stringof - ~ "\\\" due to non existing component \\\"\"~types[" ~ i.to!string ~ "].stringof~\"\\\".\"); - system.m_optional_components[opt++] = comp; - } - else static if(storages[" - ~ i.to!string ~ "] == STC.ref_) - { - comp = components_map.get(types[" ~ i.to!string ~ "].stringof, ushort.max);\n - if(comp == ushort.max)assert(0,\"Can't register system \\\"" - ~ Sys.stringof ~ "\\\" due to non existing component \\\"\"~types[" - ~ i.to!string ~ "].stringof~\"\\\".\"); - system.m_components[req++] = comp; - }"; - } - return ret; - } - - static string catchFunc()(string member, string func) - { - string ret = "static if (hasMember!(Sys, \"" ~ func ~ "\")) - { - static void call" ~ func - ~ "(void* system_pointer) - { - - Sys* s = cast(Sys*) system_pointer; - s." ~ func ~ "(); - } - - system." - ~ member ~ " = &call" ~ func ~ "; - }"; - return ret; + static assert(0, "System should have \"__gshared ushort system_id"); } static if (hasMember!(Sys, "update")) { + alias types = Parameters!(Sys.update); + alias storages = ParameterStorageClassTuple!(Sys.update); + static string genCall()() + { + string ret = "s.update(*cast(Entity*)data_pointer,"; + /*foreach (i; 1 .. (Parameters!(Sys.update)).length) + { + ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (i - 1) + .to!string ~ "]),"; + }*/ + uint i = 0; + uint req = 0; + uint opt = 0; + static foreach (param; (Parameters!(Sys.update))[1 .. $]) + { + i++; + if (isPointer!param) + { + ret ~= "cast(types[" ~ i.to!string ~ "])(optional_pointers[" ~ (opt++) + .to!string ~ "]),"; + } + else + { + ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (req++) + .to!string ~ "]),"; + } + } + ret ~= ");"; + return ret; + } + + static string genCompList()() + { + string ret = "ushort comp;uint req;uint opt;"; + foreach (i; 1 .. (Parameters!(Sys.update)).length) + { + ret ~= " + static if(isPointer!(types[" ~ i.to!string + ~ "]))opt++; + else static if(storages[" ~ i.to!string ~ "] == STC.ref_)req++;\n + else static assert(0,\"Can't register system \\\"" ~ Sys.stringof + ~ "\\\". Unsupported parameter type \\\"\"~types[" + ~ i.to!string ~ "].stringof~\"\\\".\");"; + } + ret ~= "system.m_components = Mallocator.instance.makeArray!ushort(req);"; + ret ~= "system.m_optional_components = Mallocator.instance.makeArray!ushort(opt);"; + ret ~= "opt = 0;req = 0;"; + foreach (i; 1 .. (Parameters!(Sys.update)).length) + { + ret ~= " + static if(isPointer!(types[" ~ i.to!string + ~ "])) + { + comp = components_map.get(PointerTarget!(types[" ~ i.to!string ~ "]).stringof, ushort.max);\n + if(comp == ushort.max)assert(0,\"Can't register system \\\"" ~ Sys.stringof + ~ "\\\" due to non existing component \\\"\"~types[" ~ i.to!string ~ "].stringof~\"\\\".\"); + system.m_optional_components[opt++] = comp; + } + else static if(storages[" + ~ i.to!string ~ "] == STC.ref_) + { + comp = components_map.get(types[" ~ i.to!string ~ "].stringof, ushort.max);\n + if(comp == ushort.max)assert(0,\"Can't register system \\\"" + ~ Sys.stringof ~ "\\\" due to non existing component \\\"\"~types[" + ~ i.to!string ~ "].stringof~\"\\\".\"); + system.m_components[req++] = comp; + }"; + } + return ret; + } + static void callUpdate(ref CallData data, void* entity) { static if (hasMember!(Sys, "update")) @@ -201,6 +187,24 @@ class EntityManager system.m_update = &callUpdate; } + static string catchFunc()(string member, string func) + { + string ret = "static if (hasMember!(Sys, \"" ~ func ~ "\")) + { + static void call" ~ func + ~ "(void* system_pointer) + { + + Sys* s = cast(Sys*) system_pointer; + s." ~ func ~ "(); + } + + system." + ~ member ~ " = &call" ~ func ~ "; + }"; + return ret; + } + mixin(catchFunc("m_enable", "onEnable")); mixin(catchFunc("m_disable", "onDisable")); mixin(catchFunc("m_create", "onCreate")); @@ -212,13 +216,17 @@ class EntityManager system.m_priority = priority; //system.m_components = Mallocator.instance.makeArray!uint(types.length - 1); - mixin(genCompList()); - + static if (hasMember!(Sys, "update")) + { + mixin(genCompList()); + } + ushort sys_id = systems_map.get(Sys.stringof, ushort.max); if (sys_id < systems.length) { system.enable(); systems[sys_id] = system; + Sys.system_id = sys_id; } else { @@ -231,6 +239,8 @@ class EntityManager systems[$ - 1].enable(); + Sys.system_id = cast(ushort)(systems.length - 1); + foreach (info; &entities_infos.byValue) { addEntityCaller(*info, cast(uint) systems.length - 1); @@ -240,6 +250,16 @@ class EntityManager updateEntityCallers(); } + System* getSystem(ushort id) + { + return &systems[id]; + } + + Sys* getSystem(Sys)() + { + return cast(Sys*)systems[Sys.system_id].system_pointer; + } + void registerComponent(Comp)() { ComponentInfo info; @@ -538,6 +558,8 @@ class EntityManager cast(void*) entity + info.deltas[comp], components[comp].size); } + new_block.entities_count++; + removeEntityNoID(entity, block); } diff --git a/tests/tests.d b/tests/tests.d index 3d755be..8c778d7 100644 --- a/tests/tests.d +++ b/tests/tests.d @@ -119,6 +119,13 @@ int main() } + struct InputData + { + TestComp* test; + TestComp2* test2; + @("optional") TestComp3* test3; + } + void update(ref Entity entity, ref TestComp test, ref TestComp2 test2, TestComp3* test3) //ref TestComp comp) { assert(cast(size_t)&test % TestComp.alignof == 0);