-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

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

4
source/ecs/attributes.d Normal file
View file

@ -0,0 +1,4 @@
module ecs.attributes;
enum optional = "optional";
enum absen = "absen";

View file

@ -61,6 +61,161 @@ class EntityManager
System system; System system;
version (InputStruct)
{
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 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++;";
}
}
}
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))
{
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 ~= "{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;";
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, "system_id")) || !is(typeof(Sys.system_id) == ushort)) static if (!(hasMember!(Sys, "system_id")) || !is(typeof(Sys.system_id) == ushort))
{ {
static assert(0, "System should have \"__gshared ushort system_id"); static assert(0, "System should have \"__gshared ushort system_id");
@ -110,7 +265,6 @@ class EntityManager
} }
} }
ret ~= ");"; ret ~= ");";
return ret; return ret;
} }
@ -129,8 +283,8 @@ class EntityManager
{ {
ret ~= "PointerTarget!(types[" ~ i.to!string ret ~= "PointerTarget!(types[" ~ i.to!string
~ "])[] opt_array" ~ opt.to!string ~ " = null;"; ~ "])[] opt_array" ~ opt.to!string ~ " = null;";
ret ~= "if(info.deltas[types[" ~ i.to!string ~ "].component_id] != 0)opt_array" ret ~= "if(info.deltas[types[" ~ i.to!string ~ "].component_id] != 0)opt_array" ~ opt.to!string
~ opt.to!string ~ " ~ "
= (cast(types[" ~ i.to!string ~ "])(cast(void*)block + info.deltas[types[" = (cast(types[" ~ i.to!string ~ "])(cast(void*)block + info.deltas[types["
~ i.to!string ~ "].component_id]))[0..block.entities_count];"; ~ i.to!string ~ "].component_id]))[0..block.entities_count];";
ret ~= "types[" ~ i.to!string ~ "] opt_ptr" ~ opt.to!string ~ ";"; ret ~= "types[" ~ i.to!string ~ "] opt_ptr" ~ opt.to!string ~ ";";
@ -147,46 +301,6 @@ class EntityManager
return 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 void callUpdate(ref CallData data, void* entity)
{ {
static if (hasMember!(Sys, "update")) static if (hasMember!(Sys, "update"))
@ -255,7 +369,12 @@ class EntityManager
system.m_priority = priority; system.m_priority = priority;
//system.m_components = Mallocator.instance.makeArray!uint(types.length - 1); //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()); mixin(genCompList());
} }
@ -452,7 +571,6 @@ class EntityManager
= components[comp].init_data; = components[comp].init_data;
} }
return temp; return temp;
} }
@ -505,7 +623,6 @@ class EntityManager
current_delta += entites_in_block * components[id].size; current_delta += entites_in_block * components[id].size;
} }
foreach (uint i, ref system; systems) foreach (uint i, ref system; systems)
{ {
if (system.m_update is null) if (system.m_update is null)
@ -797,7 +914,6 @@ class EntityManager
} }
} }
new_block.entities_count++; new_block.entities_count++;
removeEntityNoID(entity, block); removeEntityNoID(entity, block);
} }
@ -857,7 +973,6 @@ class EntityManager
tmpl.entity_data.ptr + info.tmpl_deltas[comp], components[comp].size); tmpl.entity_data.ptr + info.tmpl_deltas[comp], components[comp].size);
} }
if (!block.added_count) if (!block.added_count)
blocks_to_update.add(block); blocks_to_update.add(block);
@ -960,7 +1075,6 @@ class EntityManager
} }
} }
if (block.entities_count == 0) if (block.entities_count == 0)
{ {
if (info.first_block is block) if (info.first_block is block)

View file

@ -39,6 +39,7 @@ package:
void* m_system_pointer; void* m_system_pointer;
ushort[] m_components; ushort[] m_components;
ushort[] m_absen_components;
ushort[] m_optional_components; ushort[] m_optional_components;
//void function(ref EntityManager.CallData data, void* entity) update; //void function(ref EntityManager.CallData data, void* entity) update;

View file

@ -4,6 +4,7 @@ import ecs.entity;
import ecs.events; import ecs.events;
import ecs.manager; import ecs.manager;
import ecs.system; import ecs.system;
import ecs.attributes;
import core.time; import core.time;
import std.stdio; import std.stdio;
@ -124,11 +125,12 @@ int main()
} }
struct InputData static struct EntitiesData
{ {
TestComp* test; TestComp* test;
TestComp2* test2; TestComp2* test2;
@("optional") TestComp3* test3; @optional TestComp3* test3;
@absen TestComp4* test4;
} }
void update(ref Entity entity, ref TestComp test, ref TestComp2 test2)//, TestComp3* test3) //ref TestComp comp) void update(ref Entity entity, ref TestComp test, ref TestComp2 test2)//, TestComp3* test3) //ref TestComp comp)
@ -153,6 +155,11 @@ int main()
} }
void update(ref EntitiesData data)
{
}
void handleEvent(TestEvent event, ref TestComp test, ref TestComp2 test2, TestComp3* test3) void handleEvent(TestEvent event, ref TestComp test, ref TestComp2 test2, TestComp3* test3)
{ {
@ -163,6 +170,11 @@ int main()
{ {
__gshared ushort system_id; __gshared ushort system_id;
static struct EntitiesData
{
TestComp* test;
}
void initialize(ref Entity entity, ref TestComp comp) void initialize(ref Entity entity, ref TestComp comp)
{ {
@ -175,6 +187,13 @@ int main()
//writeln("High priority tekst! "); //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)
{ {
@ -185,6 +204,17 @@ int main()
{ {
__gshared ushort system_id; __gshared ushort system_id;
static struct EntitiesData
{
Entity* entity;
TestComp3* test;
/*void a()
{
}*/
}
void onEnable() void onEnable()
{ {
import std.stdio; import std.stdio;
@ -211,6 +241,13 @@ int main()
gEM.sendSelfEvent!(TestEvent)(entity.id, TestEvent()); gEM.sendSelfEvent!(TestEvent)(entity.id, TestEvent());
} }
void update(ref EntitiesData data) //ref TestComp comp)
{
//writeln("TestSystem2 update");
data.test.gg += 14;
gEM.sendSelfEvent!(TestEvent)(data.entity.id, TestEvent());
}
/*void handleEvent(Event event, ref TestComp comp) /*void handleEvent(Event event, ref TestComp comp)
{ {