-added new listener callback: onChangeEntity. Callback is called when entity optional components are changed. There is no info about which components are changed (added/removed), but should be in the future).This is probably slowest callback.
This commit is contained in:
parent
7a33e4f94f
commit
0608fe6e89
3 changed files with 175 additions and 42 deletions
|
|
@ -95,7 +95,7 @@ class EntityManager
|
||||||
{
|
{
|
||||||
if (system.m_update is null)
|
if (system.m_update is null)
|
||||||
{
|
{
|
||||||
if (system.m_add_entity || system.m_remove_entity)
|
if (system.m_add_entity || system.m_remove_entity || system.m_change_entity)
|
||||||
{
|
{
|
||||||
foreach (info; &entities_infos.byValue)
|
foreach (info; &entities_infos.byValue)
|
||||||
{
|
{
|
||||||
|
|
@ -761,6 +761,7 @@ class EntityManager
|
||||||
|
|
||||||
mixin(catchEntityFunc("m_add_entity", "onAddEntity"));
|
mixin(catchEntityFunc("m_add_entity", "onAddEntity"));
|
||||||
mixin(catchEntityFunc("m_remove_entity", "onRemoveEntity"));
|
mixin(catchEntityFunc("m_remove_entity", "onRemoveEntity"));
|
||||||
|
mixin(catchEntityFunc("m_change_entity", "onChangeEntity"));
|
||||||
|
|
||||||
system.m_system_pointer = cast(void*) Mallocator.instance.make!Sys;
|
system.m_system_pointer = cast(void*) Mallocator.instance.make!Sys;
|
||||||
system.m_priority = priority;
|
system.m_priority = priority;
|
||||||
|
|
@ -1210,10 +1211,9 @@ class EntityManager
|
||||||
|
|
||||||
foreach (i, ref system; systems)
|
foreach (i, ref system; systems)
|
||||||
{
|
{
|
||||||
//if(system.m_add_entity || system.m_remove_entity)info.systems[system.id] = true;
|
|
||||||
if (system.m_update is null)
|
if (system.m_update is null)
|
||||||
{
|
{
|
||||||
if (system.m_add_entity || system.m_remove_entity)
|
if (system.m_add_entity || system.m_remove_entity || system.m_change_entity)
|
||||||
connectListenerToEntityInfo(*info, cast(uint) i);
|
connectListenerToEntityInfo(*info, cast(uint) i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -1239,13 +1239,21 @@ class EntityManager
|
||||||
Mallocator.instance.dispose(info.remove_listeners);
|
Mallocator.instance.dispose(info.remove_listeners);
|
||||||
info.remove_listeners = null;
|
info.remove_listeners = null;
|
||||||
}
|
}
|
||||||
|
if (info.change_listeners)
|
||||||
|
{
|
||||||
|
Mallocator.instance.dispose(info.change_listeners);
|
||||||
|
info.change_listeners = null;
|
||||||
|
}
|
||||||
//allocate local data
|
//allocate local data
|
||||||
ushort[] tmp_add = (cast(ushort*) alloca(systems.length * ushort.sizeof))[0
|
ushort[] tmp_add = (cast(ushort*) alloca(systems.length * ushort.sizeof))[0
|
||||||
.. systems.length];
|
.. systems.length];
|
||||||
ushort[] tmp_rem = (cast(ushort*) alloca(systems.length * ushort.sizeof))[0
|
ushort[] tmp_rem = (cast(ushort*) alloca(systems.length * ushort.sizeof))[0
|
||||||
.. systems.length];
|
.. systems.length];
|
||||||
|
ushort[] tmp_ch = (cast(ushort*) alloca(systems.length * ushort.sizeof))[0 .. systems
|
||||||
|
.length];
|
||||||
int add_len = 0;
|
int add_len = 0;
|
||||||
int rem_len = 0;
|
int rem_len = 0;
|
||||||
|
int ch_len = 0;
|
||||||
//assign listeners to lists
|
//assign listeners to lists
|
||||||
foreach (i; 0 .. systems.length)
|
foreach (i; 0 .. systems.length)
|
||||||
{
|
{
|
||||||
|
|
@ -1290,6 +1298,25 @@ class EntityManager
|
||||||
//assign listener
|
//assign listener
|
||||||
tmp_rem[j] = cast(ushort) i;
|
tmp_rem[j] = cast(ushort) i;
|
||||||
}
|
}
|
||||||
|
//onChangeEntity listener
|
||||||
|
if (system.m_change_entity)
|
||||||
|
{
|
||||||
|
//find listener position by priority
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < ch_len; j++)
|
||||||
|
{
|
||||||
|
if (systems[i].priority > systems[tmp_ch[j]].priority)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ch_len++;
|
||||||
|
//move elements after new listener
|
||||||
|
for (int k = ch_len; k > j; k--)
|
||||||
|
{
|
||||||
|
tmp_ch[k] = tmp_ch[k - 1];
|
||||||
|
}
|
||||||
|
//assign listener
|
||||||
|
tmp_ch[j] = cast(ushort) i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1304,6 +1331,12 @@ class EntityManager
|
||||||
info.remove_listeners = Mallocator.instance.makeArray!ushort(rem_len);
|
info.remove_listeners = Mallocator.instance.makeArray!ushort(rem_len);
|
||||||
memcpy(info.remove_listeners.ptr, tmp_rem.ptr, rem_len * ushort.sizeof);
|
memcpy(info.remove_listeners.ptr, tmp_rem.ptr, rem_len * ushort.sizeof);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ch_len)
|
||||||
|
{
|
||||||
|
info.change_listeners = Mallocator.instance.makeArray!ushort(ch_len);
|
||||||
|
memcpy(info.change_listeners.ptr, tmp_ch.ptr, ch_len * ushort.sizeof);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export void connectListenerToEntityInfo(ref EntityInfo entity, uint system_id) nothrow @nogc
|
export void connectListenerToEntityInfo(ref EntityInfo entity, uint system_id) nothrow @nogc
|
||||||
|
|
@ -1486,6 +1519,18 @@ class EntityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (new_info.change_listeners)
|
||||||
|
{
|
||||||
|
foreach (listener; new_info.change_listeners)
|
||||||
|
{
|
||||||
|
if (info.systems[listener])
|
||||||
|
{
|
||||||
|
callChangeEntityListener(&systems[listener], new_info, new_block,
|
||||||
|
new_block.entities_count, new_block.entities_count + 1, del_ids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
new_block.entities_count++;
|
new_block.entities_count++;
|
||||||
|
|
||||||
removeEntityNoID(entity, block);
|
removeEntityNoID(entity, block);
|
||||||
|
|
@ -1660,6 +1705,18 @@ class EntityManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (new_info.change_listeners)
|
||||||
|
{
|
||||||
|
foreach (listener; new_info.change_listeners)
|
||||||
|
{
|
||||||
|
if (info.systems[listener])
|
||||||
|
{
|
||||||
|
callChangeEntityListener(&systems[listener], new_info, new_block,
|
||||||
|
new_block.entities_count, new_block.entities_count + 1, new_ids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
new_block.entities_count++;
|
new_block.entities_count++;
|
||||||
removeEntityNoID(entity, block);
|
removeEntityNoID(entity, block);
|
||||||
}
|
}
|
||||||
|
|
@ -2026,6 +2083,43 @@ class EntityManager
|
||||||
(cast(void function(ref ListenerCallData) nothrow @nogc) system.m_remove_entity)(data);
|
(cast(void function(ref ListenerCallData) nothrow @nogc) system.m_remove_entity)(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void callChangeEntityListener(System* system, EntityInfo* info,
|
||||||
|
EntitiesBlock* block, int begin, int end, ushort[] ch_ids) @nogc nothrow
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
bool is_ = false;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (ch_ids[i] == system.m_optional_components[j])
|
||||||
|
{
|
||||||
|
is_ = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (ch_ids[i] > system.m_optional_components[j])
|
||||||
|
{
|
||||||
|
j++;
|
||||||
|
if (j >= system.m_optional_components.length)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
if (i >= ch_ids.length)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!is_)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ListenerCallData data;
|
||||||
|
data.system = system;
|
||||||
|
data.block = block;
|
||||||
|
data.begin = begin;
|
||||||
|
data.end = end;
|
||||||
|
(cast(void function(ref ListenerCallData) nothrow @nogc) system.m_change_entity)(data);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateBlocks()
|
private void updateBlocks()
|
||||||
{
|
{
|
||||||
foreach (ref thread; threads)
|
foreach (ref thread; threads)
|
||||||
|
|
@ -2393,6 +2487,8 @@ class EntityManager
|
||||||
ushort[] add_listeners;
|
ushort[] add_listeners;
|
||||||
///systems which are listening for removed entities
|
///systems which are listening for removed entities
|
||||||
ushort[] remove_listeners;
|
ushort[] remove_listeners;
|
||||||
|
///systems which are listening for changed entities (changed in term of contained components)
|
||||||
|
ushort[] change_listeners;
|
||||||
|
|
||||||
///pointer to first block/page
|
///pointer to first block/page
|
||||||
EntitiesBlock* first_block;
|
EntitiesBlock* first_block;
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,7 @@ package:
|
||||||
|
|
||||||
void* m_add_entity;
|
void* m_add_entity;
|
||||||
void* m_remove_entity;
|
void* m_remove_entity;
|
||||||
|
void* m_change_entity;
|
||||||
|
|
||||||
//void function(ref EntityManager.CallData data) m_initialize;
|
//void function(ref EntityManager.CallData data) m_initialize;
|
||||||
//void function(ref EntityManager.CallData data) m_deinitilize;
|
//void function(ref EntityManager.CallData data) m_deinitilize;
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,27 @@ static struct TestComp4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct TestComp5
|
||||||
|
{
|
||||||
|
mixin ECS.Component; //__gshared ushort component_id;
|
||||||
|
uint gg = 7; //good game
|
||||||
|
uint bg = 8; //bad game
|
||||||
|
ulong a = 9;
|
||||||
|
ulong b = 10;
|
||||||
|
ulong c = 11;
|
||||||
|
ulong g = 12;
|
||||||
|
|
||||||
|
static void serializeComponent(ref TestComp comp, SerializeVector output)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deserializeComponent(ref TestComp comp, ubyte[] data)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct ChangeTestSystem
|
struct ChangeTestSystem
|
||||||
{
|
{
|
||||||
mixin ECS.System!16; //__gshared ushort system_id;
|
mixin ECS.System!16; //__gshared ushort system_id;
|
||||||
|
|
@ -111,12 +132,17 @@ struct ChangeTestSystem
|
||||||
void onAddEntity(EntitiesData data)
|
void onAddEntity(EntitiesData data)
|
||||||
{
|
{
|
||||||
foreach (i; 0 .. data.length)
|
foreach (i; 0 .. data.length)
|
||||||
writeln("Entity added ID: ",data.entites[i].id.id);
|
writeln("Entity added! ID: ", data.entites[i].id.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onRemoveEntity(EntitiesData data)
|
void onRemoveEntity(EntitiesData data)
|
||||||
{
|
{
|
||||||
writeln("Entity removed ID: ",data.entites[0].id);
|
writeln("Entity removed! ID: ", data.entites[0].id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onChangeEntity(EntitiesData data)
|
||||||
|
{
|
||||||
|
writeln("Entity changed! ID: ", data.entites[0].id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool onBegin()
|
bool onBegin()
|
||||||
|
|
@ -140,6 +166,7 @@ struct ChangeTestSystem
|
||||||
size_t length;
|
size_t length;
|
||||||
const(Entity)[] entites;
|
const(Entity)[] entites;
|
||||||
TestComp4[] test4;
|
TestComp4[] test4;
|
||||||
|
@optional TestComp5[] test5;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onUpdate(EntitiesData data)
|
void onUpdate(EntitiesData data)
|
||||||
|
|
@ -306,7 +333,6 @@ struct Sys3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
import std.meta;
|
import std.meta;
|
||||||
|
|
||||||
struct TestSystem2
|
struct TestSystem2
|
||||||
|
|
@ -417,13 +443,17 @@ int main()
|
||||||
{
|
{
|
||||||
write(entity.id);
|
write(entity.id);
|
||||||
TestComp* test_comp = entity.getComponent!TestComp;
|
TestComp* test_comp = entity.getComponent!TestComp;
|
||||||
if(test_comp)write(*test_comp);
|
if (test_comp)
|
||||||
|
write(*test_comp);
|
||||||
TestComp2* test_comp2 = entity.getComponent!TestComp2;
|
TestComp2* test_comp2 = entity.getComponent!TestComp2;
|
||||||
if(test_comp2)write(*test_comp2);
|
if (test_comp2)
|
||||||
|
write(*test_comp2);
|
||||||
TestComp3* test_comp3 = entity.getComponent!TestComp3;
|
TestComp3* test_comp3 = entity.getComponent!TestComp3;
|
||||||
if(test_comp3)write(*test_comp3);
|
if (test_comp3)
|
||||||
|
write(*test_comp3);
|
||||||
TestComp4* test_comp4 = entity.getComponent!TestComp4;
|
TestComp4* test_comp4 = entity.getComponent!TestComp4;
|
||||||
if(test_comp4)write(*test_comp4);
|
if (test_comp4)
|
||||||
|
write(*test_comp4);
|
||||||
writeln();
|
writeln();
|
||||||
//writeln((cast(uint*) pp)[0 .. 14], " ", pp);
|
//writeln((cast(uint*) pp)[0 .. 14], " ", pp);
|
||||||
}
|
}
|
||||||
|
|
@ -441,6 +471,7 @@ int main()
|
||||||
gEM.registerComponent!TestComp4;
|
gEM.registerComponent!TestComp4;
|
||||||
gEM.registerComponent!TestComp;
|
gEM.registerComponent!TestComp;
|
||||||
gEM.registerComponent!TestComp3;
|
gEM.registerComponent!TestComp3;
|
||||||
|
gEM.registerComponent!TestComp5;
|
||||||
|
|
||||||
gEM.registerEvent!TestEvent;
|
gEM.registerEvent!TestEvent;
|
||||||
gEM.registerEvent!TestEvent2;
|
gEM.registerEvent!TestEvent2;
|
||||||
|
|
@ -483,7 +514,8 @@ int main()
|
||||||
{
|
{
|
||||||
entity = gEM.addEntity(tmpl);
|
entity = gEM.addEntity(tmpl);
|
||||||
writeEntityComponents(gEM.getEntity(entity.id));
|
writeEntityComponents(gEM.getEntity(entity.id));
|
||||||
EntityManager.EntitiesBlock* block = EntityManager.instance.getMetaData(gEM.getEntity(entity.id));
|
EntityManager.EntitiesBlock* block = EntityManager.instance.getMetaData(
|
||||||
|
gEM.getEntity(entity.id));
|
||||||
EntityManager.EntityInfo* info = block.type_info;
|
EntityManager.EntityInfo* info = block.type_info;
|
||||||
writeln(info.add_listeners);
|
writeln(info.add_listeners);
|
||||||
//if(info)assert(0);
|
//if(info)assert(0);
|
||||||
|
|
@ -607,13 +639,17 @@ int main()
|
||||||
|
|
||||||
gEM.removeComponents!(TestComp)(entity.id);
|
gEM.removeComponents!(TestComp)(entity.id);
|
||||||
gEM.addComponents(entity.id, TestComp());
|
gEM.addComponents(entity.id, TestComp());
|
||||||
gEM.removeComponents!(TestComp4)(entity.id);
|
gEM.addComponents(entity.id, TestComp5());
|
||||||
|
|
||||||
gEM.begin();
|
gEM.begin();
|
||||||
gEM.update();
|
gEM.update();
|
||||||
gEM.update("fixed");
|
gEM.update("fixed");
|
||||||
gEM.end();
|
gEM.end();
|
||||||
|
|
||||||
|
gEM.removeComponents!(TestComp4)(entity.id);
|
||||||
|
|
||||||
|
gEM.commit();
|
||||||
|
|
||||||
writeEntityComponents(gEM.getEntity(entity.id));
|
writeEntityComponents(gEM.getEntity(entity.id));
|
||||||
//import std.stdio;
|
//import std.stdio;
|
||||||
//writeln((cast(uint*)tmpl.info.first_block)[0..48]);
|
//writeln((cast(uint*)tmpl.info.first_block)[0..48]);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue