-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
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,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)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ package:
|
|||
void* m_system_pointer;
|
||||
|
||||
ushort[] m_components;
|
||||
ushort[] m_absen_components;
|
||||
ushort[] m_optional_components;
|
||||
|
||||
//void function(ref EntityManager.CallData data, void* entity) update;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue