-git now should ignore .dub/dub.json

-added onAdd/onRemove to test
-added onAdd/onRemove callbacks for system
-generating onAdd/onRemove listeners
This commit is contained in:
Mergul 2019-03-23 19:48:24 +00:00
parent a82ca1e659
commit 6bbc8b5152
4 changed files with 116 additions and 2 deletions

View file

@ -84,6 +84,12 @@ class EntityManager
assert(register_state, "beginRegister() should be called before endRegister();");
register_state = false;
foreach(ref info; &entities_infos.byValue)
{
if(info.systems)Mallocator.instance.dispose(info.systems);
info.systems = Mallocator.instance.makeArray!bool(systems.length);
}
foreach (ref system; systems)
{
if (system.m_update is null)
@ -151,6 +157,11 @@ class EntityManager
}
}
foreach(info; &entities_infos.byValue)
{
generateListeners(info);
}
generateDependencies();
}
@ -681,7 +692,6 @@ class EntityManager
static "~RetType.stringof~" call" ~ func
~ "(void* system_pointer)
{
Sys* s = cast(Sys*) system_pointer;
"~ret_str~"s." ~ func ~ "();
}
@ -693,6 +703,32 @@ class EntityManager
//dfmt on
}
static string catchEntityFunc(RetType = void)(string member, string func)
{
//dfmt off
static if(is(RetType == void))string ret_str = "";
else string ret_str = "return ";
string ret = "static if (hasMember!(Sys, \"" ~ func ~ "\") &&
Parameters!(Sys."~func~").length == 1 &&
is(Parameters!(Sys."~func~")[0] == Sys.EntitiesData) &&
is(ReturnType!(Sys."~func~") == "~RetType.stringof~"))
{
static "~RetType.stringof~" call" ~ func
~ "(void* system_pointer)
{
Sys* s = cast(Sys*) system_pointer;
Sys.EntitiesData data;
"~ret_str~"s." ~ func ~ "(data);
}
system."
~ member ~ " = &call" ~ func ~ ";
}";
return ret;
//dfmt on
}
mixin(catchFunc("m_enable", "onEnable"));
mixin(catchFunc("m_disable", "onDisable"));
mixin(catchFunc("m_create", "onCreate"));
@ -700,6 +736,9 @@ class EntityManager
mixin(catchFunc!(bool)("m_begin", "onBegin"));
mixin(catchFunc("m_end", "onEnd"));
mixin(catchEntityFunc("m_entity_added","onAdd"));
mixin(catchEntityFunc("m_entity_removed","onRemove"));
system.m_system_pointer = cast(void*) Mallocator.instance.make!Sys;
system.m_priority = priority;
(cast(Sys*) system.m_system_pointer).__ecsInitialize();
@ -1145,6 +1184,8 @@ class EntityManager
current_delta += entites_in_block * components[id].size;
}
info.systems = Mallocator.instance.makeArray!bool(systems.length);
foreach (i, ref system; systems)
{
if (system.m_update is null)
@ -1153,10 +1194,52 @@ class EntityManager
}
entities_infos.add(info.components, info);
generateListeners(info);
}
return info;
}
void generateListeners(EntityInfo* info)
{
if(info.add_listeners)
{
Mallocator.instance.dispose(info.add_listeners);
info.add_listeners = null;
}
if(info.remove_listeners)
{
Mallocator.instance.dispose(info.remove_listeners);
info.remove_listeners = null;
}
ushort[] tmp_add = (cast(ushort*)alloca(systems.length*ushort.sizeof))[0..systems.length];
ushort[] tmp_rem = (cast(ushort*)alloca(systems.length*ushort.sizeof))[0..systems.length];
int add_len = 0;
int rem_len = 0;
foreach(i;0..systems.length)
{
if(info.systems[i])
{
System* system = &systems[i];
if(system.m_entity_added)tmp_add[add_len++] = cast(ushort)i;
if(system.m_entity_removed)tmp_rem[rem_len++] = cast(ushort)i;
}
}
if(add_len)
{
info.add_listeners = Mallocator.instance.makeArray!ushort(add_len);
memcpy(info.add_listeners.ptr,tmp_add.ptr,add_len*ushort.sizeof);
}
if(rem_len)
{
info.remove_listeners = Mallocator.instance.makeArray!ushort(rem_len);
memcpy(info.remove_listeners.ptr,tmp_add.ptr,rem_len*ushort.sizeof);
}
}
export void addSystemCaller(ref EntityInfo entity, uint system_id) nothrow @nogc
{
System* system = &systems[system_id];
@ -1193,6 +1276,8 @@ class EntityManager
if (index < passes[system.m_pass].system_callers.length)
passes[system.m_pass].system_callers[index].infos.add(&entity);
entity.systems[system_id] = true;
}
/************************************************************************************************************************
@ -2084,6 +2169,13 @@ class EntityManager
///max number of entities in block
ushort max_entities;
///array of systems which will update this entity
bool[] systems;
///systems which are listening for added entities
ushort[] add_listeners;
///systems which are listening for removed entities
ushort[] remove_listeners;
///pointer to first block/page
EntitiesBlock* first_block;
///pointer to last block

View file

@ -9,12 +9,15 @@ import ecs.manager;
/************************************************************************************************************************
*System contain data required to proper glue EntityManager with Systems.
*System callbacks:
*<br/>-void update(EntitesData);
*<br/>-void onEnable()
*<br/>-void onDisable();
*<br/>-bool onBegin();
*<br/>-void onEnd();
*<br/>-void onCreate()
*<br/>-void onDestroy();
*<br/>-void onAdd(EntitesData);
*<br/>-void onRemove(EntitiesData);
*/
struct System
{
@ -132,6 +135,9 @@ package:
void* m_begin;
void* m_end;
void* m_entity_added;
void* m_entity_removed;
//void function(ref EntityManager.CallData data) m_initialize;
//void function(ref EntityManager.CallData data) m_deinitilize;
void* m_initialize;