diff --git a/dub.json b/dub.json index 6705634..bacb5fc 100755 --- a/dub.json +++ b/dub.json @@ -10,9 +10,6 @@ "dflags-posix-ldc": [ "-defaultlib=phobos2-ldc,druntime-ldc" ], - "versions": [ - "InputStruct" - ], "configurations" : [ { "name" : "library", diff --git a/source/ecs/manager.d b/source/ecs/manager.d index 5749319..9dc7eff 100644 --- a/source/ecs/manager.d +++ b/source/ecs/manager.d @@ -66,27 +66,137 @@ class EntityManager static assert(0, "System should have \"__gshared ushort system_id"); } - version (InputStruct) + static if (!(hasMember!(Sys, "EntitiesData"))) { - static if (!(hasMember!(Sys, "EntitiesData"))) + static assert(0, "System should gave \"EntitiesData\" struct for input components"); + } + + static string genCompList()() + { + string ret = "ushort comp;uint req;uint opt;uint absen;"; + static foreach (member; __traits(allMembers, Sys.EntitiesData)) { - static assert(0, "System should gave \"EntitiesData\" struct for input components"); + static if (isFunction!(__traits(getMember, Sys.EntitiesData, member))) + static assert(0, "EntitiesData can't have any function!"); + else static if (!(isArray!(typeof(__traits(getMember, + Sys.EntitiesData, member))))) + static assert(0, "EntitiesData members should be arrays of elements!"); + else static if (is(typeof(__traits(getMember, Sys.EntitiesData, + member)) == Entity[])) + { + //ret ~= "const string entities_name = \"" ~ member ~ "\";"; + } + else + { + { + bool has_att = false; + foreach (att; __traits(getAttributes, + __traits(getMember, Sys.EntitiesData, member))) + { + if (att == "optional") + { + ret ~= "opt++;"; + has_att = true; + break; + } + else if (att == "absen") + { + ret ~= "absen++;"; + has_att = true; + break; + } + } + if (!has_att) + ret ~= "req++;"; + } + } } - static string genCompList()() + ret ~= "system.m_components = Mallocator.instance.makeArray!ushort(req);"; + ret ~= "system.m_optional_components = Mallocator.instance.makeArray!ushort(opt);"; + ret ~= "system.m_absen_components = Mallocator.instance.makeArray!ushort(absen);"; + ret ~= "opt = 0;req = 0;absen = 0;"; + + static foreach (member; __traits(allMembers, Sys.EntitiesData)) { - string ret = "ushort comp;uint req;uint opt;uint absen;"; - static foreach (member; __traits(allMembers, Sys.EntitiesData)) + static if (is(typeof(__traits(getMember, Sys.EntitiesData, + member)) == Entity[]) || is(typeof(__traits(getMember, + Sys.EntitiesData, member)) == const(Entity)[])) + { + //ret ~= "const string entities_name = \"" ~ member ~ "\";"; + } + else { - static if (isFunction!(__traits(getMember, Sys.EntitiesData, member))) - static assert(0, "EntitiesData can't have any function!"); - else static if (!(isArray!(typeof(__traits(getMember, - Sys.EntitiesData, member))))) - static assert(0, "EntitiesData members should be arrays of elements!"); - else static if (is(typeof(__traits(getMember, - Sys.EntitiesData, member)) == Entity[])) { - //ret ~= "const string entities_name = \"" ~ member ~ "\";"; + + ret ~= "{comp = components_map.get(Unqual!(ForeachType!(typeof( + Sys.EntitiesData." ~ member ~ "))) + .stringof, ushort.max);\n + if(comp == ushort.max)assert(0,\"Can't register system \\\"" + ~ Sys.stringof + ~ "\\\" due to non existing component \" ~ ForeachType!(typeof( + Sys.EntitiesData." + ~ member ~ ")) + .stringof + ~ \".\");"; + + bool has_att = false; + foreach (att; __traits(getAttributes, + __traits(getMember, Sys.EntitiesData, member))) + { + if (att == "optional") + { + ret ~= "system.m_optional_components[opt++] = comp;}"; + has_att = true; + break; + } + else if (att == "absen") + { + ret ~= "system.m_absen_components[absen++] = comp;}"; + has_att = true; + break; + } + } + if (!has_att) + { + ret ~= "system.m_components[req++] = comp;}"; + } + } + } + } + return ret; + } + + string genParamsChecking()() + { + string ret; + foreach (func; __traits(getOverloads, Sys, "update")) + { + if ((Parameters!(func)).length == 1) + ret ~= "\"" ~ (fullyQualifiedName!(Sys.EntitiesData)) ~ "\" == \"" ~ ( + fullyQualifiedName!((Parameters!(func))[0])) ~ "\" || "; + } + ret ~= "false"; + return ret; + } + + static if (hasMember!(Sys, "update") && (mixin(genParamsChecking()))) + { + static string genFillInputData()() + { + string ret; + ushort comp; + uint req = 0; + uint opt = 0; + uint absen = 0; + foreach (member; __traits(allMembers, Sys.EntitiesData)) + { + if (is(typeof(__traits(getMember, Sys.EntitiesData, + member)) == Entity[]) || is(typeof(__traits(getMember, + Sys.EntitiesData, member)) == const(Entity)[])) + { + ret ~= "input_data." ~ member + ~ " = (cast(Entity*) block.dataBegin())[0 .. block.entities_count];"; } else { @@ -97,325 +207,55 @@ class EntityManager { if (att == "optional") { - ret ~= "opt++;"; - has_att = true; - break; - } - else if (att == "absen") - { - ret ~= "absen++;"; - has_att = true; - break; - } - } - if (!has_att) - ret ~= "req++;"; - } - } - } - - ret ~= "system.m_components = Mallocator.instance.makeArray!ushort(req);"; - ret ~= "system.m_optional_components = Mallocator.instance.makeArray!ushort(opt);"; - ret ~= "system.m_absen_components = Mallocator.instance.makeArray!ushort(absen);"; - ret ~= "opt = 0;req = 0;absen = 0;"; - - static foreach (member; __traits(allMembers, Sys.EntitiesData)) - { - static if (is(typeof(__traits(getMember, Sys.EntitiesData, member)) == Entity[]) - || is(typeof(__traits(getMember, Sys.EntitiesData, member)) == const(Entity)[])) - { - //ret ~= "const string entities_name = \"" ~ member ~ "\";"; - } - else - { - { - - ret ~= "{comp = components_map.get(Unqual!(ForeachType!(typeof( - Sys.EntitiesData." - ~ member ~ "))) - .stringof, ushort.max);\n - if(comp == ushort.max)assert(0,\"Can't register system \\\"" ~ Sys.stringof - ~ "\\\" due to non existing component \" ~ ForeachType!(typeof( - Sys.EntitiesData." - ~ member ~ ")) - .stringof - ~ \".\");"; - - bool has_att = false; - foreach (att; __traits(getAttributes, - __traits(getMember, Sys.EntitiesData, member))) - { - if (att == "optional") - { - ret ~= "system.m_optional_components[opt++] = comp;}"; - has_att = true; - break; - } - else if (att == "absen") - { - ret ~= "system.m_absen_components[absen++] = comp;}"; - has_att = true; - break; - } - } - if (!has_att) - { - ret ~= "system.m_components[req++] = comp;}"; - } - } - } - } - return ret; - } - } - else - { - 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 if (hasMember!(Sys, "update")) - { - alias types = Parameters!(Sys.update); - alias storages = ParameterStorageClassTuple!(Sys.update); - static string genCall()() - { - string ret; - { - uint i = 0; - uint opt = 0; - static foreach (param; (Parameters!(Sys.update))[1 .. $]) - { - i++; - if (isPointer!param) - { - ret ~= "if(opt_array" ~ opt.to!string ~ " !is null)opt_ptr" - ~ opt.to!string ~ " = &opt_array" ~ opt.to!string ~ "[i];"; - opt++; - } - } - } - - uint i = 0; - uint req = 0; - uint opt = 0; - ret ~= "s.update(id_array[i],"; - static foreach (param; (Parameters!(Sys.update))[1 .. $]) - { - i++; - if (isPointer!param) - { - ret ~= "opt_ptr" ~ (opt++).to!string ~ ","; - } - else - { - ret ~= "array" ~ (req++).to!string ~ "[i],"; - } - } - - ret ~= ");"; - return ret; - } - - static string genArrays()() - { - string ret; - - uint i = 0; - uint req = 0; - uint opt = 0; - static foreach (param; (Parameters!(Sys.update))[1 .. $]) - { - i++; - if (isPointer!param) - { - ret ~= "PointerTarget!(types[" ~ i.to!string - ~ "])[] opt_array" ~ opt.to!string ~ " = null;"; - ret ~= "if(info.deltas[types[" ~ i.to!string ~ "].component_id] != 0)opt_array" ~ opt.to!string - ~ " - = (cast(types[" ~ i.to!string ~ "])(cast(void*)block + info.deltas[types[" - ~ i.to!string ~ "].component_id]))[0..block.entities_count];"; - ret ~= "types[" ~ i.to!string ~ "] opt_ptr" ~ opt.to!string ~ ";"; - opt++; - } - else - { - ret ~= "types[" ~ i.to!string ~ "][] array" ~ req.to!string ~ " = (cast(types[" - ~ i.to!string ~ "]*)(cast(void*)block + info.deltas[types[" - ~ i.to!string ~ "].component_id]))[0..block.entities_count];"; - req++; - } - } - return ret; - } - - version (InputStruct) - { - - static string genFillInputData()() - { - string ret; - ushort comp; - uint req = 0; - uint opt = 0; - uint absen = 0; - foreach (member; __traits(allMembers, Sys.EntitiesData)) - { - if (is(typeof(__traits(getMember, Sys.EntitiesData, member)) == Entity[]) - || is(typeof(__traits(getMember, Sys.EntitiesData, member)) == const(Entity)[])) - { - ret ~= "input_data." ~ member - ~ " = (cast(Entity*) block.dataBegin())[0 .. block.entities_count];"; - } - else - { - { - bool has_att = false; - foreach (att; __traits(getAttributes, - __traits(getMember, Sys.EntitiesData, member))) - { - if (att == "optional") - { - ret ~= "if(data.system.m_optional_components[" - ~ opt.to!string ~ "] < info.deltas.length && info.deltas[ data.system.m_optional_components[" - ~ opt.to!string ~ "]] != 0)input_data." ~ member ~ " = (cast(ForeachType!(typeof(Sys.EntitiesData." - ~ member ~ "))*)(cast(void*) block + info.deltas[ data.system.m_optional_components[" + ret ~= "if(data.system.m_optional_components[" ~ opt.to!string + ~ "] < info.deltas.length && info.deltas[ data.system.m_optional_components[" + ~ opt.to!string ~ "]] != 0)input_data." ~ member + ~ " = (cast(ForeachType!(typeof(Sys.EntitiesData." ~ member + ~ "))*)(cast(void*) block + info.deltas[ data.system.m_optional_components[" ~ opt.to!string ~ "]]))[0 .. block.entities_count]; - else input_data." ~ member ~ " = null;"; - opt++; - has_att = true; - break; - } - else if (att == "absen") - { - absen++; - has_att = true; - break; - } + else input_data." + ~ member ~ " = null;"; + opt++; + has_att = true; + break; } - if (!has_att) + else if (att == "absen") { - ret ~= "input_data." ~ member ~ " = (cast(ForeachType!(typeof(Sys.EntitiesData." - ~ member ~ "))*)(cast(void*) block + info.deltas[ data.system.m_components[" - ~ req.to!string ~ "]]))[0 .. block.entities_count];"; - req++; + absen++; + has_att = true; + break; } } - } - } - return ret; - } - - static void callUpdate(ref CallData data, void* entity) - { - static if (hasMember!(Sys, "update")) - { - Sys* s = cast(Sys*) data.system.m_system_pointer; - - /*void*[] pointers = (cast(void**) alloca(data.system.m_components.length * (void*) - .sizeof))[0 .. data.system.m_components.length]; - void*[] optional_pointers = (cast(void**) alloca( - data.system.m_optional_components.length * (void*).sizeof))[0 - .. data.system.m_optional_components.length];*/ - - Sys.EntitiesData input_data; - - EntitiesBlock* block = data.info.first_block; - while (block !is null) - { - EntityInfo* info = block.type_info; - /*Entity[] id_array = (cast(Entity*) block.dataBegin())[0 - .. block.entities_count];*/ - //mixin(genArrays()); - - mixin(genFillInputData()); - - s.update(input_data); - /*foreach (i; 0 .. block.entities_count) + if (!has_att) { - mixin(genCall()); - }*/ - - block = block.next_block; - } - - } - } - } - else - { - static void callUpdate(ref CallData data, void* entity) - { - static if (hasMember!(Sys, "update")) - { - Sys* s = cast(Sys*) data.system.m_system_pointer; - - void*[] pointers = (cast(void**) alloca(data.system.m_components.length * (void*) - .sizeof))[0 .. data.system.m_components.length]; - void*[] optional_pointers = (cast(void**) alloca( - data.system.m_optional_components.length * (void*).sizeof))[0 - .. data.system.m_optional_components.length]; - - EntitiesBlock* block = data.info.first_block; - while (block !is null) - { - EntityInfo* info = block.type_info; - Entity[] id_array = (cast(Entity*) block.dataBegin())[0 - .. block.entities_count]; - mixin(genArrays()); - foreach (i; 0 .. block.entities_count) - { - mixin(genCall()); - //data_pointer += EntityID.sizeof; //data.info.size; - /*foreach (ref pointer; pointers) - pointer += size; - foreach (ref pointer; optional_pointers) - if (pointer != null) - pointer += size;*/ + ret ~= "input_data." ~ member ~ " = (cast(ForeachType!(typeof(Sys.EntitiesData." ~ member + ~ "))*)(cast(void*) block + info.deltas[ data.system.m_components[" + ~ req.to!string ~ "]]))[0 .. block.entities_count];"; + req++; } - - block = block.next_block; } - } } + return ret; + } + + static void callUpdate(ref CallData data, void* entity) + { + Sys* s = cast(Sys*) data.system.m_system_pointer; + + Sys.EntitiesData input_data; + + EntitiesBlock* block = data.info.first_block; + while (block !is null) + { + EntityInfo* info = block.type_info; + + mixin(genFillInputData()); + + s.update(input_data); + + block = block.next_block; + } } system.m_update = &callUpdate; @@ -449,16 +289,7 @@ class EntityManager system.m_system_pointer = cast(void*) Mallocator.instance.make!Sys; system.m_priority = priority; - //system.m_components = Mallocator.instance.makeArray!uint(types.length - 1); - - version (InputStruct) - { - mixin(genCompList()); - } - else static if (hasMember!(Sys, "update")) - { - mixin(genCompList()); - } + mixin(genCompList()); ushort sys_id = systems_map.get(Sys.stringof, ushort.max); if (sys_id < systems.length) @@ -487,9 +318,12 @@ class EntityManager Sys.system_id = cast(ushort)(systems.length - 1); - foreach (info; &entities_infos.byValue) + if (system.m_update !is null) { - addEntityCaller(*info, cast(uint) systems.length - 1); + foreach (info; &entities_infos.byValue) + { + addEntityCaller(*info, cast(uint) systems.length - 1); + } } } diff --git a/tests/tests.d b/tests/tests.d index 3e9eee3..6947b29 100644 --- a/tests/tests.d +++ b/tests/tests.d @@ -176,18 +176,9 @@ int main() } - void update(ref Entity entity, ref TestComp test) //ref TestComp comp) + void update(ref EntitiesData data) { - assert(cast(size_t)&test % TestComp.alignof == 0); - - //writeln("High priority tekst! "); - } - - void update(ref EntitiesData data) //ref TestComp comp) - { - assert(cast(size_t)&data.test % TestComp.alignof == 0); - - //writeln("High priority tekst! "); + } /*void handleEvent(Event event, ref TestComp comp) @@ -204,11 +195,6 @@ int main() { Entity[] entity; TestComp3[] test; - - /*void a() - { - - }*/ } void onEnable() @@ -230,16 +216,8 @@ int main() } - void update(ref Entity entity, ref TestComp3 test) //ref TestComp comp) + void update(ref EntitiesData data) { - //writeln("TestSystem2 update"); - test.gg += 14; - gEM.sendSelfEvent!(TestEvent)(entity.id, TestEvent()); - } - - void update(ref EntitiesData data) //ref TestComp comp) - { - //writeln("TestSystem2 update"); foreach(i;0..data.test.length) { data.test[i].gg += 14;