-onAdd/onRemove order is determined by system priority
-fixed many bug with onAdd/onRemove -onAdd/onRemove now works even when system haven't update callback
This commit is contained in:
parent
c64d621f0e
commit
280d7b8ec4
2 changed files with 148 additions and 11 deletions
|
|
@ -93,7 +93,16 @@ class EntityManager
|
|||
foreach (ref system; systems)
|
||||
{
|
||||
if (system.m_update is null)
|
||||
{
|
||||
if(system.m_entity_added || system.m_entity_removed)
|
||||
{
|
||||
foreach (info; &entities_infos.byValue)
|
||||
{
|
||||
connectListenerToEntityInfo(*info,system.id);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
bool added = false;
|
||||
foreach (i, caller; passes[system.m_pass].system_callers)
|
||||
|
|
@ -119,6 +128,7 @@ class EntityManager
|
|||
foreach (info; &entities_infos.byValue)
|
||||
{
|
||||
addSystemCaller(*info, system.id);
|
||||
//info.systems[system.id] = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1197,8 +1207,12 @@ class EntityManager
|
|||
|
||||
foreach (i, ref system; systems)
|
||||
{
|
||||
//if(system.m_entity_added || system.m_entity_removed)info.systems[system.id] = true;
|
||||
if (system.m_update is null)
|
||||
{
|
||||
if(system.m_entity_added || system.m_entity_removed)connectListenerToEntityInfo(*info,cast(uint)i);
|
||||
continue;
|
||||
}
|
||||
addSystemCaller(*info, cast(uint)i);
|
||||
}
|
||||
|
||||
|
|
@ -1221,18 +1235,53 @@ class EntityManager
|
|||
Mallocator.instance.dispose(info.remove_listeners);
|
||||
info.remove_listeners = null;
|
||||
}
|
||||
|
||||
//allocate local data
|
||||
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;
|
||||
//assign listeners to lists
|
||||
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;
|
||||
//onAddEntity listener
|
||||
if(system.m_entity_added)
|
||||
{
|
||||
//find listener position by priority
|
||||
int j;
|
||||
for(j=0;j<add_len;j++)
|
||||
{
|
||||
if(systems[i].priority > systems[tmp_add[j]].priority)break;
|
||||
}
|
||||
add_len++;
|
||||
//move elements after new listener
|
||||
for(int k=add_len;k>j;k--)
|
||||
{
|
||||
tmp_add[k] = tmp_add[k-1];
|
||||
}
|
||||
//assign listener
|
||||
tmp_add[j] = cast(ushort)i;
|
||||
}
|
||||
//onRemoveEntity listener
|
||||
if(system.m_entity_removed)
|
||||
{
|
||||
//find listener position by priority
|
||||
int j;
|
||||
for(j=0;j<rem_len;j++)
|
||||
{
|
||||
if(systems[i].priority > systems[tmp_rem[j]].priority)break;
|
||||
}
|
||||
rem_len++;
|
||||
//move elements after new listener
|
||||
for(int k=rem_len;k>j;k--)
|
||||
{
|
||||
tmp_rem[k] = tmp_rem[k-1];
|
||||
}
|
||||
//assign listener
|
||||
tmp_rem[j] = cast(ushort)i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1245,11 +1294,11 @@ class EntityManager
|
|||
if(rem_len)
|
||||
{
|
||||
info.remove_listeners = Mallocator.instance.makeArray!ushort(rem_len);
|
||||
memcpy(info.remove_listeners.ptr,tmp_add.ptr,rem_len*ushort.sizeof);
|
||||
memcpy(info.remove_listeners.ptr,tmp_rem.ptr,rem_len*ushort.sizeof);
|
||||
}
|
||||
}
|
||||
|
||||
export void addSystemCaller(ref EntityInfo entity, uint system_id) nothrow @nogc
|
||||
export void connectListenerToEntityInfo(ref EntityInfo entity, uint system_id) nothrow @nogc
|
||||
{
|
||||
System* system = &systems[system_id];
|
||||
|
||||
|
|
@ -1276,6 +1325,38 @@ class EntityManager
|
|||
is_:
|
||||
}
|
||||
|
||||
entity.systems[system_id] = true;
|
||||
}
|
||||
|
||||
export void addSystemCaller(ref EntityInfo info, uint system_id) nothrow @nogc
|
||||
{
|
||||
System* system = &systems[system_id];
|
||||
|
||||
if (system.m_excluded_components)
|
||||
{
|
||||
foreach (id; system.m_excluded_components)
|
||||
{
|
||||
foreach (id2; info.components)
|
||||
{
|
||||
if (id == id2)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (id; system.m_components)
|
||||
{
|
||||
foreach (i2, id2; info.components)
|
||||
{
|
||||
if (id2 == id)
|
||||
goto is_;
|
||||
}
|
||||
return;
|
||||
is_:
|
||||
}
|
||||
|
||||
info.systems[system_id] = true;
|
||||
|
||||
uint index = 0;
|
||||
for (; index < passes[system.m_pass].system_callers.length; index++)
|
||||
{
|
||||
|
|
@ -1285,9 +1366,7 @@ 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;
|
||||
passes[system.m_pass].system_callers[index].infos.add(&info);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1917,7 +1996,7 @@ class EntityManager
|
|||
|
||||
private void callRemoveEntityListeners(EntityInfo* info, EntitiesBlock* block, int begin, int end) @nogc nothrow
|
||||
{
|
||||
foreach(listener;info.add_listeners)
|
||||
foreach(listener;info.remove_listeners)
|
||||
{
|
||||
System* system = &systems[listener];
|
||||
callRemoveEntityListener(system,info,block,begin,end);
|
||||
|
|
|
|||
|
|
@ -170,11 +170,11 @@ struct TestSystem
|
|||
//foreach(i;0..data.length)
|
||||
//writeln("Entity added ID: ",data.entites[i].id.id);
|
||||
}
|
||||
|
||||
/*
|
||||
void onRemove(EntitiesData data)
|
||||
{
|
||||
//writeln("Entity destroyed ID: ",data.entites[0].id);
|
||||
}
|
||||
}*/
|
||||
|
||||
bool onBegin()
|
||||
{
|
||||
|
|
@ -256,6 +256,57 @@ struct TestSystemWithHighPriority
|
|||
}*/
|
||||
}
|
||||
|
||||
struct Sys1
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
TestComp[] comp;
|
||||
}
|
||||
|
||||
void onAdd(EntitiesData data)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct Sys2
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
TestComp[] comp;
|
||||
}
|
||||
|
||||
void onAdd(EntitiesData data)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct Sys3
|
||||
{
|
||||
mixin ECS.System;
|
||||
|
||||
struct EntitiesData
|
||||
{
|
||||
TestComp[] comp;
|
||||
}
|
||||
|
||||
void onAdd(EntitiesData data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void update(EntitiesData data)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
import std.meta;
|
||||
|
||||
struct TestSystem2
|
||||
|
|
@ -402,6 +453,9 @@ int main()
|
|||
gEM.registerSystem!TestSystemWithHighPriority(100,"fixed");
|
||||
gEM.registerSystem!TestSystem(0);
|
||||
gEM.registerSystem!ChangeTestSystem(0);
|
||||
gEM.registerSystem!Sys1(10);
|
||||
gEM.registerSystem!Sys2(-100);
|
||||
gEM.registerSystem!Sys3(-2);
|
||||
//gEM.registerSystem!TestSystemWithHighPriority(100);
|
||||
//gEM.registerSystem!TestSystem2(0);
|
||||
gEM.endRegister();
|
||||
|
|
@ -429,6 +483,10 @@ int main()
|
|||
{
|
||||
entity = gEM.addEntity(tmpl);
|
||||
writeEntityComponents(gEM.getEntity(entity.id));
|
||||
EntityManager.EntitiesBlock* block = EntityManager.instance.getMetaData(gEM.getEntity(entity.id));
|
||||
EntityManager.EntityInfo* info = block.type_info;
|
||||
writeln(info.add_listeners);
|
||||
//if(info)assert(0);
|
||||
}
|
||||
|
||||
time = MonoTime.currTime;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue