module tests.tests; import std.experimental.allocator; import std.experimental.allocator.mallocator; import ecs.entity; import ecs.events; import ecs.manager; import ecs.system; import ecs.attributes; import ecs.core; import core.time; import std.stdio; struct TestEvent { mixin ECS.Event; //__gshared ushort event_id; int a; } struct TestEvent2 { mixin ECS.Event; //__gshared ushort event_id; float a; } static struct TestComp { mixin ECS.Component; //__gshared ushort component_id; int a = 1; ulong b = 2; static void serializeComponent(SerializeVector output) { } static void deserializeComponent(ubyte[] data) { } } static struct TestComp2 { mixin ECS.Component; //__gshared ushort component_id; int b = 3; int a = 4; static void serializeComponent(ref TestComp comp, SerializeVector output) { } static void deserializeComponent(ref TestComp comp, ubyte[] data) { } } static struct TestComp3 { mixin ECS.Component; //__gshared ushort component_id; uint gg = 5; //good game uint bg = 6; //bad game void serializeComponent(SerializeVector output) { } void deserializeComponent(ubyte[] data) { } } static struct TestComp4 { 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) { } } 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 { mixin ECS.System!16; //__gshared ushort system_id; void onCreate() { writeln("On Change Test System create."); } void onCreate(int i) { writeln("On Change Test System create."); } void onDestroy() { writeln("On Change Test System destroy."); } void onAddEntity(EntitiesData data) { //printf("Entity added! ID: "); foreach (i; 0 .. data.length) printf("Entity added! ID: %u\n",data.entites[i].id); //writeln("Entity added! ID: ", data.entites[i].id); } void onRemoveEntity(EntitiesData data) { //writeln("Entity removed! ID: ", data.entites[0].id); printf("Entity removed! ID: %u\n",data.entites[0].id); } void onChangeEntity(EntitiesData data) { //writeln("Entity changed! ID: ", data.entites[0].id); printf("Entity changed! ID: %u\n",data.entites[0].id); } bool onBegin() { //writeln("On Test System begin."); return true; } void onEnd() { //writeln("On Test System end."); } void initialize(ref Entity entity, ref TestComp comp) { } static struct EntitiesData { size_t length; const(Entity)[] entites; TestComp4[] test4; @optional TestComp5[] test5; } void onUpdate(EntitiesData data) { foreach (i; 0 .. data.length) { } } } struct TestSystem { mixin ECS.System!16; //__gshared ushort system_id; void onCreate() { writeln("On Test System create."); } void onDestroy() { writeln("On Test System destroy."); } void onAddEntity(EntitiesData data) { //foreach(i;0..data.length) //writeln("Entity added ID: ",data.entites[i].id.id); } /* void onRemoveEntity(EntitiesData data) { //writeln("Entity destroyed ID: ",data.entites[0].id); }*/ bool onBegin() { //writeln("On Test System begin."); return true; } void onEnd() { //writeln("On Test System end."); } void initialize(ref Entity entity, ref TestComp comp) { } static struct EntitiesData { size_t length; const(Entity)[] entites; TestComp[] test; TestComp2[] test2; @readonly @optional const(TestComp3)[] test3; //@excluded TestComp4[] test4; } void onUpdate(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)&test2 % TestComp2.alignof == 0); import std.stdio; test.a += 1000; test.b += 2000; test2.b += 2; test2.a = 8; } void onUpdate(EntitiesData data) { foreach (i; 0 .. data.length) { data.test[i].a += 1000; data.test[i].b += 2000; data.test2[i].b += 2; data.test2[i].a = 8; } } void handleEvent(TestEvent event, ref TestComp test, ref TestComp2 test2, TestComp3* test3) { } } struct TestSystemWithHighPriority { mixin ECS.System!16; //__gshared ushort system_id; static struct EntitiesData { TestComp[] test; } void initialize(ref Entity entity, ref TestComp comp) { int o = 1; } void onUpdate(EntitiesData data) { } /*void handleEvent(Event event, ref TestComp comp) { }*/ } struct Sys1 { mixin ECS.System; struct EntitiesData { TestComp[] comp; } void onAddEntity(EntitiesData data) { } } struct Sys2 { mixin ECS.System; struct EntitiesData { TestComp[] comp; } void onAddEntity(EntitiesData data) { } } struct Sys3 { mixin ECS.System; struct EntitiesData { TestComp[] comp; } void onAddEntity(EntitiesData data) { } void onUpdate(EntitiesData data) { } } import std.meta; struct TestSystem2 { mixin ECS.System!16; //__gshared ushort system_id; /*enum ExcludedComponents { TestComp, TestComp4 }*/ //alias ExcludedComponents = AliasSeq!("TestComp", "TestComp4"); /* string ExcludedComponents2;*/ static struct EntitiesData { short length; const(Entity)[] entity; TestComp3[] test; //@excluded TestComp[] testt; } static struct EventInput { Entity* entity; TestComp3* test; //TestComp* tt; } void handleEvent(EventInput input) { } void handleEvent(EventInput input, ref TestEvent event) { input.test.bg = event.a; TestEvent2 event2; event2.a = event.a + 8; gEM.sendEvent(input.entity.id, event2); } void handleEvent(EventInput input, ref TestEvent2 event) { input.test.gg = cast(uint) event.a; } void onEnable() { import std.stdio; writeln("TestSystem2 enabled"); } void onDisable() { import std.stdio; writeln("TestSystem2 disabled"); } void initialize(ref Entity entity, ref TestComp comp) { } void onUpdate(EntitiesData data) { foreach (i; 0 .. data.test.length) { data.test[i].gg += 14; TestEvent event; event.a = data.test[i].gg + 4; gEM.sendEvent(data.entity[i].id, event); //*/ /*TestEvent2 event2; event2.a = data.test[i].gg + 8; gEM.sendEvent(data.entity[i].id, event2);//*/ //gEM.sendEvent!(TestEvent)(data.entity[i].id, event); //gEM.sendSelfEvent!(TestEvent)(data.entity[i].id, TestEvent()); } } void lateUpdate(ref EntitiesData data) { foreach (i; 0 .. data.test.length) { data.test[i].gg -= 1; //gEM.sendSelfEvent!(TestEvent)(data.entity[i].id, TestEvent()); } } /*void handleEvent(Event event, ref TestComp comp) { }*/ } int main() { void dispatch(EntityManager.JobGroup jobs) nothrow @nogc { foreach (job; jobs.jobs) { //writeln(job); job.execute(); } } void writeEntityComponents(Entity* entity) { write(entity.id); TestComp* test_comp = entity.getComponent!TestComp; if (test_comp) write(*test_comp); TestComp2* test_comp2 = entity.getComponent!TestComp2; if (test_comp2) write(*test_comp2); TestComp3* test_comp3 = entity.getComponent!TestComp3; if (test_comp3) write(*test_comp3); TestComp4* test_comp4 = entity.getComponent!TestComp4; if (test_comp4) write(*test_comp4); writeln(); //writeln((cast(uint*) pp)[0 .. 14], " ", pp); } EntityManager.initialize(1); gEM.setJobDispachFunc(&dispatch); assert(gEM !is null); gEM.beginRegister(); gEM.registerPass("fixed"); MonoTime time = MonoTime.currTime; gEM.registerComponent!TestComp2; gEM.registerComponent!TestComp4; gEM.registerComponent!TestComp; gEM.registerComponent!TestComp3; gEM.registerComponent!TestComp5; gEM.registerEvent!TestEvent; gEM.registerEvent!TestEvent2; ulong dur = (MonoTime.currTime - time).total!"usecs"; writeln("Components register: ", dur, " usecs"); time = MonoTime.currTime; 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(); dur = (MonoTime.currTime - time).total!"usecs"; writeln("Systems register: ", dur, " usecs"); time = MonoTime.currTime; //ushort[3] ids = [TestComp2.component_id, TestComp.component_id, TestComp4.component_id]; ushort[2] ids = [TestComp2.component_id, TestComp.component_id]; EntityTemplate* tmpl = gEM.allocateTemplate(ids); //ushort[3] ids2 = [TestComp3.component_id, TestComp.component_id, TestComp4.component_id]; ushort[2] ids2 = [TestComp3.component_id, TestComp.component_id]; EntityTemplate* tmpl2 = gEM.allocateTemplate(ids2); //writeln(tmpl.info.components[]); //*cast(EntityID*) tmpl.entity_data.ptr = EntityID(1, 1); dur = (MonoTime.currTime - time).total!"usecs"; writeln("Template allocating: ", dur, " usecs"); Entity entity; { 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; //foreach(i; 0..1_000_000)gEM.addEntity(tmpl); //foreach(i; 0..1_000_000)gEM.removeEntity(gEM.addEntity(tmpl).id); EntityID[] idss = Mallocator.instance.makeArray!EntityID(5000);//[5000] scope(exit)Mallocator.instance.dispose(idss); foreach (i; 0 .. 200) { gEM.begin(); foreach (j; 0 .. 5_000) idss[j] = gEM.addEntity(tmpl).id; foreach (j; 0 .. 5_000) gEM.removeEntity(idss[j]); gEM.end(); } gEM.commit(); dur = (MonoTime.currTime - time).total!"usecs"; writeln("Entities adding: ", dur, " usecs"); uint blocks = 0; foreach (info; &gEM.entities_infos.byValue) { EntityManager.EntitiesBlock* block = info.first_block; while (block !is null) { block = block.next_block; blocks++; } } writeln("Entities blocks: ", blocks); //foreach(j; 0..1_000)gEM.addEntity(tmpl); gEM.beginRegister(); gEM.registerSystem!TestSystem2(0); gEM.endRegister(); System* sys = EntityManager.instance.getSystem(TestSystem2.system_id); //gEM.generateDependencies(); //assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+24)) == EntityID(1,1)); //assert(*(cast(EntityID*)(cast(void*)tmpl.info.first_block+48)) == EntityID(1,1)); Entity entity2; time = MonoTime.currTime; EntityID[] entities = Mallocator.instance.makeArray!EntityID(1_000_000); foreach (i; 0 .. 500_000) { entity2 = gEM.addEntity(tmpl); entities[i*2] = entity2.id; entities[i*2+1] = gEM.addEntity(tmpl2).id; } gEM.commit(); dur = (MonoTime.currTime - time).total!"usecs"; writeln("Entities adding2: ", dur, " usecs"); time = MonoTime.currTime; foreach (i; 0 .. 1_000_000) { EntityManager.instance.addComponents(entities[i],TestComp5()); if((i & 0x00FFFF) == 0)gEM.commit(); } gEM.commit(); dur = (MonoTime.currTime - time).total!"usecs"; writeln("Components adding: ", dur, " usecs"); time = MonoTime.currTime; foreach (i; 0 .. 1_000_000) { EntityManager.instance.removeComponents!TestComp5(entities[i]); //if((i & 0x00FFFF) == 0)gEM.commit(); } gEM.commit(); dur = (MonoTime.currTime - time).total!"usecs"; writeln("Components removing: ", dur, " usecs"); Mallocator.instance.dispose(entities); time = MonoTime.currTime; gEM.begin(); //gEM.updateMT(); gEM.update(); gEM.end(); dur = (MonoTime.currTime - time).total!"usecs"; writeln("Update: ", dur, " usecs"); writeEntityComponents(gEM.getEntity(entity2.id)); time = MonoTime.currTime; gEM.begin(); gEM.updateMT(); //gEM.update(); gEM.end(); dur = (MonoTime.currTime - time).total!"usecs"; writeln("Update: ", dur, " usecs"); writeEntityComponents(gEM.getEntity(entity2.id)); time = MonoTime.currTime; gEM.begin(); gEM.updateMT(); //gEM.update(); gEM.end(); dur = (MonoTime.currTime - time).total!"usecs"; writeln("Update: ", dur, " usecs"); writeEntityComponents(gEM.getEntity(entity2.id)); entity = gEM.addEntity(tmpl); gEM.begin(); gEM.update(); gEM.end(); //Entity* pp;// = gEM.getEntity(entity.id); //writeln((cast(uint*) pp)[0 .. 14], " ", pp); writeEntityComponents(gEM.getEntity(entity.id)); gEM.addEntity(tmpl); gEM.addComponents(entity.id, TestComp4()); gEM.addComponents(entity.id, TestComp3()); gEM.begin(); gEM.update(); gEM.end(); writeEntityComponents(gEM.getEntity(entity.id)); gEM.removeComponents!(TestComp)(entity.id); gEM.addComponents(entity.id, TestComp()); gEM.addComponents(entity.id, TestComp5()); gEM.begin(); gEM.update(); gEM.update("fixed"); gEM.end(); gEM.removeComponents!(TestComp4)(entity.id); gEM.commit();//*/ writeEntityComponents(gEM.getEntity(entity.id)); //import std.stdio; //writeln((cast(uint*)tmpl.info.first_block)[0..48]); gEM.freeTemplate(tmpl); gEM.freeTemplate(tmpl2); EntityManager.destroy(); return 0; }