-working update() with EntitiesData structure input

-added support for 'const' components input (read only, future usage)
This commit is contained in:
Mergul 2018-09-30 23:12:20 +02:00
parent ed589bbd71
commit d5780a6252
3 changed files with 167 additions and 86 deletions

View file

@ -17,7 +17,7 @@ struct Entity
EntityManager.instance.id_manager.update(this); EntityManager.instance.id_manager.update(this);
} }
T* getComponent(T)() T* getComponent(T)() const
{ {
EntityManager.EntitiesBlock* block = gEM.getMetaData(&this); EntityManager.EntitiesBlock* block = gEM.getMetaData(&this);
EntityManager.EntityInfo* info = block.type_info; EntityManager.EntityInfo* info = block.type_info;

View file

@ -61,6 +61,11 @@ class EntityManager
System system; System system;
static if (!(hasMember!(Sys, "system_id")) || !is(typeof(Sys.system_id) == ushort))
{
static assert(0, "System should have \"__gshared ushort system_id");
}
version (InputStruct) version (InputStruct)
{ {
static if (!(hasMember!(Sys, "EntitiesData"))) static if (!(hasMember!(Sys, "EntitiesData")))
@ -75,13 +80,13 @@ class EntityManager
{ {
static if (isFunction!(__traits(getMember, Sys.EntitiesData, member))) static if (isFunction!(__traits(getMember, Sys.EntitiesData, member)))
static assert(0, "EntitiesData can't have any function!"); static assert(0, "EntitiesData can't have any function!");
else static if (isArray!(typeof(__traits(getMember, else static if (!(isArray!(typeof(__traits(getMember,
Sys.EntitiesData, member)))) Sys.EntitiesData, member)))))
static assert(0, "EntitiesData members should be arrays of elements!"); static assert(0, "EntitiesData members should be arrays of elements!");
else static if (is(typeof(__traits(getMember, else static if (is(typeof(__traits(getMember,
Sys.EntitiesData, member)) == Entity[])) Sys.EntitiesData, member)) == Entity[]))
{ {
ret ~= "const string entities_name = \"" ~ member ~ "\";"; //ret ~= "const string entities_name = \"" ~ member ~ "\";";
} }
else else
{ {
@ -111,61 +116,51 @@ class EntityManager
ret ~= "system.m_components = Mallocator.instance.makeArray!ushort(req);"; ret ~= "system.m_components = Mallocator.instance.makeArray!ushort(req);";
ret ~= "system.m_optional_components = Mallocator.instance.makeArray!ushort(opt);"; 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;"; ret ~= "opt = 0;req = 0;absen = 0;";
static foreach (member; __traits(allMembers, Sys.EntitiesData)) static foreach (member; __traits(allMembers, Sys.EntitiesData))
{ {
static if (isFunction!(__traits(getMember, Sys.EntitiesData, member))) static if (is(typeof(__traits(getMember, Sys.EntitiesData, member)) == Entity[])
static assert(0, "EntitiesData can't have any function!"); || is(typeof(__traits(getMember, Sys.EntitiesData, member)) == const(Entity)[]))
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 ~= "const string entities_name = \"" ~ member ~ "\";";
} }
else 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; bool has_att = false;
foreach (att; __traits(getAttributes, foreach (att; __traits(getAttributes,
__traits(getMember, Sys.EntitiesData, member))) __traits(getMember, Sys.EntitiesData, member)))
{ {
if (att == "optional") if (att == "optional")
{ {
ret ~= "{comp = components_map.get(\"" ~ (typeof(__traits(getMember, ret ~= "system.m_optional_components[opt++] = comp;}";
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; has_att = true;
break; break;
} }
else if (att == "absen") else if (att == "absen")
{ {
ret ~= "{comp = components_map.get(\"" ~ (typeof(__traits(getMember, ret ~= "system.m_absen_components[absen++] = comp;}";
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; has_att = true;
break; break;
} }
} }
if (!has_att) if (!has_att)
{ {
ret ~= "{comp = components_map.get(\"" ~ (typeof(__traits(getMember, ret ~= "system.m_components[req++] = comp;}";
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;}";
} }
} }
} }
@ -216,11 +211,6 @@ class EntityManager
} }
} }
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")) static if (hasMember!(Sys, "update"))
{ {
alias types = Parameters!(Sys.update); alias types = Parameters!(Sys.update);
@ -243,11 +233,6 @@ class EntityManager
} }
} }
/*foreach (i; 1 .. (Parameters!(Sys.update)).length)
{
ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (i - 1)
.to!string ~ "]),";
}*/
uint i = 0; uint i = 0;
uint req = 0; uint req = 0;
uint opt = 0; uint opt = 0;
@ -301,6 +286,101 @@ class EntityManager
return ret; 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];
else input_data." ~ member ~ " = null;";
opt++;
has_att = true;
break;
}
else if (att == "absen")
{
absen++;
has_att = true;
break;
}
}
if (!has_att)
{
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];";
req++;
}
}
}
}
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());
}*/
block = block.next_block;
}
}
}
}
else
{
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"))
@ -336,6 +416,7 @@ class EntityManager
} }
} }
}
system.m_update = &callUpdate; system.m_update = &callUpdate;
} }
@ -918,7 +999,7 @@ class EntityManager
removeEntityNoID(entity, block); removeEntityNoID(entity, block);
} }
void addComponents(Components...)(EntityID entity_id, Components comps) void addComponents(Components...)(const EntityID entity_id, Components comps)
{ {
const uint num = Components.length; const uint num = Components.length;
Entity* entity = id_manager.getEntityPointer(entity_id); Entity* entity = id_manager.getEntityPointer(entity_id);
@ -1120,7 +1201,7 @@ class EntityManager
*params: *params:
*pointer = pointer to any data of entity (i.e. component data pointer) *pointer = pointer to any data of entity (i.e. component data pointer)
*/ */
export EntitiesBlock* getMetaData(void* pointer) export EntitiesBlock* getMetaData(const void* pointer)
{ {
return cast(EntitiesBlock*)(cast(size_t) pointer & (~cast(size_t)(page_size - 1))); return cast(EntitiesBlock*)(cast(size_t) pointer & (~cast(size_t)(page_size - 1)));
} }

View file

@ -127,10 +127,10 @@ int main()
static struct EntitiesData static struct EntitiesData
{ {
TestComp* test; TestComp[] test;
TestComp2* test2; TestComp2[] test2;
@optional TestComp3* test3; @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) void update(ref Entity entity, ref TestComp test, ref TestComp2 test2)//, TestComp3* test3) //ref TestComp comp)
@ -139,25 +139,21 @@ int main()
assert(cast(size_t)&test2 % TestComp2.alignof == 0); assert(cast(size_t)&test2 % TestComp2.alignof == 0);
import std.stdio; import std.stdio;
//writeln("Jakis tekst! ",test.b);
test.a += 1000; test.a += 1000;
test.b += 2000; test.b += 2000;
//writeln("Jakis tekst! ",test.b);
test2.b += 2; test2.b += 2;
test2.a = 8; test2.a = 8;
//writeln("Jakis tekst! ",test2.b);
//writeln("Low priority tekst! ");
/*if (test3)
{
test3.gg = 200;
test3.bg += 1;
}*/
} }
void update(ref EntitiesData data) void update(ref EntitiesData data)
{ {
foreach(i;0..data.test.length)
{
data.test[i].a += 1000;
data.test[i].b += 2000;
data.test2[i].b += 2;
data.test2[i].a = 8;
}
} }
void handleEvent(TestEvent event, ref TestComp test, ref TestComp2 test2, TestComp3* test3) void handleEvent(TestEvent event, ref TestComp test, ref TestComp2 test2, TestComp3* test3)
@ -172,7 +168,7 @@ int main()
static struct EntitiesData static struct EntitiesData
{ {
TestComp* test; TestComp[] test;
} }
void initialize(ref Entity entity, ref TestComp comp) void initialize(ref Entity entity, ref TestComp comp)
@ -206,8 +202,8 @@ int main()
static struct EntitiesData static struct EntitiesData
{ {
Entity* entity; Entity[] entity;
TestComp3* test; TestComp3[] test;
/*void a() /*void a()
{ {
@ -244,8 +240,12 @@ int main()
void update(ref EntitiesData data) //ref TestComp comp) void update(ref EntitiesData data) //ref TestComp comp)
{ {
//writeln("TestSystem2 update"); //writeln("TestSystem2 update");
data.test.gg += 14; foreach(i;0..data.test.length)
gEM.sendSelfEvent!(TestEvent)(data.entity.id, TestEvent()); {
data.test[i].gg += 14;
gEM.sendSelfEvent!(TestEvent)(data.entity[i].id, TestEvent());
}
} }
/*void handleEvent(Event event, ref TestComp comp) /*void handleEvent(Event event, ref TestComp comp)