From e4573f1ec7facdaeea1583a70dd424538356e291 Mon Sep 17 00:00:00 2001 From: Mergul Date: Mon, 1 Oct 2018 17:17:40 +0200 Subject: [PATCH] -better compile time code generation -support for AbsenComponents. Absen components can't exist in entity which are used by system. There are three possibilities to add absen component. Add '@absen' property to EntitiesData mebmer, create AbsenComponents enum with fields names corresponding to components names, or create AbsenComponents AliasSeq with strings expressions corresponding to components names. --- source/ecs/manager.d | 97 ++++++++++++++++++++++++++++++++------------ tests/tests.d | 25 +++++++++++- 2 files changed, 93 insertions(+), 29 deletions(-) diff --git a/source/ecs/manager.d b/source/ecs/manager.d index 11556cd..ffa53f6 100644 --- a/source/ecs/manager.d +++ b/source/ecs/manager.d @@ -73,7 +73,7 @@ class EntityManager static string genCompList()() { - string ret = "ushort comp;uint req;uint opt;uint absen;"; + static foreach (member; __traits(allMembers, Sys.EntitiesData)) { static if (isFunction!(__traits(getMember, Sys.EntitiesData, member))) @@ -86,11 +86,20 @@ class EntityManager 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, + } + + string ret;// = "ushort comp;uint req;uint opt;uint absen;"; + + uint req; + uint opt; + uint absen; + foreach (member; __traits(allMembers, Sys.EntitiesData)) + { + if (member == "length" || is(typeof(__traits(getMember, Sys.EntitiesData, member)) == Entity[]) || is(typeof(__traits(getMember, Sys.EntitiesData, member)) == const(Entity)[])) { - //ret ~= "const string entities_name = \"" ~ member ~ "\";"; + } else { @@ -101,44 +110,72 @@ class EntityManager { if (att == "optional") { - ret ~= "opt++;"; + //ret ~= "opt++;"; + opt++; has_att = true; break; } else if (att == "absen") { - ret ~= "absen++;"; + absen++; + //ret ~= "absen++;"; has_att = true; break; } } - if (!has_att) - ret ~= "req++;"; + if (!has_att)req++; + //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(__traits(hasMember, Sys, "AbsenComponents")) { - static if (is(typeof(__traits(getMember, Sys.EntitiesData, + static if(is(Sys.AbsenComponents == enum)) + { + absen += (Fields!(Sys.AbsenComponents)).length;//static assert(0,"Enum AbsenComponents are not implemented yet."); + } + else static if(__traits(compiles,allSameType!(string,typeof(Sys.AbsenComponents))) && allSameType!(string,typeof(Sys.AbsenComponents)) && + isExpressions!(Sys.AbsenComponents)) + { + absen += Sys.AbsenComponents.length; + } + } + + if(req > 0)ret ~= "system.m_components = Mallocator.instance.makeArray!ushort("~req.to!string~");"; + if(opt > 0)ret ~= "system.m_optional_components = Mallocator.instance.makeArray!ushort("~opt.to!string~");"; + if(absen > 0)ret ~= "system.m_absen_components = Mallocator.instance.makeArray!ushort("~absen.to!string~");"; + ret ~= "ushort comp;";//uint opt = 0;uint req = 0;uint absen = 0;"; + + opt = 0; + req = 0; + absen = 0; + + static if(__traits(hasMember, Sys, "AbsenComponents")) + { + static if(is(Sys.AbsenComponents == enum)) + { + //static assert(0,"Enum AbsenComponents are not implemented yet."); + foreach(str;Fields!(Sys.AbsenComponents))ret ~= "system.m_absen_components["~(absen++).to!string~"] = components_map.get(\""~str.stringof~"\", ushort.max);"; + } + else static if(__traits(compiles,allSameType!(string,typeof(Sys.AbsenComponents))) && allSameType!(string,typeof(Sys.AbsenComponents)) && + isExpressions!(Sys.AbsenComponents)) + { + foreach(str;Sys.AbsenComponents)ret ~= "system.m_absen_components["~(absen++).to!string~"] = components_map.get(\""~str~"\", ushort.max);"; + } + } + + foreach (member; __traits(allMembers, Sys.EntitiesData)) + { + if (member == "length" || 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(member == "length") { } else { { - ret ~= "{comp = components_map.get(Unqual!(ForeachType!(typeof( Sys.EntitiesData." ~ member ~ "))) .stringof, ushort.max);\n @@ -156,20 +193,20 @@ class EntityManager { if (att == "optional") { - ret ~= "system.m_optional_components[opt++] = comp;}"; + ret ~= "system.m_optional_components["~(opt++).to!string~"] = comp;}"; has_att = true; break; } else if (att == "absen") { - ret ~= "system.m_absen_components[absen++] = comp;}"; + ret ~= "system.m_absen_components["~(absen++).to!string~"] = comp;}"; has_att = true; break; } } if (!has_att) { - ret ~= "system.m_components[req++] = comp;}"; + ret ~= "system.m_components["~(req++).to!string~"] = comp;}"; } } } @@ -586,6 +623,17 @@ class EntityManager ushort[] deltas = (cast(ushort*) alloca(num * ushort.sizeof))[0 .. num]; uint delta_id = 0; + if(system.m_absen_components) + { + foreach (id; system.m_absen_components) + { + foreach (id2; entity.components) + { + if(id == id2)return; + } + } + } + foreach (id; system.m_components) { deltas[delta_id] = ushort.max; @@ -618,11 +666,6 @@ class EntityManager break; } } - /*if (deltas[delta_id] == ushort.max) - { - deltas = null; - break; - }*/ delta_id++; } diff --git a/tests/tests.d b/tests/tests.d index 8cdc402..f2f0be0 100644 --- a/tests/tests.d +++ b/tests/tests.d @@ -131,7 +131,7 @@ int main() TestComp[] test; TestComp2[] test2; @optional TestComp3[] test3; - @absen TestComp4[] test4; + //@absen TestComp4[] test4; } void update(ref Entity entity, ref TestComp test, ref TestComp2 test2)//, TestComp3* test3) //ref TestComp comp) @@ -188,15 +188,28 @@ int main() }*/ } +import std.meta; + struct TestSystem2 { __gshared ushort system_id; + enum AbsenComponents0 + { + TestComp, + TestComp4 + } + + alias AbsenComponents = AliasSeq!("TestComp", "TestComp4"); + + string AbsenComponents2; + static struct EntitiesData { short length; Entity[] entity; TestComp3[] test; + //@absen TestComp[] testt; } void onEnable() @@ -225,7 +238,15 @@ int main() data.test[i].gg += 14; gEM.sendSelfEvent!(TestEvent)(data.entity[i].id, TestEvent()); } - + } + + void lateUpdate(ref EntitiesData data) + { + foreach(i;0..data.test.length) + { + data.test[i].gg -= 1; + gEM.sendSelfEvent!(TestEvent)(data.entity[i].id, TestEvent()); + } } /*void handleEvent(Event event, ref TestComp comp)