-added absen components list to system

-added ECS uda attributes
-added InputStruct version switch (gets update() input as structure of arrays)
-initial (WIP) EntitiesData update() input structure compile time parsing
This commit is contained in:
Mergul 2018-09-29 23:10:31 +02:00
parent 8468335b50
commit ed589bbd71
5 changed files with 238 additions and 79 deletions

View file

@ -61,92 +61,120 @@ class EntityManager
System system;
static if (!(hasMember!(Sys, "system_id")) || !is(typeof(Sys.system_id) == ushort))
version (InputStruct)
{
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()()
static if (!(hasMember!(Sys, "EntitiesData")))
{
string ret;
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))
{
uint i = 0;
uint opt = 0;
static foreach (param; (Parameters!(Sys.update))[1 .. $])
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
{
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++;
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++;";
}
}
}
/*foreach (i; 1 .. (Parameters!(Sys.update)).length)
ret ~= "system.m_components = Mallocator.instance.makeArray!ushort(req);";
ret ~= "system.m_optional_components = Mallocator.instance.makeArray!ushort(opt);";
ret ~= "opt = 0;req = 0;absen = 0;";
static foreach (member; __traits(allMembers, Sys.EntitiesData))
{
ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (i - 1)
.to!string ~ "]),";
}*/
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)
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 ~= "opt_ptr" ~ (opt++).to!string ~ ",";
//ret ~= "const string entities_name = \"" ~ member ~ "\";";
}
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++;
{
bool has_att = false;
foreach (att; __traits(getAttributes,
__traits(getMember, Sys.EntitiesData, member)))
{
if (att == "optional")
{
ret ~= "{comp = components_map.get(\"" ~ (typeof(__traits(getMember,
Sys.EntitiesData, member)))
.stringof ~ "\", ushort.max);\n
if(comp == ushort.max)assert(0,\"Can't register system \\\"" ~ Sys.stringof
~ "\\\" due to non existing component " ~ typeof(__traits(getMember,
Sys.EntitiesData, member)).stringof ~ ".\");
system.m_optional_components[opt++] = comp;}";
has_att = true;
break;
}
else if (att == "absen")
{
ret ~= "{comp = components_map.get(\"" ~ (typeof(__traits(getMember,
Sys.EntitiesData, member)))
.stringof ~ "\", ushort.max);\n
if(comp == ushort.max)assert(0,\"Can't register system \\\"" ~ Sys.stringof
~ "\\\" due to non existing component " ~ typeof(__traits(getMember,
Sys.EntitiesData, member)).stringof
~ ".\");system.m_absen_components[absen++] = comp;}";
has_att = true;
break;
}
}
if (!has_att)
{
ret ~= "{comp = components_map.get(\"" ~ (typeof(__traits(getMember,
Sys.EntitiesData, member)))
.stringof ~ "\", ushort.max);\n
if(comp == ushort.max)assert(0,\"Can't register system \\\"" ~ Sys.stringof
~ "\\\" due to non existing component " ~ typeof(__traits(getMember,
Sys.EntitiesData, member)).stringof ~ ".\");
system.m_components[req++] = comp;}";
}
}
}
}
return ret;
}
}
else
{
static string genCompList()()
{
string ret = "ushort comp;uint req;uint opt;";
@ -186,6 +214,92 @@ class EntityManager
}
return ret;
}
}
static if (!(hasMember!(Sys, "system_id")) || !is(typeof(Sys.system_id) == ushort))
{
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;
{
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++;
}
}
}
/*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;
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;
}
static void callUpdate(ref CallData data, void* entity)
{
@ -255,7 +369,12 @@ class EntityManager
system.m_priority = priority;
//system.m_components = Mallocator.instance.makeArray!uint(types.length - 1);
static if (hasMember!(Sys, "update"))
version (InputStruct)
{
mixin(genCompList());
}
else static if (hasMember!(Sys, "update"))
{
mixin(genCompList());
}
@ -452,7 +571,6 @@ class EntityManager
= components[comp].init_data;
}
return temp;
}
@ -505,7 +623,6 @@ class EntityManager
current_delta += entites_in_block * components[id].size;
}
foreach (uint i, ref system; systems)
{
if (system.m_update is null)
@ -644,7 +761,7 @@ class EntityManager
EntitiesBlock* new_block = findBlockWithFreeSpace(new_info);
void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof;
Entity* new_entity = cast(Entity*) start;
new_entity.id = entity.id;
new_entity.updateID();
@ -759,7 +876,7 @@ class EntityManager
//removeEntityNoID(entity, block);
void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof;
Entity* new_entity = cast(Entity*) start;
new_entity.id = entity.id;
new_entity.updateID();
@ -797,7 +914,6 @@ class EntityManager
}
}
new_block.entities_count++;
removeEntityNoID(entity, block);
}
@ -857,7 +973,6 @@ class EntityManager
tmpl.entity_data.ptr + info.tmpl_deltas[comp], components[comp].size);
}
if (!block.added_count)
blocks_to_update.add(block);
@ -960,7 +1075,6 @@ class EntityManager
}
}
if (block.entities_count == 0)
{
if (info.first_block is block)