-fixed removingComponents issue (object was transferred to another block, but count of entities in block doesn't increase)

-functions to get System by ID or ECS System by Type
-added system_id to system
-fixed issue with registering systems without update() function
This commit is contained in:
Mergul 2018-09-20 19:12:53 +02:00
parent 4ad81fe116
commit 45110e236c
2 changed files with 118 additions and 89 deletions

View file

@ -57,102 +57,88 @@ class EntityManager
void registerSystem(Sys)(int priority) void registerSystem(Sys)(int priority)
{ {
alias types = Parameters!(Sys.update);
alias storages = ParameterStorageClassTuple!(Sys.update);
alias STC = ParameterStorageClass; alias STC = ParameterStorageClass;
System system; System system;
static string genCall()() static if (!(hasMember!(Sys, "system_id")) || !is(typeof(Sys.system_id) == ushort))
{ {
string ret = "s.update(*cast(Entity*)data_pointer,"; static assert(0, "System should have \"__gshared ushort system_id");
/*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;
static foreach (param; (Parameters!(Sys.update))[1 .. $])
{
i++;
if (isPointer!param)
{
ret ~= "cast(types[" ~ i.to!string ~ "])(optional_pointers[" ~ (opt++)
.to!string ~ "]),";
}
else
{
ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (req++)
.to!string ~ "]),";
}
}
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 string catchFunc()(string member, string func)
{
string ret = "static if (hasMember!(Sys, \"" ~ func ~ "\"))
{
static void call" ~ func
~ "(void* system_pointer)
{
Sys* s = cast(Sys*) system_pointer;
s." ~ func ~ "();
}
system."
~ member ~ " = &call" ~ func ~ ";
}";
return ret;
} }
static if (hasMember!(Sys, "update")) static if (hasMember!(Sys, "update"))
{ {
alias types = Parameters!(Sys.update);
alias storages = ParameterStorageClassTuple!(Sys.update);
static string genCall()()
{
string ret = "s.update(*cast(Entity*)data_pointer,";
/*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;
static foreach (param; (Parameters!(Sys.update))[1 .. $])
{
i++;
if (isPointer!param)
{
ret ~= "cast(types[" ~ i.to!string ~ "])(optional_pointers[" ~ (opt++)
.to!string ~ "]),";
}
else
{
ret ~= "*cast(types[" ~ i.to!string ~ "]*)(pointers[" ~ (req++)
.to!string ~ "]),";
}
}
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"))
@ -201,6 +187,24 @@ class EntityManager
system.m_update = &callUpdate; system.m_update = &callUpdate;
} }
static string catchFunc()(string member, string func)
{
string ret = "static if (hasMember!(Sys, \"" ~ func ~ "\"))
{
static void call" ~ func
~ "(void* system_pointer)
{
Sys* s = cast(Sys*) system_pointer;
s." ~ func ~ "();
}
system."
~ member ~ " = &call" ~ func ~ ";
}";
return ret;
}
mixin(catchFunc("m_enable", "onEnable")); mixin(catchFunc("m_enable", "onEnable"));
mixin(catchFunc("m_disable", "onDisable")); mixin(catchFunc("m_disable", "onDisable"));
mixin(catchFunc("m_create", "onCreate")); mixin(catchFunc("m_create", "onCreate"));
@ -212,13 +216,17 @@ 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);
mixin(genCompList()); static if (hasMember!(Sys, "update"))
{
mixin(genCompList());
}
ushort sys_id = systems_map.get(Sys.stringof, ushort.max); ushort sys_id = systems_map.get(Sys.stringof, ushort.max);
if (sys_id < systems.length) if (sys_id < systems.length)
{ {
system.enable(); system.enable();
systems[sys_id] = system; systems[sys_id] = system;
Sys.system_id = sys_id;
} }
else else
{ {
@ -231,6 +239,8 @@ class EntityManager
systems[$ - 1].enable(); systems[$ - 1].enable();
Sys.system_id = cast(ushort)(systems.length - 1);
foreach (info; &entities_infos.byValue) foreach (info; &entities_infos.byValue)
{ {
addEntityCaller(*info, cast(uint) systems.length - 1); addEntityCaller(*info, cast(uint) systems.length - 1);
@ -240,6 +250,16 @@ class EntityManager
updateEntityCallers(); updateEntityCallers();
} }
System* getSystem(ushort id)
{
return &systems[id];
}
Sys* getSystem(Sys)()
{
return cast(Sys*)systems[Sys.system_id].system_pointer;
}
void registerComponent(Comp)() void registerComponent(Comp)()
{ {
ComponentInfo info; ComponentInfo info;
@ -538,6 +558,8 @@ class EntityManager
cast(void*) entity + info.deltas[comp], components[comp].size); cast(void*) entity + info.deltas[comp], components[comp].size);
} }
new_block.entities_count++;
removeEntityNoID(entity, block); removeEntityNoID(entity, block);
} }

View file

@ -119,6 +119,13 @@ int main()
} }
struct InputData
{
TestComp* test;
TestComp2* test2;
@("optional") TestComp3* test3;
}
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)
{ {
assert(cast(size_t)&test % TestComp.alignof == 0); assert(cast(size_t)&test % TestComp.alignof == 0);