-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:
parent
8468335b50
commit
ed589bbd71
5 changed files with 238 additions and 79 deletions
3
dub.json
3
dub.json
|
|
@ -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
4
source/ecs/attributes.d
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
module ecs.attributes;
|
||||||
|
|
||||||
|
enum optional = "optional";
|
||||||
|
enum absen = "absen";
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue