module ecs.manager; import std.experimental.allocator.mallocator : Mallocator; import std.experimental.allocator; import std.traits; import ecs.system; import ecs.entity; alias gEM = EntityManager.instance; class EntityManager { static void initialize() { instance = Mallocator.instance.make!EntityManager; } void registerSystem(Sys)(int priority) { static void callUpdate(ref CallData data, void* entity) { static if(hasMember!(Sys,"update")) { Sys* s = cast(Sys*)data.system.system_pointer; s.update(); } } System system; static if(hasMember!(Sys,"update")) { system.update = &callUpdate; } system.system_pointer = cast(void*)Mallocator.instance.make!Sys; if(systems is null) { systems = Mallocator.instance.makeArray!System(1); systems[0] = system; } else { Mallocator.instance.expandArray(systems,1); systems[$-1] = system; } } void registerComponent(Comp)() { uint size = Comp.sizeof; ComponentInfo info; info.size = size; info.aligment = 8; if(components is null) { components = Mallocator.instance.makeArray!ComponentInfo(1); components[0] = info; } else { Mallocator.instance.expandArray(components,1); components[$-1] = info; } } void update() { foreach(ref system;systems) { if(system.update is null)continue; CallData call_data = CallData(&system,null); system.update(call_data,null); } } EntityTemplate* allocateTemplate(uint[] components_ids) { uint size = 0; foreach(id;components_ids) { size += components[id].size; } size += EntityID.sizeof; ubyte[] entity_data = Mallocator.instance.makeArray!ubyte(size); EntityTemplate* temp = Mallocator.instance.make!EntityTemplate; temp.components = components_ids; temp.entity = cast(Entity*)entity_data.ptr; return temp; } struct CallData { System* system; uint[] deltas; } struct ComponentInfo { int size; int aligment; } System[] systems; ComponentInfo[] components; __gshared EntityManager instance; }