-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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue