From 00028523035da8aa07002beba58497c0375a10cb Mon Sep 17 00:00:00 2001 From: Mergul Date: Wed, 17 Nov 2021 15:22:13 +0100 Subject: [PATCH] Added CAPI files I forgot to add CAPI files to .gitignore with previous commits :/ --- .gitignore | 6 +- c-api/becs.h | 207 ++++++++++ c-api/manager.d | 306 ++++++++++++++ c-api/test.c | 1051 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1569 insertions(+), 1 deletion(-) create mode 100644 c-api/becs.h create mode 100644 c-api/manager.d create mode 100644 c-api/test.c diff --git a/.gitignore b/.gitignore index e0e6fff..eae1286 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,8 @@ !compile_wasm.py !compile_android.py !.gitlab-ci.yml -!LICENSE \ No newline at end of file +!LICENSE +!c-api +!c-api/*.h +!c-api/*.d +!c-api/*.c \ No newline at end of file diff --git a/c-api/becs.h b/c-api/becs.h new file mode 100644 index 0000000..2a2bca0 --- /dev/null +++ b/c-api/becs.h @@ -0,0 +1,207 @@ +#ifndef __BECS__ +#define __BECS__ + +#include +#include +#include +#include + +typedef struct BECSSystem +{ + +}BECSSystem; + +typedef struct BECSArray +{ + size_t size; + void* ptr; +}BECSArray; + +typedef struct EntityID +{ + ///Index to entity in IDManager. + uint32_t id; + ///Counter required for reusing ID. + uint32_t counter; +}EntityID; + +typedef struct Entity +{ + ///Entity ID. + EntityID id; +}Entity; + +typedef struct ComponentRef +{ + ///pointer to component + void* ptr; + ///component index + uint16_t id; +}ComponentRef; + +typedef ComponentRef EventRef; + +typedef struct BECSComponentInfo +{ + ///Component size + uint16_t size; + ///Component data alignment + uint16_t alignment; + ///Initialization data + BECSArray init_data; + ///Pointer to component destroy callback + void* destroy_callback; + ///Pointer to component create callback + void* create_callback; + //void* create_callback; +}BECSComponentInfo; + +typedef struct BECSEventRegisterInfo +{ + ///Component size + uint16_t size; + ///Component data alignment + uint16_t alignment; +}BECSEventRegisterInfo; + +typedef struct EntityTemplate +{ + /*///Entity components data + BECSArray entity_data; + ///Pointer to entity type info. + void* info;*/ +}EntityTemplate; + +enum BECSSystemComponentAttribute +{ + required = 0, + optional = 1, + excluded = 2 +}; + +enum BECSSystemComponentAccess +{ + writable = 0, + readonly = 1 +}; + +typedef struct BECSSystemComponentInfo +{ + uint16_t id; + enum BECSSystemComponentAttribute attribute; + enum BECSSystemComponentAccess access; +}BECSSystemComponentInfo; + +///C-API structure conatin only subset of real data which can be accessed directly. Component arrays can be retrived using function calls. +typedef struct BECSListenerCallData +{ + uint32_t count; + void* context; +}BECSListenerCallData; + +///C-API structure conatin only subset of real data which can be accessed directly. Component arrays can be retrived using function calls. +typedef struct BECSSystemCallData +{ + uint32_t count; + uint32_t thread_id; + uint32_t job_id; + void* context; +}BECSSystemCallData; + +///C-API structure conatin only subset of real data which can be accessed directly. Component arrays can be retrived using function calls. +typedef struct BECSEventCallData +{ + Entity* entity; + void* event; + void* context; +}BECSEventCallData; + +typedef struct BECSEventCallback +{ + uint16_t id; + void (*callback)(BECSEventCallData* data); +}BECSEventCallback; + +typedef struct BECSSystemRegisterInfo +{ + uint32_t pass_id; + int32_t priority; + uint32_t max_jobs; + + size_t components_count; + BECSSystemComponentInfo* components; + + size_t event_handlers_count; + BECSEventCallback* event_handlers; + + size_t system_size; + void* init_data; + + void (*on_update)(BECSSystemCallData* call_data); + void (*on_create)(void* system_pointer); + void (*on_destroy)(void* system_pointer); + void (*on_enable)(void* system_pointer); + void (*on_disable)(void* system_pointer); + char (*on_begin)(void* system_pointer); + void (*on_end)(void* system_pointer); + void (*on_add_entity)(BECSListenerCallData*); + void (*on_remove_entity)(BECSListenerCallData*); + void (*on_change_entity)(BECSListenerCallData*); + void (*filter_entity)(void* system_pointer, void* info); +}BECSSystemRegisterInfo; + +void becsInitialize(); +void becsDestroy(); + +void becsBeginRegister(); +void becsEndRegister(); + +void becsBegin(); +void becsEnd(); +void becsCommit(); + +void becsUpdate(uint16_t pass_id); +void becsUpdateMT(uint16_t pass_id); + +uint16_t becsRegisterComponent(const char* name, BECSComponentInfo info); +uint16_t becsRegisterEvent(const char* name, BECSEventRegisterInfo info); +uint16_t becsRegisterSystem(const char* name, BECSSystemRegisterInfo info); +uint16_t becsRegisterPass(const char* name); + +Entity* becsAddEntity(EntityTemplate* template); +Entity* becsAddEntityCopy(EntityID id); +void becsRemoveEntity(EntityID id); + +Entity* becsGetEntity(EntityID id); + +void becsAddComponents(const EntityID entity_id, size_t length, ComponentRef* comps); +void becsRemoveComponents(const EntityID entity_id, size_t length, uint16_t* comps); + +EntityTemplate* becsAllocateTemplate(uint32_t count, uint16_t* components); +EntityTemplate* becsAllocateTemplateFromEntity(EntityID id, uint8_t fill_default); +EntityTemplate* becsAllocateTemplateCopy(EntityTemplate* tmpl); +EntityTemplate* becsAllocateTemplateFromTemplate(EntityTemplate* tmpl, size_t new_count, uint16_t* components, size_t remove_count, uint16_t* remove_components); +void becsFreeTemplate(EntityTemplate* tmpl); + +void* becsEntityGetComponent(Entity* entity, uint16_t component_id); + +void* becsSystemCallDataGetComponentArray(BECSSystemCallData* data, uint16_t component_id); +Entity* becsSystemCallDataGetEntitiesArray(BECSSystemCallData* data); + +void* becsListenerCallDataGetComponentArray(BECSListenerCallData* data, uint16_t component_id); +Entity* becsListenerCallDataGetEntitiesArray(BECSListenerCallData* data); + +void becsCallEntitiesFunction(uint16_t system_id, void (*on_update)(BECSSystemCallData* call_data), void* context); + +void becsSendEvent(EntityID id, EventRef event); + +#define BECS_REGISTER_COMPONENT(comp) \ + ({ \ + void* mem_ptr = malloc(sizeof(comp)); \ + memcpy(mem_ptr, &comp, sizeof(comp)); \ + becsRegisterComponent(#comp, (BECSComponentInfo){sizeof(comp), alignof(comp), (BECSArray){sizeof(comp), mem_ptr}, 0, 0}); \ + }) + + //BECSComponentInfo(sizeof(comp), 4, 0, 0, 0)); + +#endif //__BECS__ \ No newline at end of file diff --git a/c-api/manager.d b/c-api/manager.d new file mode 100644 index 0000000..e109f1d --- /dev/null +++ b/c-api/manager.d @@ -0,0 +1,306 @@ +module manager; + +import bubel.ecs.manager; +import bubel.ecs.entity; +import bubel.ecs.events; +import bubel.ecs.system; +import bubel.ecs.std; + +import core.stdc.string; + +extern (C): +/* +struct BECSComponentInfo +{ + ///Component size + ushort size; + ///Component data alignment + ushort alignment; + ///Initialization data + ubyte[] init_data; + ///Pointer to component destroy callback + void* destroy_callback; + ///Pointer to component create callback + void* create_callback; + //void* create_callback; +}*/ + +alias BECSComponentInfo = EntityManager.ComponentInfo; +// alias BECSEventCallData = EntityManager.EventCallData; + +enum BECSSystemComponentAttribute +{ + required = 0, + optional = 1, + excluded = 2 +} + +enum BECSSystemComponentAccess +{ + writable = 0, + readonly = 1 +} + +struct BECSSystemComponentInfo +{ + ushort id; + BECSSystemComponentAttribute attribute; + BECSSystemComponentAccess access; +} + +struct BECSEventCallback +{ + ushort id; + void function(EntityManager.EventCallData* data) callback; +} + +struct BECSSystemRegisterInfo +{ + uint pass_id; + int priority; + uint max_jobs; + + BECSSystemComponentInfo[] components; + BECSEventCallback[] event_handlers; + + byte[] init_data; + + void function(EntityManager.SystemCallData* call_data) on_update; + void function(void* system_pointer) on_create; + void function(void* system_pointer) on_destroy; + void function(void* system_pointer) on_enable; + void function(void* system_pointer) on_disable; + bool function(void* system_pointer) on_begin; + void function(void* system_pointer) on_end; + void function(EntityManager.ListenerCallData*) on_add_entity; + void function(EntityManager.ListenerCallData*) on_remove_entity; + void function(EntityManager.ListenerCallData*) on_change_entity; + void function(void* system_pointer, EntityManager.EntityInfo* info) filter_entity; +} + +alias BECSEventRegisterInfo = EntityManager.EventRegisterInfo; + +void becsInitialize() +{ + EntityManager.initialize(); +} + +void becsDestroy() +{ + EntityManager.destroy(); +} + +void becsBeginRegister() +{ + gEntityManager.beginRegister(); +} + +void becsEndRegister() +{ + gEntityManager.endRegister(); +} + +void becsBegin() +{ + gEntityManager.begin(); +} + +void becsEnd() +{ + gEntityManager.end(); +} + +void becsCommit() +{ + gEntityManager.commit(); +} + +void becsUpdate(ushort pass_id) +{ + gEntityManager.update(pass_id); +} + +void becsUpdateMT(ushort pass_id) +{ + gEntityManager.update(pass_id); +} + +ushort becsRegisterPass(const (char)* name) +{ + return gEntityManager.registerPass(name[0 .. strlen(name)]); +} + +ushort becsRegisterComponent(const(char)* name, BECSComponentInfo info) +{ + return gEntityManager.registerComponent(name[0 .. strlen(name)], info); +} + +ushort becsRegisterEvent(const(char)* name, BECSEventRegisterInfo info) +{ + return gEntityManager.registerEvent(name[0 .. strlen(name)], info); +} + +ushort becsRegisterSystem(const(char)* name, BECSSystemRegisterInfo info) +{ + System system; + + if(info.init_data.length) + { + system.m_system_pointer = malloc(info.init_data.length); + memcpy(system.m_system_pointer, info.init_data.ptr, info.init_data.length); + } + + if(info.event_handlers.length) + { + system.m_event_callers = Mallocator.makeArray!(System.EventCaller)(info.event_handlers.length); + foreach(i, BECSEventCallback callback; info.event_handlers) + { + system.m_event_callers[i].id = callback.id; + system.m_event_callers[i].callback = callback.callback; + } + } + + system.m_update = info.on_update; + system.m_create = info.on_create; + system.m_destroy = info.on_destroy; + system.m_enable = info.on_enable; + system.m_disable = info.on_disable; + system.m_begin = info.on_begin; + system.m_end = info.on_end; + system.m_add_entity = info.on_add_entity; + system.m_remove_entity = info.on_remove_entity; + system.m_change_entity = info.on_change_entity; + system.m_filter_entity = info.filter_entity; + + if(info.components.length) + { + uint req; + uint opt; + foreach(comp; info.components) + { + if(comp.attribute == BECSSystemComponentAttribute.required)req++; + else if(comp.attribute == BECSSystemComponentAttribute.optional)opt++; + } + if(req)system.m_components = Mallocator.makeArray!ushort(req); + if(opt)system.m_optional_components = Mallocator.makeArray!ushort(opt); + req = 0; + opt = 0; + foreach(comp; info.components) + { + if(comp.attribute == BECSSystemComponentAttribute.required) + { + system.m_components[req++] = comp.id; + } + else if(comp.attribute == BECSSystemComponentAttribute.optional) + { + system.m_optional_components[opt++] = comp.id; + } + } + } + else + { + system.m_empty = true; + } + return gEntityManager.registerSystem(name[0 .. strlen(name)], system); +} + +EntityTemplate* becsAllocateTemplate(uint count, ushort* components) +{ + return gEntityManager.allocateTemplate(components[0 .. count]); +} + +EntityTemplate* becsAllocateTemplateFromEntity(EntityID id, bool fill_default) +{ + return gEntityManager.allocateTemplate(id, fill_default); +} + +EntityTemplate* becsAllocateTemplateCopy(EntityTemplate* tmpl) +{ + return gEntityManager.allocateTemplate(tmpl); +} + +EntityTemplate* becsAllocateTemplateFromTemplate(EntityTemplate* tmpl, size_t new_count, ushort* components, size_t remove_count, ushort* remove_components) +{ + return gEntityManager.allocateTemplate(tmpl, components[0 .. new_count], remove_components[0 .. remove_count]); +} + +void becsFreeTemplate(EntityTemplate* tmpl) +{ + gEntityManager.freeTemplate(tmpl); +} + +Entity* becsAddEntity(EntityTemplate* tmpl) +{ + return gEntityManager.addEntity(tmpl); +} + +Entity* becsAddEntityCopy(EntityID id) +{ + return gEntityManager.addEntityCopy(id); +} + +void becsRemoveEntity(EntityID id) +{ + gEntityManager.removeEntity(id); +} + +Entity* becsGetEntity(EntityID id) +{ + return gEntityManager.getEntity(id); +} + +void* becsEntityGetComponent(Entity* entity, ushort component_id) +{ + return entity.getComponent(component_id); +} + +void* becsSystemCallDataGetComponentArray(EntityManager.SystemCallData* data, ushort component_id) +{ + if(data.info.deltas.length <= component_id || data.info.deltas[component_id] == 0)return null; + return cast(void*)data.block + data.info.deltas[component_id]; +} + +Entity* becsSystemCallDataGetEntitiesArray(EntityManager.SystemCallData* data) +{ + return cast(Entity*)data.block.dataBegin(); +} + +void* becsListenerCallDataGetComponentArray(EntityManager.ListenerCallData* data, ushort component_id) +{ + if(data.info.deltas.length <= component_id || data.info.deltas[component_id] == 0)return null; + return cast(void*)data.block + data.info.deltas[component_id]; +} + +Entity* becsListenerCallDataGetEntitiesArray(EntityManager.ListenerCallData* data) +{ + return cast(Entity*)data.block.dataBegin(); +} + +void becsCallEntitiesFunction(ushort system_id, void function(EntityManager.SystemCallData*) callback, void* context) +{ + System* system = gEntityManager.getSystem(system_id); + + if (!system.m_any_system_caller) + return; + + foreach (info; system.m_any_system_caller.infos) + { + EntityManager.CallData data = EntityManager.CallData(system.id, system, info, context, cast(void*)callback); + data.update(); + } +} + +void becsAddComponents(const EntityID entity_id, ComponentRef[] comps) +{ + gEntityManager.addComponents(entity_id, comps); +} + +void becsRemoveComponents(const EntityID entity_id, ushort[] comps) +{ + gEntityManager.removeComponents(entity_id, comps); +} + +void becsSendEvent(EntityID id, EventRef event) +{ + gEntityManager.sendEvent(id, event); +} \ No newline at end of file diff --git a/c-api/test.c b/c-api/test.c new file mode 100644 index 0000000..c6b1246 --- /dev/null +++ b/c-api/test.c @@ -0,0 +1,1051 @@ +#include "becs.h" +#include +#include + +uint32_t getID() +{ + return 0; +} + +long getUSecTime() +{ + //time_t time; + struct timespec spec; + + clock_gettime(CLOCK_REALTIME, &spec); + + //time = spec.tv_sec; + return spec.tv_sec * 1000000 + spec.tv_nsec / 1000; //time / 1000_000; +} + +typedef struct TestEvent +{ + int32_t a; +}TestEvent; +static uint16_t TestEventID; + +typedef struct TestEvent2 +{ + float a; +}TestEvent2; +static uint16_t TestEvent2ID; + +typedef struct +{ + float x,y; +}CLocation; +static uint16_t CLocationID; + +typedef struct +{ + float x,y; +}CVelocity; +static uint16_t CVelocityID; + +typedef struct TestComp +{ + int32_t a;// = 1; + uint64_t b;// = 2; +}TestComp; +static uint16_t TestCompID; + +typedef struct TestComp2 +{ + int32_t b;// = 3; + int32_t a;// = 4; +}TestComp2; +static uint16_t TestComp2ID; + +typedef struct TestComp3 +{ + uint32_t gg;// = 5; //good game + uint32_t bg;// = 6; //bad game +}TestComp3; +static uint16_t TestComp3ID; + +typedef struct TestComp4 +{ + uint32_t gg;// = 7; //good game + uint32_t bg;// = 8; //bad game + uint64_t a;// = 9; + uint64_t b;// = 10; + uint64_t c;// = 11; + uint64_t g;// = 12; +}TestComp4; +static uint16_t TestComp4ID; + +typedef struct TestComp5 +{ + uint32_t gg;// = 7; //good game + uint32_t bg;// = 8; //bad game + uint64_t a;// = 9; + uint64_t b;// = 10; + uint64_t c;// = 11; + uint64_t g;// = 12; +}TestComp5; +static uint16_t TestComp5ID; + +typedef struct CPosition +{ + float x; + float y; +}CPosition; +static uint16_t CPositionID; + +void onUpdateTest(BECSSystemCallData* call_data) +{ + CLocation* location = (CLocation*)becsSystemCallDataGetComponentArray(call_data, CLocationID); + CVelocity* velocity = (CVelocity*)becsSystemCallDataGetComponentArray(call_data, CVelocityID); + //if(velocity != NULL)exit(0); + for(int i=0; icount; i++) + { + location[i].y += 10; + if(velocity)velocity[i].x += 1; + } + printf("To jest printf z systemu!\n"); +} +/* +struct EverySystem +{ + struct EntitiesData + { + uint length; + Entity[] entity; + CPosition[] pos; + } + + +};*/ + +void EverySystemFree(BECSSystemCallData* call_data) +{ + Entity* entity = becsSystemCallDataGetEntitiesArray(call_data); + for(int i=0; icount; i++) + { + becsRemoveEntity(entity[i].id); + } +} + +void EverySystemAddOne(BECSSystemCallData* call_data) +{ + Entity* entity = becsSystemCallDataGetEntitiesArray(call_data); + TestComp2 comp2 = {3, 4}; + ComponentRef ref = {&comp2, TestComp2ID}; + + for(int i=0; icount; i++) + { + becsAddComponents(entity[i].id, 1, &ref); + ///gEntityManager.addComponents(data.entity[i].id, TestComp2()); + } +} + +void EverySystemOnUpdate(BECSSystemCallData* call_data) +{ + //CLocation* location = (CLocation*)becsSystemCallDataGetComponentArray(call_data, CLocationID); + CPosition* pos = (CPosition*)becsSystemCallDataGetComponentArray(call_data, CPositionID); + + for(int i=0; icount; i++) + { + pos[i].x++; + pos[i].y++; + } +}; + +void EverySystemIterate(BECSSystemCallData* call_data) +{ + //CLocation* location = (CLocation*)becsSystemCallDataGetComponentArray(call_data, CLocationID); + CPosition* pos = (CPosition*)becsSystemCallDataGetComponentArray(call_data, CPositionID); + + for(int i=0; icount; i++) + { + pos[i].x++; + pos[i].y++; + } +}; + +/* +struct ChangeTestSystem +{ + mixin ECS.System!16; //__gshared ushort system_id; + + static struct EntitiesData + { + size_t length; + const(Entity)[] entites; + TestComp4[] test4; + @optional TestComp5[] test5; + } + + +}*/ + +void ChangeTestSystemOnCreate() +{ + //writeln("On Change Test System create."); + printf("On Change Test System create.\n"); +} + +void ChangeTestSystemOnDestroy() +{ + //writeln("On Change Test System destroy."); + printf("On Change Test System destroy.\n"); +} + +void ChangeTestSystemOnAddEntity(BECSListenerCallData* call_data) +{ + Entity* entities = becsListenerCallDataGetEntitiesArray(call_data); + //printf("Entity added! ID: "); + for(int i=0; icount; i++) + printf("Entity added! ID: %u\n",(uint32_t) entities[i].id.id); + ////writeln("Entity added! ID: ", entities[i].id); +} + +void ChangeTestSystemOnRemoveEntity(BECSListenerCallData* call_data) +{ + Entity* entities = becsListenerCallDataGetEntitiesArray(call_data); + ////writeln("Entity removed! ID: ", entities[0].id); + printf("Entity removed! ID: %u\n",(uint32_t) entities[0].id.id); +} + +void ChangeTestSystemOnChangeEntity(BECSListenerCallData* call_data) +{ + Entity* entities = becsListenerCallDataGetEntitiesArray(call_data); + ////writeln("Entity changed! ID: ", entities[0].id); + printf("Entity changed! ID: %u\n",(uint32_t) entities[0].id.id); +} + +char ChangeTestSystemOnBegin(void* context) +{ + ////writeln("On Test System begin."); + return 1; +} + +void ChangeTestSystemOnEnd(void* context) +{ + ////writeln("On Test System end."); +} + +void ChangeTestSystemOnUpdate(BECSSystemCallData* call_data) +{ + /*for(int i=0; icount; i++) + { + + }*/ +} + +uint16_t ChangeTestSystemID; + + +typedef struct TestSystem +{ + uint32_t print; + + /* + + 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 handleEvent(TestEvent event, ref TestComp test, ref TestComp2 test2, TestComp3* test3) + { + + }*/ +}TestSystem; + +void TestSystemOnCreate(void* context) +{ + //writeln("On Test System create."); + printf("On Change Test System create.\n"); +} + +void TestSystemOnDestroy(void* context) +{ + //writeln("On Test System destroy."); + printf("On Change Test System destroy.\n"); +} + +void TestSystemOnAddEntity(BECSListenerCallData* call_data) +{ + //foreach(i;0..data.length) + ////writeln("Entity added ID: ",data.entites[i].id.id); +} + +void TestSystemOnRemoveEntity(BECSListenerCallData* call_data) +{ + ////writeln("Entity destroyed ID: ",data.entites[0].id); +} + +char TestSystemOnBegin(void* context) +{ + TestSystem* system = (TestSystem*)context; + if(system->print)printf("On Test System begin.\n"); + return 1; +} + +void TestSystemOnEnd(void* context) +{ + TestSystem* system = (TestSystem*)context; + if(system->print)printf("On Test System end.\n"); + system->print = 0; +} + +void TestSystemOnUpdate(BECSSystemCallData* call_data) +{ + TestComp* test = (TestComp*)becsSystemCallDataGetComponentArray(call_data, TestCompID); + TestComp2* test2 = (TestComp2*)becsSystemCallDataGetComponentArray(call_data, TestComp2ID); + for(int i=0; icount; i++) + { + test[i].a += 1000; + test[i].b += 2000; + test2[i].b += 2; + test2[i].a = 8; + } +} + +uint16_t TestSystemID; + +/* +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 TestSystemWithHighPriorityOnUpdate(BECSSystemCallData* call_data) +{ + +} + +uint16_t TestSystemWithHighPriorityID; + +/* +struct Sys1 +{ + mixin ECS.System; + + struct EntitiesData + { + TestComp[] comp; + } +}*/ + +void Sys1OnAddEntity(BECSListenerCallData* call_data) +{ + +} + +uint16_t Sys1ID; +/* +struct Sys2 +{ + mixin ECS.System; + + struct EntitiesData + { + TestComp[] comp; + } +}*/ + +void Sys2OnAddEntity(BECSListenerCallData* call_data) +{ + +} + +uint16_t Sys2ID; +/* +struct Sys3 +{ + mixin ECS.System; + + struct EntitiesData + { + TestComp[] comp; + } +}*/ + +void Sys3OnAddEntity(BECSListenerCallData* call_data) +{ + +} + +void Sys3OnUpdate(BECSSystemCallData* call_data) +{ + +} + +uint16_t Sys3ID; + + +typedef struct EmptyEventSystem +{ + char handled; +}EmptyEventSystem; + +void EmptyEventSystemHandleEvent(BECSEventCallData* call_data) +{ + //TestEvent* event = (TestEvent*)call_data->event; + EmptyEventSystem* context = (EmptyEventSystem*)call_data->context; + if (!context->handled) + { + printf("EmptyEventSystem.handleEvent() called!\n"); + context->handled = 1; + } + exit(0);//assert(0, "this shouldn't be called!"); +} + +uint16_t EmptyEventSystemID; + + +typedef struct EventSystem +{ + char handled; + + /*struct EntitiesData + { + uint thread_id; + TestComp[] comp; + }*/ +}EventSystem; + +void EventSystemHandleTestEvent(BECSEventCallData* call_data) +{ + //TestEvent* event = (TestEvent*)call_data->event; + EmptyEventSystem* context = (EmptyEventSystem*)call_data->context; + if (!context->handled) + { + printf("EventSystem.handleEvent() called!\n"); + context->handled = 1; + } +} + +uint16_t EventSystemID; + +/* +struct EmptySystem +{ + mixin ECS.System; + + struct EntitiesData + { + uint thread_id; + } +}*/ + +void EmptySystemOnUpdate(BECSSystemCallData* call_data) +{ + printf("EmptySystem.onUpdate() - this should be called once per update\n"); +} + +uint16_t EmptySystemID; + +/* +import std.meta; + +struct TestSystem2 +{ + mixin ECS.System!16; //__gshared ushort system_id; + + //alias ExcludedComponents = AliasSeq!("TestComp", "TestComp4"); + + static struct EntitiesData + { + short length; + const(Entity)[] entity; + TestComp3[] test; + //@excluded TestComp[] testt; + } + + static struct EventInput + { + Entity* entity; + TestComp3* test; + //TestComp* tt; + } + + void initialize(ref Entity entity, ref TestComp comp) + { + + } + + void lateUpdate(ref BECSSystemCallData* call_data) + { + for(int i=0;icount;i++) + { + data.test[i].gg -= 1; + //gEntityManager.sendSelfEvent!(TestEvent)(data.entity[i].id, TestEvent()); + } + } + +} +*/ + +void TestSystem2HandleEvent(BECSEventCallData* call_data) +{ + Entity* entity = call_data->entity; + TestEvent* event = (TestEvent*)call_data->event; + EmptyEventSystem* context = (EmptyEventSystem*)call_data->context; + + TestComp3* test = (TestComp3*)becsEntityGetComponent(entity, TestComp3ID); + test->bg = event->a; + TestEvent2 event2; + event2.a = event->a + 8; + becsSendEvent(entity->id, (EventRef){&event2, TestEvent2ID}); +} + +void TestSystem2HandleEvent2(BECSEventCallData* call_data) +{ + Entity* entity = call_data->entity; + TestEvent2* event = (TestEvent2*)call_data->event; + EmptyEventSystem* context = (EmptyEventSystem*)call_data->context; + + TestComp3* test = (TestComp3*)becsEntityGetComponent(entity, TestComp3ID); + test->gg =(uint32_t) event->a; +} + +void TestSystem2OnEnable() +{ + + //writeln("TestSystem2 enabled"); + printf("TestSystem2 enabled\n"); +} + +void TestSystem2OnDisable() +{ + + //writeln("TestSystem2 disabled"); + printf("TestSystem2 disabled\n"); +} + +void TestSystem2OnUpdate(BECSSystemCallData* call_data) +{ + TestComp3* test = (TestComp3*)becsSystemCallDataGetComponentArray(call_data, TestComp3ID); + Entity* entity = becsSystemCallDataGetEntitiesArray(call_data); + for(int i=0;icount;i++) + { + test[i].gg += 14; + TestEvent event; + event.a = test[i].gg + 4; + becsSendEvent(entity[i].id, (EventRef){&event, TestEventID}); + //gEntityManager.sendEvent!(TestEvent)(data.entity[i].id, event); + //gEntityManager.sendSelfEvent!(TestEvent)(data.entity[i].id, TestEvent()); + } +} + +uint16_t TestSystem2ID; + +typedef struct ExternalUpdateCallTest +{ + int print_count;// = 3 +}ExternalUpdateCallTest; + +void ExternalUpdateCallTestUpdate(BECSSystemCallData* call_data) +{ + TestComp3* test = becsSystemCallDataGetComponentArray(call_data, TestComp3ID); + ExternalUpdateCallTest* context = (ExternalUpdateCallTest*)call_data->context; + + if (context->print_count > 0) + { + context->print_count--; + printf("ExternalUpdateCallTest %u %u\n", test[0].gg,(uint32_t) call_data->count); + } +} + +static uint16_t EverySystemID; + +void writeEntityComponents(Entity* entity) +{ + + printf("EntityID(%u, %u)", (uint32_t) entity->id.id, (uint32_t) entity->id.counter); + //write(entity->id); + TestComp* test_comp = (TestComp*)becsEntityGetComponent(entity, TestCompID);//.getComponent!TestComp; + if (test_comp) + printf("TestComp(%u, %u)", (uint32_t) test_comp->a, (uint32_t) test_comp->b); //write(*test_comp); + TestComp2* test_comp2 = (TestComp2*)becsEntityGetComponent(entity, TestComp2ID);//.getComponent!TestComp2; + if (test_comp2) + printf("TestComp2(%u, %u)", (uint32_t) test_comp2->b, (uint32_t) test_comp2->a); //write(*test_comp2); + TestComp3* test_comp3 = (TestComp3*)becsEntityGetComponent(entity, TestComp3ID);//.getComponent!TestComp3; + if (test_comp3) + printf("TestComp3(%u, %u)", (uint32_t) test_comp3->gg, (uint32_t) test_comp3->bg); //write(*test_comp3); + TestComp4* test_comp4 = (TestComp4*)becsEntityGetComponent(entity, TestComp4ID);//.getComponent!TestComp4; + if (test_comp4) + printf("TestComp4(%u, %u, %u, %u, %u, %u)", test_comp4->gg, test_comp4->bg, + (uint32_t) test_comp4->a, (uint32_t) test_comp4->b, + (uint32_t) test_comp4->c, (uint32_t) test_comp4->g); //write(*test_comp4); + printf("\n"); + //writeln(); + ////writeln(((uint32_t*) pp)[0 .. 14], " ", pp); +} + +int main() +{ + becsInitialize(); + //gEntityManager.setMultithreadingCallbacks(&dispatch, &getID); + + becsBeginRegister(); + uint16_t fixed_pass = becsRegisterPass("fixed"); + + long time = getUSecTime(); + + TestComp2 test_comp2 = {3,4}; + TestComp2ID = BECS_REGISTER_COMPONENT(test_comp2); + TestComp4 test_comp4 = {7,8,9,10,11,12}; + TestComp4ID = BECS_REGISTER_COMPONENT(test_comp4); + TestComp test_comp = {1,2}; + TestCompID = BECS_REGISTER_COMPONENT(test_comp); + TestComp3 test_comp3 = {5,6}; + TestComp3ID = BECS_REGISTER_COMPONENT(test_comp3); + TestComp5 test_comp5 = {7,8,9,10,11,12}; + TestComp5ID = BECS_REGISTER_COMPONENT(test_comp5); + CPosition position = {0,0}; + CPositionID = BECS_REGISTER_COMPONENT(position); + + CLocation loc = {10,12.2}; + CLocationID = BECS_REGISTER_COMPONENT(loc); + CVelocity vel = {1,2.6}; + CVelocityID = BECS_REGISTER_COMPONENT(vel); + + TestEventID = becsRegisterEvent("TestEvent", (BECSEventRegisterInfo){sizeof(TestEvent), alignof(TestEvent)}); + TestEvent2ID = becsRegisterEvent("TestEvent2", (BECSEventRegisterInfo){sizeof(TestEvent2), alignof(TestEvent2)}); + + printf("Components register: %f usecs\n", (float)(getUSecTime() - time)); + time = getUSecTime(); + + /*{ + BECSSystemComponentInfo array[] = {(BECSSystemComponentInfo){0}}; + BECSSystemRegisterInfo register_info; + register_info.components_count = 1; + register_info.components = array; + register_info.on_update = onUpdateTest; + becsRegisterSystem("System", register_info); + }*/ + + { + BECSSystemComponentInfo array[] = {(BECSSystemComponentInfo){TestCompID}}; + BECSSystemRegisterInfo register_info = {}; + register_info.priority = 100; + register_info.components_count = 1; + register_info.components = array; + register_info.pass_id = fixed_pass; + register_info.on_update = TestSystemWithHighPriorityOnUpdate; + TestSystemWithHighPriorityID = becsRegisterSystem("TestSystemWithHighPriority", register_info); + } + + { + BECSSystemComponentInfo array[] = { + (BECSSystemComponentInfo){TestCompID}, + (BECSSystemComponentInfo){TestComp2ID}, + (BECSSystemComponentInfo){TestComp3ID,optional}}; + BECSSystemRegisterInfo register_info = {}; + register_info.priority = 0; + register_info.system_size = sizeof(TestSystem); + register_info.init_data = &(TestSystem){1}; + register_info.components_count = 3; + register_info.components = array; + register_info.on_create = TestSystemOnCreate; + register_info.on_destroy = TestSystemOnDestroy; + register_info.on_add_entity = TestSystemOnAddEntity; + register_info.on_update = TestSystemOnUpdate; + register_info.on_begin = TestSystemOnBegin; + register_info.on_end = TestSystemOnEnd; + TestSystemID = becsRegisterSystem("TestSystem", register_info); + } + + { + BECSSystemComponentInfo array[] = { + (BECSSystemComponentInfo){TestComp4ID}, + (BECSSystemComponentInfo){TestComp5ID,optional}}; + BECSSystemRegisterInfo register_info = {}; + register_info.priority = 0; + register_info.components_count = 2; + register_info.components = array; + register_info.on_update = ChangeTestSystemOnUpdate; + register_info.on_create = ChangeTestSystemOnCreate; + register_info.on_destroy = ChangeTestSystemOnDestroy; + register_info.on_add_entity = ChangeTestSystemOnAddEntity; + register_info.on_remove_entity = ChangeTestSystemOnRemoveEntity; + register_info.on_change_entity = ChangeTestSystemOnChangeEntity; + register_info.on_begin = ChangeTestSystemOnBegin; + register_info.on_end = ChangeTestSystemOnEnd; + ChangeTestSystemID = becsRegisterSystem("ChangeTestSystem", register_info); + } + + { + BECSSystemComponentInfo array[] = {(BECSSystemComponentInfo){TestCompID}}; + BECSSystemRegisterInfo register_info= {}; + register_info.priority = 10; + register_info.components_count = 1; + register_info.components = array; + register_info.on_add_entity = Sys1OnAddEntity; + Sys1ID = becsRegisterSystem("Sys1", register_info); + } + + { + BECSSystemComponentInfo array[] = {(BECSSystemComponentInfo){TestCompID}}; + BECSSystemRegisterInfo register_info= {}; + register_info.priority = -100; + register_info.components_count = 1; + register_info.components = array; + register_info.on_add_entity = Sys2OnAddEntity; + Sys2ID = becsRegisterSystem("Sys2", register_info); + } + + { + BECSSystemComponentInfo array[] = {(BECSSystemComponentInfo){TestCompID}}; + BECSSystemRegisterInfo register_info= {}; + register_info.priority = -2; + register_info.components_count = 1; + register_info.components = array; + register_info.on_update = Sys3OnUpdate; + register_info.on_add_entity = Sys3OnAddEntity; + Sys3ID = becsRegisterSystem("Sys3", register_info); + } + + { + BECSSystemRegisterInfo register_info= {}; + register_info.priority = 2; + register_info.on_update = EmptySystemOnUpdate; + EmptySystemID = becsRegisterSystem("EmptySystem", register_info); + } + + { + BECSEventCallback event_array[] = {(BECSEventCallback){TestEventID, EmptyEventSystemHandleEvent}}; + BECSSystemRegisterInfo register_info= {}; + register_info.priority = 2; + register_info.system_size = sizeof(EmptyEventSystem); + register_info.init_data = &(EmptyEventSystem){}; + register_info.event_handlers_count = 1; + register_info.event_handlers = event_array; + EmptyEventSystemID = becsRegisterSystem("EmptyEventSystem", register_info); + } + + { + BECSEventCallback event_array[] = {(BECSEventCallback){TestEventID, EventSystemHandleTestEvent}}; + BECSSystemComponentInfo array[] = {(BECSSystemComponentInfo){TestCompID}}; + BECSSystemRegisterInfo register_info= {}; + register_info.priority = 2; + register_info.system_size = sizeof(EventSystem); + register_info.init_data = &(EventSystem){}; + register_info.components_count = 1; + register_info.components = array; + register_info.event_handlers_count = 1; + register_info.event_handlers = event_array; + EventSystemID = becsRegisterSystem("EventSystem", register_info); + } + + { + BECSSystemComponentInfo array[] = {(BECSSystemComponentInfo){CPositionID}}; + BECSSystemRegisterInfo register_info= {}; + register_info.priority = 0; + register_info.components_count = 1; + register_info.components = array; + register_info.on_update = EverySystemOnUpdate; + EverySystemID = becsRegisterSystem("EverySystem", register_info); + } + + becsEndRegister(); + + printf("Systems register: %f usecs\n", (float)(getUSecTime() - time)); + time = getUSecTime(); + + uint16_t ids[2] = {TestComp2ID, TestCompID}; + EntityTemplate* tmpl = becsAllocateTemplate(2, ids); + + uint16_t ids2[2] = {TestComp3ID, TestCompID}; + EntityTemplate* tmpl2 = becsAllocateTemplate(2, ids2); + + printf("Template allocating: %f usecs\n", (float)(getUSecTime() - time)); + time = getUSecTime(); + + uint16_t empty_ids[1] = {CPositionID}; + EntityTemplate* tmpl_empty = becsAllocateTemplate(1, empty_ids); + + becsCommit(); + + time = getUSecTime(); + for(int i = 0;i < 4000000; i++)becsAddEntity(tmpl_empty); + becsCommit(); + for(int i = 0;i < 4000000; i++)becsAddEntity(tmpl_empty); + becsCommit(); + for(int i = 0;i < 2000000; i++)becsAddEntity(tmpl_empty); + becsCommit(); + + printf("Adding 1M entities: %f usecs\n", (float)(getUSecTime() - time)); + + becsCommit(); + time = getUSecTime(); + becsCallEntitiesFunction(EverySystemID, EverySystemIterate, NULL); + printf("Iterate 1M entities: %f usecs\n", (float)(getUSecTime() - time)); + + becsBegin(); + time = getUSecTime(); + becsUpdate(0); + printf("Iterate 1M entities (update): %f usecs\n", (float)(getUSecTime() - time)); + becsEnd(); + + time = getUSecTime(); + becsCallEntitiesFunction(EverySystemID,EverySystemFree, NULL); + becsCommit(); + printf("Deleting 1M entities: %f usecs\n", (float)(getUSecTime() - time)); + + time = getUSecTime(); + for(int i = 0;i < 4000000; i++)becsAddEntity(tmpl_empty); + becsCommit(); + for(int i = 0;i < 4000000; i++)becsAddEntity(tmpl_empty); + becsCommit(); + for(int i = 0;i < 2000000; i++)becsAddEntity(tmpl_empty); + becsCommit(); + + printf("Adding 1M entities (prealloc): %f usecs\n", (float)(getUSecTime() - time)); + + becsCommit(); + time = getUSecTime(); + becsCallEntitiesFunction(EverySystemID, EverySystemAddOne, NULL); + becsCommit(); + printf("Adding 1M component: %f usecs\n", (float)(getUSecTime() - time)); + + becsCommit(); + becsCallEntitiesFunction(EverySystemID,EverySystemFree, NULL); + becsCommit(); + + time = getUSecTime(); + + EntityID entity; + + { + entity = becsAddEntity(tmpl)->id; + writeEntityComponents(becsGetEntity(entity)); + /*EntityManager.EntitiesBlock* block = gEntityManager.getMetaData( + gEntityManager.getEntity(entity)); + EntityManager.EntityInfo* info = block.type_info;*/ + //writeln(info.add_listeners); + //if(info)assert(0); + } + + time = getUSecTime(); + + //EntityID[] idss = Mallocator.makeArray!EntityID(5000); //[5000] + EntityID* idss = (EntityID*)malloc(sizeof(EntityID) * 5000); + + for (int i=0;i<200;i++) + { + becsBegin(); + for (int j=0;j<5000;j++) + idss[j] = becsAddEntity(tmpl)->id; + for (int j=0;j<5000;j++) + becsRemoveEntity(idss[j]); + becsEnd(); + } + becsCommit(); + + printf("Entities adding: %f usecs\n", (float)(getUSecTime() - time)); + free(idss); + time = getUSecTime(); + + uint32_t blocks = 0; + /*foreach (info; &gEntityManager.entities_infos.byValue) + { + EntityManager.EntitiesBlock* block = info.first_block; + while (block !is null) + { + block = block.next_block; + blocks++; + } + }*/ + //writeln("Entities blocks: ", blocks); + printf("Entities blocks: %u\n", blocks); + + becsBeginRegister(); + { + BECSEventCallback event_array[] = { + (BECSEventCallback){TestEventID, TestSystem2HandleEvent}, + (BECSEventCallback){TestEvent2ID, TestSystem2HandleEvent2}}; + BECSSystemComponentInfo array[] = {(BECSSystemComponentInfo){TestComp3ID}}; + BECSSystemRegisterInfo register_info; + register_info.priority = 0; + register_info.components_count = 1; + register_info.components = array; + register_info.event_handlers_count = 2; + register_info.event_handlers = event_array; + register_info.on_enable = TestSystem2OnEnable; + register_info.on_disable = TestSystem2OnDisable; + register_info.on_update = TestSystem2OnUpdate; + TestSystem2ID = becsRegisterSystem("TestSystem2", register_info); + } + becsEndRegister(); + + EntityID entity2; + + time = getUSecTime(); + + EntityID* entities = (EntityID*)malloc(sizeof(EntityID) * 1000000); + for (int i=0;i< 500000;i++) + { + entity2 = becsAddEntity(tmpl)->id; + entities[i * 2] = entity2; + entities[i * 2 + 1] = becsAddEntity(tmpl2)->id; + } + + becsCommit(); + + printf("Entities adding2: %f usecs\n", (float)(getUSecTime() - time)); + time = getUSecTime(); + + for (int i=0;i< 1000000;i++) + { + becsAddComponents(entities[i], 1, &(ComponentRef){&(TestComp5){7, 8, 9, 10, 11, 12}, TestComp5ID}); + if ((i & 0x00FFFF) == 0) + becsCommit(); + } + + becsCommit(); + + printf("Components adding: %f usecs\n", (float)(getUSecTime() - time)); + time = getUSecTime(); + + for (int i=0;i< 1000000;i++) + { + becsRemoveComponents(entities[i], 1, &TestComp5ID); + //if((i & 0x00FFFF) == 0)gEntityManager.commit(); + } + + becsCommit(); + printf("Components removing: %f usecs\n", (float)(getUSecTime() - time)); + time = getUSecTime(); + + free(entities); + + time = getUSecTime(); + + becsBegin(); + becsUpdate(0); + becsEnd(); + + printf("Update: %f usecs\n", (float)(getUSecTime() - time)); + + writeEntityComponents(becsGetEntity(entity2)); + + time = getUSecTime(); + + becsBegin(); + becsUpdateMT(0); + becsEnd(); + + printf("Update: %f usecs\n", (float)(getUSecTime() - time)); + + writeEntityComponents(becsGetEntity(entity2)); + + time = getUSecTime(); + + becsBegin(); + becsUpdate(0); + becsEnd(); + + printf("Update: %f usecs\n", (float)(getUSecTime() - time)); + + writeEntityComponents(becsGetEntity(entity2)); + + entity = becsAddEntity(tmpl)->id; + + becsBegin(); + becsUpdate(0); + becsEnd(); + + writeEntityComponents(becsGetEntity(entity)); + + becsAddEntity(tmpl); + writeEntityComponents(becsGetEntity(entity)); + writeEntityComponents(becsAddEntityCopy(entity)); + EntityTemplate* copy_tempalte = becsAllocateTemplateFromEntity(entity, 0); + writeEntityComponents(becsAddEntity(copy_tempalte)); + EntityTemplate* copy_default_tempalte = becsAllocateTemplateFromEntity(entity, 1); + writeEntityComponents(becsAddEntity(copy_default_tempalte)); + + becsAddComponents(entity, 1, &(ComponentRef){&(TestComp4){7,8,9,10,11,12},TestComp4ID}); + becsAddComponents(entity, 1, &(ComponentRef){&(TestComp3){5,6},TestComp3ID}); + + becsBegin(); + becsUpdate(0); + becsEnd(); + + writeEntityComponents(becsGetEntity(entity)); + + becsRemoveComponents(entity, 1, &TestCompID); + becsAddComponents(entity, 1, &(ComponentRef){&(TestComp){1,2},TestCompID}); + becsAddComponents(entity, 1, &(ComponentRef){&(TestComp5){7,8,9,10,11,12},TestComp5ID}); + + becsBegin(); + becsUpdate(0); + becsUpdate(fixed_pass); + becsEnd(); + + becsRemoveComponents(entity, 1, &TestComp4ID); + + becsCommit(); + + // BECSSystem* sys = (BECSSystem*)becsGetSystem(TestSystem2ID); + + ExternalUpdateCallTest external_update_test = {3}; + + becsCallEntitiesFunction(TestSystem2ID, ExternalUpdateCallTestUpdate, &external_update_test); + + printf("pre end\n"); + + writeEntityComponents(becsGetEntity(entity)); + becsFreeTemplate(tmpl_empty); + becsFreeTemplate(tmpl); + becsFreeTemplate(tmpl2); + becsFreeTemplate(copy_tempalte); + becsFreeTemplate(copy_default_tempalte); + becsDestroy(); + + printf("end\n"); + +/* + unsigned short components[1] = {CLocationID}; + EntityTemplate* template = becsAllocateTemplate(1, components); + unsigned short components2[2] = {CVelocityID, CLocationID}; + EntityTemplate* template2 = becsAllocateTemplate(2, components2); + Entity* entity = becsAddEntity(template); + Entity* entity2 = becsAddEntity(template2); + Entity* entity3 = becsAddEntity(template2); + printf("%lu\n", (unsigned long)entity); + entity = becsGetEntity(entity->id); + printf("%lu\n", (unsigned long)entity); + CLocation* location = (CLocation*)becsEntityGetComponent(entity, CLocationID); + printf("comp %f %f\n", location->x, location->y); + + entity2 = becsGetEntity(entity2->id); + CVelocity* velocity = (CVelocity*)becsEntityGetComponent(entity2, CVelocityID); + printf("compv %f %f\n", velocity->x, velocity->y); + + entity3 = becsGetEntity(entity3->id); + location = (CLocation*)becsEntityGetComponent(entity3, CLocationID); + printf("comp %f %f\n", location->x, location->y); + + becsBegin(); + becsUpdate(0); + becsEnd(); + printf("comp %f %f\n", location->x, location->y);*/ + return 0; +} \ No newline at end of file