-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,92 +61,120 @@ class EntityManager
System system; 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, "EntitiesData")))
}
static if (hasMember!(Sys, "update"))
{
alias types = Parameters!(Sys.update);
alias storages = ParameterStorageClassTuple!(Sys.update);
static string genCall()()
{ {
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; static if (isFunction!(__traits(getMember, Sys.EntitiesData, member)))
uint opt = 0; static assert(0, "EntitiesData can't have any function!");
static foreach (param; (Parameters!(Sys.update))[1 .. $]) 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" bool has_att = false;
~ opt.to!string ~ " = &opt_array" ~ opt.to!string ~ "[i];"; foreach (att; __traits(getAttributes,
opt++; __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) static if (isFunction!(__traits(getMember, Sys.EntitiesData, member)))
.to!string ~ "]),"; static assert(0, "EntitiesData can't have any function!");
}*/ else static if (isArray!(typeof(__traits(getMember,
uint i = 0; Sys.EntitiesData, member))))
uint req = 0; static assert(0, "EntitiesData members should be arrays of elements!");
uint opt = 0; else static if (is(typeof(__traits(getMember,
ret ~= "s.update(id_array[i],"; Sys.EntitiesData, member)) == Entity[]))
static foreach (param; (Parameters!(Sys.update))[1 .. $])
{
i++;
if (isPointer!param)
{ {
ret ~= "opt_ptr" ~ (opt++).to!string ~ ","; //ret ~= "const string entities_name = \"" ~ member ~ "\";";
} }
else else
{ {
ret ~= "array" ~ (req++).to!string ~ "[i],"; {
} bool has_att = false;
} foreach (att; __traits(getAttributes,
__traits(getMember, Sys.EntitiesData, member)))
{
ret ~= ");"; if (att == "optional")
return ret; {
} ret ~= "{comp = components_map.get(\"" ~ (typeof(__traits(getMember,
Sys.EntitiesData, member)))
static string genArrays()() .stringof ~ "\", ushort.max);\n
{ if(comp == ushort.max)assert(0,\"Can't register system \\\"" ~ Sys.stringof
string ret; ~ "\\\" due to non existing component " ~ typeof(__traits(getMember,
Sys.EntitiesData, member)).stringof ~ ".\");
uint i = 0; system.m_optional_components[opt++] = comp;}";
uint req = 0; has_att = true;
uint opt = 0; break;
static foreach (param; (Parameters!(Sys.update))[1 .. $]) }
{ else if (att == "absen")
i++; {
if (isPointer!param) ret ~= "{comp = components_map.get(\"" ~ (typeof(__traits(getMember,
{ Sys.EntitiesData, member)))
ret ~= "PointerTarget!(types[" ~ i.to!string .stringof ~ "\", ushort.max);\n
~ "])[] opt_array" ~ opt.to!string ~ " = null;"; if(comp == ushort.max)assert(0,\"Can't register system \\\"" ~ Sys.stringof
ret ~= "if(info.deltas[types[" ~ i.to!string ~ "].component_id] != 0)opt_array" ~ "\\\" due to non existing component " ~ typeof(__traits(getMember,
~ opt.to!string ~ " Sys.EntitiesData, member)).stringof
= (cast(types[" ~ i.to!string ~ "])(cast(void*)block + info.deltas[types[" ~ ".\");system.m_absen_components[absen++] = comp;}";
~ i.to!string ~ "].component_id]))[0..block.entities_count];"; has_att = true;
ret ~= "types[" ~ i.to!string ~ "] opt_ptr" ~ opt.to!string ~ ";"; break;
opt++; }
} }
else if (!has_att)
{ {
ret ~= "types[" ~ i.to!string ~ "][] array" ~ req.to!string ~ " = (cast(types[" ret ~= "{comp = components_map.get(\"" ~ (typeof(__traits(getMember,
~ i.to!string ~ "]*)(cast(void*)block + info.deltas[types[" Sys.EntitiesData, member)))
~ i.to!string ~ "].component_id]))[0..block.entities_count];"; .stringof ~ "\", ushort.max);\n
req++; 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; return ret;
} }
}
else
{
static string genCompList()() static string genCompList()()
{ {
string ret = "ushort comp;uint req;uint opt;"; string ret = "ushort comp;uint req;uint opt;";
@ -186,6 +214,92 @@ class EntityManager
} }
return ret; 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) static void callUpdate(ref CallData data, void* entity)
{ {
@ -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)
@ -644,7 +761,7 @@ class EntityManager
EntitiesBlock* new_block = findBlockWithFreeSpace(new_info); EntitiesBlock* new_block = findBlockWithFreeSpace(new_info);
void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof; void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof;
Entity* new_entity = cast(Entity*) start; Entity* new_entity = cast(Entity*) start;
new_entity.id = entity.id; new_entity.id = entity.id;
new_entity.updateID(); new_entity.updateID();
@ -759,7 +876,7 @@ class EntityManager
//removeEntityNoID(entity, block); //removeEntityNoID(entity, block);
void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof; void* start = new_block.dataBegin() + new_block.entities_count * EntityID.sizeof;
Entity* new_entity = cast(Entity*) start; Entity* new_entity = cast(Entity*) start;
new_entity.id = entity.id; new_entity.id = entity.id;
new_entity.updateID(); new_entity.updateID();
@ -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)
{ {