-removed 'InputStruct' version switch (now it's default behaviour)

-checking if System struct has valid update(EntitiesData) prototype
This commit is contained in:
Mergul 2018-10-01 13:17:31 +02:00
parent d5780a6252
commit 0e13fafefd
3 changed files with 172 additions and 363 deletions

View file

@ -10,9 +10,6 @@
"dflags-posix-ldc": [ "dflags-posix-ldc": [
"-defaultlib=phobos2-ldc,druntime-ldc" "-defaultlib=phobos2-ldc,druntime-ldc"
], ],
"versions": [
"InputStruct"
],
"configurations" : [ "configurations" : [
{ {
"name" : "library", "name" : "library",

View file

@ -66,27 +66,137 @@ class EntityManager
static assert(0, "System should have \"__gshared ushort system_id"); 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 if (is(typeof(__traits(getMember, Sys.EntitiesData,
static foreach (member; __traits(allMembers, 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 else
{ {
@ -97,325 +207,55 @@ class EntityManager
{ {
if (att == "optional") if (att == "optional")
{ {
ret ~= "opt++;"; ret ~= "if(data.system.m_optional_components[" ~ opt.to!string
has_att = true; ~ "] < info.deltas.length && info.deltas[ data.system.m_optional_components["
break; ~ opt.to!string ~ "]] != 0)input_data." ~ member
} ~ " = (cast(ForeachType!(typeof(Sys.EntitiesData." ~ member
else if (att == "absen") ~ "))*)(cast(void*) block + info.deltas[ data.system.m_optional_components["
{
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["
~ opt.to!string ~ "]]))[0 .. block.entities_count]; ~ opt.to!string ~ "]]))[0 .. block.entities_count];
else input_data." ~ member ~ " = null;"; else input_data."
opt++; ~ member ~ " = null;";
has_att = true; opt++;
break; has_att = true;
} break;
else if (att == "absen")
{
absen++;
has_att = true;
break;
}
} }
if (!has_att) else if (att == "absen")
{ {
ret ~= "input_data." ~ member ~ " = (cast(ForeachType!(typeof(Sys.EntitiesData." absen++;
~ member ~ "))*)(cast(void*) block + info.deltas[ data.system.m_components[" has_att = true;
~ req.to!string ~ "]]))[0 .. block.entities_count];"; break;
req++;
} }
} }
} if (!has_att)
}
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)
{ {
mixin(genCall()); 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];";
block = block.next_block; req++;
}
}
}
}
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;*/
} }
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; system.m_update = &callUpdate;
@ -449,16 +289,7 @@ class EntityManager
system.m_system_pointer = cast(void*) Mallocator.instance.make!Sys; system.m_system_pointer = cast(void*) Mallocator.instance.make!Sys;
system.m_priority = priority; system.m_priority = priority;
//system.m_components = Mallocator.instance.makeArray!uint(types.length - 1); mixin(genCompList());
version (InputStruct)
{
mixin(genCompList());
}
else static if (hasMember!(Sys, "update"))
{
mixin(genCompList());
}
ushort sys_id = systems_map.get(Sys.stringof, ushort.max); ushort sys_id = systems_map.get(Sys.stringof, ushort.max);
if (sys_id < systems.length) if (sys_id < systems.length)
@ -487,9 +318,12 @@ class EntityManager
Sys.system_id = cast(ushort)(systems.length - 1); 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);
}
} }
} }

View file

@ -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) /*void handleEvent(Event event, ref TestComp comp)
@ -204,11 +195,6 @@ int main()
{ {
Entity[] entity; Entity[] entity;
TestComp3[] test; TestComp3[] test;
/*void a()
{
}*/
} }
void onEnable() 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) foreach(i;0..data.test.length)
{ {
data.test[i].gg += 14; data.test[i].gg += 14;