diff --git a/dub.json b/dub.json index bebf2ff..4f1f32c 100755 --- a/dub.json +++ b/dub.json @@ -40,6 +40,38 @@ "-Hdimport/", "-op" ] + }, + { + "name" : "library-betterC", + "targetType" : "library", + "excludedSourceFiles":[ + "source\/win_dll.d" + ], + "dflags": [ + "-betterC", + "-defaultlib=" + ] + }, + { + "name" : "dynlib-betterC", + "targetType" : "dynamicLibrary", + "dflags": [ + "-betterC", + "-defaultlib=", + "--fvisibility=hidden" + ] + }, + { + "name" : "tests-betterC", + "targetType" : "executable", + "sourcePaths" : ["source\/","tests\/"], + "excludedSourceFiles":[ + "source\/win_dll.d" + ], + "dflags": [ + "-betterC", + "-defaultlib=" + ] } ] } \ No newline at end of file diff --git a/source/ecs/block_allocator.d b/source/ecs/block_allocator.d index 2894f61..abb7856 100644 --- a/source/ecs/block_allocator.d +++ b/source/ecs/block_allocator.d @@ -1,9 +1,10 @@ module ecs.block_allocator; import ecs.manager; - +import ecs.std; +/* import std.experimental.allocator; -import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator; +import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator;*/ struct BlockAllocator//(uint block_size, uint blocks_in_allocation) { @@ -37,13 +38,13 @@ struct BlockAllocator//(uint block_size, uint blocks_in_allocation) private void allocBlock() nothrow @nogc { - next_block = cast(void*) AlignedMallocator.instance.alignedAllocate( + next_block = cast(void*) Mallocator.alignAlloc( block_size * blocks_in_allocation, block_size); - if(pointers is null)pointers = Mallocator.instance.make!BlockPointers; + if(pointers is null)pointers = Mallocator.make!BlockPointers; if(pointers.numberof >= 32) { - BlockPointers* new_pointers = Mallocator.instance.make!BlockPointers; + BlockPointers* new_pointers = Mallocator.make!BlockPointers; new_pointers.next_pointers = pointers; pointers = new_pointers; } @@ -65,10 +66,10 @@ struct BlockAllocator//(uint block_size, uint blocks_in_allocation) { foreach(i;0..pointers.numberof) { - AlignedMallocator.instance.dispose(pointers.blocks[i]); + Mallocator.alignDispose(pointers.blocks[i]); } BlockPointers* next_pointers = pointers.next_pointers; - Mallocator.instance.dispose(pointers); + Mallocator.dispose(pointers); pointers = next_pointers; } } diff --git a/source/ecs/core.d b/source/ecs/core.d index 64dceba..431f57b 100644 --- a/source/ecs/core.d +++ b/source/ecs/core.d @@ -9,21 +9,6 @@ static struct ECS { __gshared ushort system_id; uint __ecs_jobs_count = jobs_count; - /*EntityManager.Job[] _ecs_jobs; - - void __ecsInitialize() nothrow @nogc - { - import std.experimental.allocator.mallocator; - import std.experimental.allocator; - _ecs_jobs = Mallocator.instance.makeArray!(EntityManager.Job)(jobs_count); - } - - void __ecsDeinitialize() nothrow @nogc - { - import std.experimental.allocator.mallocator; - import std.experimental.allocator; - Mallocator.instance.dispose(_ecs_jobs); - }*/ } mixin template Component() diff --git a/source/ecs/ecs.d b/source/ecs/ecs.d deleted file mode 100644 index 60d0f6a..0000000 --- a/source/ecs/ecs.d +++ /dev/null @@ -1,339 +0,0 @@ -module ecs.ecs; - -import std.stdio; - -version(Design): - -alias SytemFuncType = void function(ref SystemCallData data, void* componentsStart); - -struct HasComponentsStore -{ - ulong[4] bits; //256 components - - bool has(HasComponentsStore components) - { - return true; - } - - bool notIn(HasComponentsStore components) - { - return true; - } - - int length() - { - assert(0); - } -} - -// Informacje o kompnencie -struct ComponentInfo -{ - int size; - int aligment; - SerializeJSON funsSerJ; - SerializeBiN funcSerB; -} - -struct System -{ - HasComponentsStore requiredComponents; - HasComponentsStore absenComponents; - HasComponentsStore maybeComponents; - bool enabled; - int priority; - SytemFuncType func; -} -// Informacje o systemie dla konkretnego entitiesa -struct SystemCallData -{ - System* system; - int[] componentsDt; -} - -// Informacje o entitiesie danego typu -struct EntityTypeData -{ - HasComponentsStore components; - int[] deltas; - int totalSize; - int totalAligment = 8; - SystemCallData[] systems; -} - -struct EntitiesBlock -{ - EntityTypeData* typeData; - Entity* freeEntitySlot; - EntitiesBlock* nextBlock; -} - -struct EntityID -{ - ulong id = ulong.max; - static immutable notUsedValue = EntityID(ulong.max); -} - -// Dane konkretnego Entitiesa -struct Entity -{ - EntityID entityID = EntityID.notUsedValue; - union - { - string name; - Entity* nextFreeSlot; - } - - //string eventOnDestroy; - uint group; - EntityID entityID; - //ubyte[XX] thereIsComponentsMemory; -} - -struct Template -{ - HasComponentsStore hasComp; - Entity* entity; -} - -struct Manager -{ - EntityAllocator entityArrayAllcoator; - - ComponentInfo[] components; - System[] systems; - HashMap!(HasComponentsStore, EntitiesBlock*) entitiesDatas; - HashMapTwoWays!(string, Entity*) nameMap; - HashMapTwoWays!(EntityID, Entity*) idMap; - - EntitiesBlock* getEntitiesBlock(HasComponentsStore hasComponents) - { - EntitiesBlock* block = entitiesDatas.get(hasComponents, null); - if (block is null) - { - // If such component combination was never present, add it - block = addNewBlock(hasComponents, block); - return block; - } - // Iterate over list of components until free slot is found or lists ends - do - { - if (block.freeEntitySlot !is null) - { - return block; - } - if (block.nextBlock is null) - { - block = addNewBlock(hasComponents); - return block; - } - block = block.nextBlock; - } - while (block.nextBlock !is null); - - } - - EntitiesBlock* addNewBlock(HasComponentsStore hasComponents, EntitiesBlock* firstBlock) - { - // Get last block so order of blocks is preserved, and first blocks are filled first - EntitiesBlock* lastBlock = firstBlock; - if (lastBlock !is null) - { - while (lastBlock.nextBlock !is null) - { - lastBlock = lastBlock.nextBlock; - } - } - assert(lastBlock is null || lastBlock.nextBlock is null); - - ubyte[] memory = new ubyte[](4096); - EntitiesBlock* block = cast(EntitiesBlock*) memory.ptr; - if (lastBlock is null) - { - EntityTypeData* entityTypeData = newEntityTypeData(hasComponents); - block.typeData = entityTypeData; - block.nextBlock = null; - entitiesDatas.add(hasComponents, block); - } - else - { - lastBlock.nextBlock = block; - block.typeData = lastBlock.typeData; - block.nextBlock = null; - } - } - - void alignNum(ref int num, int aligment) - { - int reminder = num % aligment; - if (reminder != 0) - { - num += aligment - reminder; - } - } - - EntityTypeData* newEntityTypeData(HasComponentsStore hasComponents) - { - EntityTypeData* typeData = new EntityTypeData(); - typeData.components = hasComponents; - ComponentInfo[] components = getComponentsInfo(hasComponents); - typeData.deltas.length = hasComponents.length; - - foreach (i, comp; components) - { - typeData.deltas[i] = typeData.totalSize; - typeData.totalAligment.max(comp.aligment); - typeData.totalSize += comp.size; - alignNum(typeData.totalSize, comp.aligment); - } - alignNum(typeData.totalSize, typeData.totalAligment); - - foreach (sys; systems) - { - if (!typeData.hasComp.has(sys.requiredComponents) - || !typeData.hasComp.notIn(sys.absenComponents)) - { - continue; - } - entTypeData.systems ~= sys; - } - - return typeData; - } - - void addEntity(Template* templ) - { - EntitiesBlock* block = getEntitiesBlock(templ.hasComp); - Entity* newEntity = block.freeEntitySlot; - block.freeEntitySlot = newEntity.nextFreeSlot; - // from to size - memcpy(temp.entity, newEntity, block.typeData.totalSize); - } - - void addSystem(Func)(int priority) - { - HasComponentsStore requiredComponents; - HasComponentsStore absenComponents; - HasComponentsStore maybeComponents; - - void systemCaller(ref SystemCallData data, void * componentsStart) - { - Func(cast(FUnc.par1Type)(componentsStart + data.componentsDt[0]), - cast(FUnc.par1Type)(componentsStart + data.componentsDt[1])/*...*/); - } - System* system = new System(&systemCaller, entTypeData); - systems ~= system; - - foreach (ref entTypeData; entitiesDatas) - { - if (!entTypeData.hasComp.has(requiredComponents) - || !entTypeData.hasComp.notIn(absenComponents)) - { - continue; - } - entTypeData.systems ~= system; - } - } -} - -void someSystem(CompA a, CompB b, CompC* c) -{ -} - -void main() -{ - writeln("Edit source/app.d to start your project."); -} - -class System -{ - - void start() - { - - } - - void end() - { - - } - - void update(ref ObjRend a) - { - - } - - void useEvent(EventData evvv, ref ObjRend a) - { - - } -} - -alias SerializeVector = ubyte[]; - -__gshared EntityManager gEntityManager; - -unittest -{ - struct ComponentA - { - __gshared static int component_id; - int a; - ulong b; - - static void serializeComponent(ref ComponentA comp, SerializeVector output) - { - - } - - static void deerializeComponent(ref ComponentA comp, ubyte[] data) - { - - } - - } - - gEM.addComponet!ComponentA(); - assert(ComponentA.component_id == 0); - ComponentData* ccc = &gEM.componnets[ComponentA.component_id]; - assert(ccc.totalAligment == 8); - assert(ccc.totalSize == 8); - - HasComponentsStore hasComponents; - hasComponents.addComponet(ComponentA.component_id); - EntityTempalte* tmpl = gEM.allocateTemplate(hasComponents); - - ComponentA* comp = tmpl.getComponent!ComponentA(ComponentA.component_id); - comp.a = 111; - comp.b = 222; - - gEM.addEntity(tmpl); - - struct SystemAdd - { - void update(ref ComponentA a) - { - a.a+=1000; - b.b+=2000; - - } - - void handleEvent(EventData evvv, ref ComponentA a) - { - } - } - - int priority=10; - gEM.registerSystem!(SystemAdd)(priority); - gEM.updateStepAll(); - foreach(EntityID id; gEM.IterateByAllEntiteis){ - assert(id.getComponent(ComponentA.component_id)); - ComponentA* ccc=id.getComponent(ComponentA.component_id); - assert(ccc.a==1111); - assert(ccc.b==2222); - } - - - -} - diff --git a/source/ecs/events.d b/source/ecs/events.d index b2bd8cc..b7fa8ed 100644 --- a/source/ecs/events.d +++ b/source/ecs/events.d @@ -3,12 +3,13 @@ module ecs.events; import ecs.manager; import ecs.block_allocator; import ecs.entity; - +import ecs.std; +/* import std.experimental.allocator; -import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator; +import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator;*/ import std.algorithm.comparison : max; -import core.sync.mutex; +//import core.sync.mutex; /*struct Event { @@ -20,67 +21,22 @@ import core.sync.mutex; struct EventManager { - //@disable this(); - - /*this(EntityManager m) - { - manager = m; - }*/ - - /*void sendSelfEvent(Ev)(EntityID id, Ev event) - { - ushort size = cast(ushort)(Ev.sizeof); // + EntityID.sizeof + ushort.sizeof); - ushort alignment = cast(ushort)(Ev.alignof); - - EventList* list = &process_events; - - if (list.current_block is null) - { - list.current_block = cast(EventBlock*) allocator.getBlock(); - list.first_block = list.current_block; - list.current_block.index = cast(ushort)((void*).sizeof + ushort.sizeof); - } - - ushort index = cast(ushort)( - list.current_block.index + ushort.sizeof + EntityID.sizeof + ushort.sizeof); - - ushort aligned_index = index; //cast(ushort)(list.current_block.index); - alignNum(aligned_index, alignment); - - if (aligned_index + Ev.sizeof > events_block_size) - { - list.current_block.next = cast(EventBlock*) allocator.getBlock(); - list.current_block = list.current_block.next; - list.current_block.index = cast(ushort)((void*).sizeof + ushort.sizeof); - - index = cast(ushort)((void*) - .sizeof + ushort.sizeof + ushort.sizeof + EntityID.sizeof + ushort.sizeof); // + EntityID.sizeof + ushort.sizeof; - - aligned_index = index; - alignNum(aligned_index, alignment); - } - - EventBlock* block = list.current_block; - - ushort align_ = cast(ushort)(aligned_index - index); - *cast(ushort*)&block.data[block.index] = align_; - index = cast(ushort)(aligned_index - (EntityID.sizeof + ushort.sizeof)); - *cast(ushort*)&block.data[index] = Ev.event_id; - *cast(EntityID*)&block.data[index + 2] = id; - *cast(Ev*)&block.data[aligned_index] = event; - block.index = cast(ushort)(aligned_index + Ev.sizeof); - }*/ - - void initialize(EntityManager m) nothrow @nogc + void initialize(EntityManager* m) nothrow @nogc { allocator = BlockAllocator(events_block_size, events_blocks_in_allocation); - event_block_alloc_mutex = Mallocator.instance.make!Mutex; + event_block_alloc_mutex = Mallocator.make!Mutex; + event_block_alloc_mutex.initialize(); manager = m; } - void destroy() + void destroy() nothrow @nogc { - Mallocator.instance.dispose(event_block_alloc_mutex); + if(event_block_alloc_mutex) + { + event_block_alloc_mutex.destroy(); + Mallocator.dispose(event_block_alloc_mutex); + event_block_alloc_mutex = null; + } } export void sendEvent(Ev)(EntityID id, Ev event, uint thread_id = 0) nothrow @nogc @@ -94,9 +50,9 @@ struct EventManager if(block is null) { - event_block_alloc_mutex.lock_nothrow(); + event_block_alloc_mutex.lock(); scope (exit) - event_block_alloc_mutex.unlock_nothrow(); + event_block_alloc_mutex.unlock(); block = cast(EventBlock*) allocator.getBlock(); *block = EventBlock(); @@ -106,9 +62,9 @@ struct EventManager if(block.count >= data.max_events) { - event_block_alloc_mutex.lock_nothrow(); + event_block_alloc_mutex.lock(); scope (exit) - event_block_alloc_mutex.unlock_nothrow(); + event_block_alloc_mutex.unlock(); EventBlock* new_block = cast(EventBlock*) allocator.getBlock(); *new_block = EventBlock(); @@ -117,9 +73,6 @@ struct EventManager data.blocks[block_id] = block; } - /*void* start = cast(void*)block + data.data_offset + block.count * info.size; - Ev* event_ptr = cast(Ev*)start; - *event_ptr = event;*/ Ev* event_array = cast(Ev*)(cast(void*)block + data.data_offset); event_array[block.count] = event; block.count++; @@ -172,30 +125,16 @@ struct EventManager block = null; } } - /*EventList tmp = current_events; - current_events = process_events; - process_events = tmp; - - EventBlock* block = process_events.first_block; - - while (block) - { - EventBlock* free = block; - block = block.next; - allocator.freeBlock(free); - } - process_events.first_block = null; - process_events.current_block = null;*/ } void allocateData(uint threads_count) nothrow @nogc { disposeData(); - events = Mallocator.instance.makeArray!EventData(gEM.events.length); + events = Mallocator.makeArray!EventData(gEM.events.length); foreach(i,ref event;events) { - event.blocks = Mallocator.instance.makeArray!(EventBlock*)(threads_count*2); - event.first_blocks = Mallocator.instance.makeArray!(EventBlock*)(threads_count*2); + event.blocks = Mallocator.makeArray!(EventBlock*)(threads_count*2); + event.first_blocks = Mallocator.makeArray!(EventBlock*)(threads_count*2); event.data_offset = EventBlock.sizeof;//gEM.events[i]. gEM.alignNum(event.data_offset, gEM.events[i].alignment); @@ -216,16 +155,16 @@ struct EventManager if(block)next_block = first_block.next; while(block) { - Mallocator.instance.dispose(block); + Mallocator.dispose(block); block = next_block; if(block)next_block = block.next; } } - Mallocator.instance.dispose(event.blocks); - Mallocator.instance.dispose(event.first_blocks); + Mallocator.dispose(event.blocks); + Mallocator.dispose(event.first_blocks); } - Mallocator.instance.dispose(events); + Mallocator.dispose(events); } allocator.freeMemory(); } @@ -233,10 +172,6 @@ struct EventManager ~this() nothrow @nogc { disposeData(); - /*foreach(i,ref event;events) - { - EventBlock* block = event.first_blocks; - }*/ } ///Single page size. Must be power of two. @@ -246,26 +181,10 @@ struct EventManager struct EventBlock { - /*union - { - struct - { - EventBlock* next; - ushort index = 2; - } - - ubyte[events_block_size] data; - }*/ EventBlock* next; ushort count = 0; } - /*struct EventList - { - EventBlock* first_block; - EventBlock* current_block; - }*/ - struct EventData { ushort data_offset; @@ -276,12 +195,10 @@ struct EventManager //EventBlock*[] current_blocks; } - /*EventList current_events; - EventList process_events;*/ uint current_index = 0; EventData[] events; - Mutex event_block_alloc_mutex; + Mutex* event_block_alloc_mutex; - BlockAllocator/*!(events_block_size, events_blocks_in_allocation)*/ allocator; - EntityManager manager; + BlockAllocator allocator; + EntityManager* manager; } diff --git a/source/ecs/hash_map.d b/source/ecs/hash_map.d index 4f25394..f6d1642 100755 --- a/source/ecs/hash_map.d +++ b/source/ecs/hash_map.d @@ -30,6 +30,7 @@ export ulong hashInt(ulong x) nothrow @nogc @safe { struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { alias Key = KeyPar; alias Value = ValuePar; + nothrow: enum rehashFactor = 0.75; enum size_t getIndexEmptyValue = size_t.max; @@ -262,7 +263,7 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { return result; } - export int byKey(scope int delegate(Key k) dg) { + export int byKey(scope int delegate(Key k) nothrow dg) { int result; foreach (ref Key k; this) { result = dg(k); @@ -272,7 +273,7 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { return result; } - export int byValue(scope int delegate(ref Value k) dg) { + export int byValue(scope int delegate(ref Value k) nothrow dg) { int result; foreach (ref Value v; this) { result = dg(v); @@ -282,7 +283,7 @@ struct HashMap(KeyPar, ValuePar, alias hashFunc = defaultHashFunc) { return result; } - export int byKeyValue(scope int delegate(ref Key k, ref Value v) dg) { + export int byKeyValue(scope int delegate(ref Key k, ref Value v) nothrow dg) { int result; foreach (ref Key k, ref Value v; this) { result = dg(k, v); diff --git a/source/ecs/id_manager.d b/source/ecs/id_manager.d index 3ee7f1c..8821918 100644 --- a/source/ecs/id_manager.d +++ b/source/ecs/id_manager.d @@ -1,14 +1,15 @@ module ecs.id_manager; - +/* import std.experimental.allocator; -import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator; +import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator;*/ import ecs.entity; import ecs.vector; +import ecs.std; import core.atomic; import core.stdc.string : memcpy; -import core.sync.mutex; +//import core.sync.mutex; /************************************************************************************************************************ *IDManager is responsible for assignment and removing IDs. IDs are unique throughtout a whole duration of the program. @@ -35,13 +36,13 @@ begin: uint block_id = local_id >> 16; if (block_id >= m_blocks_count) { - add_mutex.lock_nothrow(); + add_mutex.lock(); if(block_id >= m_blocks_count) { m_blocks[m_blocks_count].alloc(); m_blocks_count++; } - add_mutex.unlock_nothrow(); + add_mutex.unlock(); } } @@ -145,30 +146,34 @@ begin: void initialize() nothrow @nogc { - m_ids_array = Mallocator.instance.makeArray!Data(65536); - m_free_stack = Mallocator.instance.makeArray!uint(65536); - m_blocks = Mallocator.instance.makeArray!Block(64); + m_ids_array = Mallocator.makeArray!Data(65536); + m_free_stack = Mallocator.makeArray!uint(65536); + m_blocks = Mallocator.makeArray!Block(64); + foreach(ref block;m_blocks)block = Block(); m_blocks_count = 1; m_blocks[0].alloc(); - add_mutex = Mallocator.instance.make!Mutex(); + add_mutex = Mallocator.make!Mutex(); + add_mutex.initialize(); } - void deinitialize() @trusted @nogc + void deinitialize() @trusted @nogc nothrow { - if(m_ids_array)Mallocator.instance.dispose(m_ids_array); - if(m_free_stack)Mallocator.instance.dispose(m_free_stack); + if(m_ids_array)Mallocator.dispose(m_ids_array); + if(m_free_stack)Mallocator.dispose(m_free_stack); if(m_blocks) { foreach(ref block;m_blocks) { if(block.data)block.free(); } - Mallocator.instance.dispose(m_blocks); + Mallocator.dispose(m_blocks); } if(add_mutex) { - Mallocator.instance.dispose(cast(void*)add_mutex); //workaround for compiler bug + add_mutex.destroy(); + Mallocator.dispose(add_mutex);//cast(void*)add_mutex); //workaround for compiler bug + add_mutex = null; } } @@ -178,14 +183,14 @@ begin: if(m_last_id > m_ids_array.length) { uint begin = cast(uint)m_ids_array.length; - Data[] new_array = Mallocator.instance.makeArray!Data(begin + (m_blocks_count << 16)); + Data[] new_array = Mallocator.makeArray!Data(begin + (m_blocks_count << 16)); memcpy(new_array.ptr, m_ids_array.ptr, m_ids_array.length * Data.sizeof); - Mallocator.instance.dispose(m_ids_array); + Mallocator.dispose(m_ids_array); m_ids_array = new_array; - uint[] new_stack = Mallocator.instance.makeArray!uint(m_ids_array.length); + uint[] new_stack = Mallocator.makeArray!uint(m_ids_array.length); memcpy(new_stack.ptr,m_free_stack.ptr,m_free_stack.length * uint.sizeof); - Mallocator.instance.dispose(m_free_stack); + Mallocator.dispose(m_free_stack); m_free_stack = new_stack; foreach(block;m_blocks[0..m_blocks_count-1]) @@ -204,13 +209,13 @@ begin: void alloc() nothrow @nogc { assert(data is null); - data = Mallocator.instance.makeArray!Data(65536); + data = Mallocator.makeArray!Data(65536); } void free() nothrow @nogc { assert(data !is null); - Mallocator.instance.dispose(data); + Mallocator.dispose(data); data = null; } @@ -225,7 +230,7 @@ begin: } private: - Mutex add_mutex; + Mutex* add_mutex; //shared uint m_next_id = 0; //shared uint m_last_id = 0; @@ -261,5 +266,4 @@ unittest assert(id3 == EntityID(2, 1)); assert(manager.isExist(id3)); assert(!manager.isExist(EntityID(0, 1))); - } diff --git a/source/ecs/manager.d b/source/ecs/manager.d index d75fa00..e3d37f3 100644 --- a/source/ecs/manager.d +++ b/source/ecs/manager.d @@ -5,14 +5,14 @@ module ecs.manager; import std.algorithm : max; import std.conv : to; -import std.experimental.allocator; -import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator; +//import std.experimental.allocator; +//import std.experimental.allocator.mallocator : AlignedMallocator, Mallocator; import std.traits; -import core.stdc.stdlib; +import core.stdc.stdlib : qsort; import core.stdc.string; import core.atomic; -import core.sync.mutex; +//import core.sync.mutex; import ecs.system; import ecs.entity; @@ -23,6 +23,7 @@ import ecs.vector; import ecs.simple_vector; import ecs.events; import ecs.traits; +import ecs.std; export alias gEM = EntityManager.instance; export alias gEntityManager = EntityManager.instance; @@ -32,18 +33,21 @@ alias SerializeVector = ecs.vector.Vector!ubyte; /************************************************************************************************************************ *Entity manager is responsible for everything. */ -export class EntityManager +export struct EntityManager { export static void initialize(uint threads_count) { if (instance is null) { - instance = Mallocator.instance.make!EntityManager(threads_count); + //instance = Mallocator.make!EntityManager(threads_count); + instance = Mallocator.make!EntityManager(threads_count); with(instance) { - UpdatePass* pass = Mallocator.instance.make!UpdatePass; - pass.name = Mallocator.instance.makeArray("update"); + UpdatePass* pass = Mallocator.make!UpdatePass; + pass.name = Mallocator.makeArray(cast(char[])"update"); + //pass.name = Mallocator.makeArray!char("update".length); + //pass.name[0..$] = "update"; passes.add(pass); passes_map.add(cast(string) pass.name, cast(ushort)(passes.length - 1)); } @@ -63,50 +67,49 @@ export class EntityManager if (system.m_destroy) (cast(void function(void*)) system.m_destroy)(system.m_system_pointer); - if(system.jobs)Mallocator.instance.dispose(system.jobs); - if(system.m_read_only_components)Mallocator.instance.dispose(system.m_read_only_components); - if(system.m_modified_components)Mallocator.instance.dispose(system.m_modified_components); - if(system.m_components)Mallocator.instance.dispose(system.m_components); - if(system.m_excluded_components)Mallocator.instance.dispose(system.m_excluded_components); - if(system.m_optional_components)Mallocator.instance.dispose(system.m_optional_components); - if(system.m_name)Mallocator.instance.dispose(system.m_name); - if(system.m_event_callers)Mallocator.instance.dispose(system.m_event_callers); + if(system.jobs)Mallocator.dispose(system.jobs); + if(system.m_read_only_components)Mallocator.dispose(system.m_read_only_components); + if(system.m_modified_components)Mallocator.dispose(system.m_modified_components); + if(system.m_components)Mallocator.dispose(system.m_components); + if(system.m_excluded_components)Mallocator.dispose(system.m_excluded_components); + if(system.m_optional_components)Mallocator.dispose(system.m_optional_components); + if(system.m_name)Mallocator.dispose(system.m_name); + if(system.m_event_callers)Mallocator.dispose(system.m_event_callers); - if(system.m_system_pointer)Mallocator.instance.dispose(system.m_system_pointer); + if(system.m_system_pointer)Mallocator.dispose(system.m_system_pointer); } foreach(EntityInfo* info;&entities_infos.byValue) { - //if(info.components)Mallocator.instance.dispose(info.components); + //if(info.components)Mallocator.dispose(info.components); - Mallocator.instance.dispose(info); - } + Mallocator.dispose(info); + }//*/ foreach(UpdatePass* pass; passes) { - Mallocator.instance.dispose(pass); + Mallocator.dispose(pass); } passes.clear(); foreach(ComponentInfo info; components) { - if(info.init_data)Mallocator.instance.dispose(info.init_data); + if(info.init_data)Mallocator.dispose(info.init_data); } foreach(EventInfo info; events) { - if(info.callers)Mallocator.instance.dispose(info.callers); + if(info.callers)Mallocator.dispose(info.callers); } foreach(name; &components_map.byKey) { - if(name)Mallocator.instance.dispose(name); + if(name)Mallocator.dispose(name); } } - Mallocator.instance.dispose(instance); + Mallocator.dispose(instance); instance = null; - } /************************************************************************************************************************ @@ -121,7 +124,7 @@ export class EntityManager { foreach (caller; pass.system_callers) { - Mallocator.instance.dispose(caller); + Mallocator.dispose(caller); } pass.system_callers.clear(); } @@ -138,8 +141,8 @@ export class EntityManager foreach (ref info; &entities_infos.byValue) { if (info.systems) - Mallocator.instance.dispose(info.systems); - info.systems = Mallocator.instance.makeArray!bool(systems.length); + Mallocator.dispose(info.systems); + info.systems = Mallocator.makeArray!bool(systems.length); } foreach (ref system; systems) @@ -161,7 +164,7 @@ export class EntityManager { if (systems[caller.system_id].priority > system.priority) { - SystemCaller* sys_caller = Mallocator.instance.make!SystemCaller; + SystemCaller* sys_caller = Mallocator.make!SystemCaller; sys_caller.system_id = system.id; sys_caller.job_group.caller = sys_caller; passes[system.m_pass].system_callers.add(sys_caller, i); @@ -171,7 +174,7 @@ export class EntityManager } if (!added) { - SystemCaller* sys_caller = Mallocator.instance.make!SystemCaller; + SystemCaller* sys_caller = Mallocator.make!SystemCaller; sys_caller.system_id = system.id; sys_caller.job_group.caller = sys_caller; passes[system.m_pass].system_callers.add(sys_caller); @@ -188,7 +191,7 @@ export class EntityManager foreach (ref info; events) { - Mallocator.instance.dispose(info.callers); + Mallocator.dispose(info.callers); } ushort[] event_callers = (cast(ushort*) alloca(ushort.sizeof * events.length))[0 @@ -206,7 +209,7 @@ export class EntityManager foreach (i, ref info; events) { - info.callers = Mallocator.instance.makeArray!(EventCaller)(event_callers[i]); + info.callers = Mallocator.makeArray!(EventCaller)(event_callers[i]); } foreach (ref caller; event_callers) @@ -222,7 +225,7 @@ export class EntityManager } } - foreach (info; &entities_infos.byValue) + foreach(EntityInfo* info;&entities_infos.byValue) { generateListeners(info); } @@ -233,30 +236,37 @@ export class EntityManager /************************************************************************************************************************ *Default constructor. */ - this(uint threads_count) + this(uint threads_count) nothrow @nogc { if (threads_count == 0) threads_count = 1; - threads = Mallocator.instance.makeArray!ThreadData(threads_count); + threads = Mallocator.makeArray!ThreadData(threads_count); + //foreach(ref thread;threads)thread = ThreadData().init; id_manager.initialize(); - event_manager.initialize(this); + event_manager.initialize(&this); allocator = BlockAllocator(page_size, pages_in_block); - //add_mutex = Mallocator.instance.make!Mutex; - entity_block_alloc_mutex = Mallocator.instance.make!Mutex; + //add_mutex = Mallocator.make!Mutex; + entity_block_alloc_mutex = Mallocator.make!Mutex; + entity_block_alloc_mutex.initialize(); //event_manager = EventManager(this); //event_manager.manager = this; } - ~this() + ~this() nothrow @nogc { id_manager.deinitialize(); event_manager.destroy(); - if(threads)Mallocator.instance.dispose(threads); - if(entity_block_alloc_mutex)Mallocator.instance.dispose(entity_block_alloc_mutex); + if(threads)Mallocator.dispose(threads); + if(entity_block_alloc_mutex) + { + entity_block_alloc_mutex.destroy(); + Mallocator.dispose(entity_block_alloc_mutex); + entity_block_alloc_mutex = null; + } allocator.freeMemory(); } @@ -267,7 +277,7 @@ export class EntityManager void registerSystem(Sys)(int priority, const(char)[] pass_name) { ushort pass = passes_map.get(pass_name, ushort.max); - assert(pass != ushort.max, "Update pass (Name " ~ pass_name ~ ") doesn't exist."); + assert(pass != ushort.max);//, "Update pass (Name " ~ pass_name ~ ") doesn't exist."); registerSystem!(Sys)(priority, pass); } @@ -286,19 +296,19 @@ export class EntityManager assert(register_state, "registerSystem must be called between beginRegister() and endRegister()."); - assert(pass < passes.length, "Update pass (ID " ~ pass.to!string ~ ") doesn't exist."); + assert(pass < passes.length);//, "Update pass (ID " ~ pass.to!string ~ ") doesn't exist."); System system; system.m_pass = pass; static if (!(hasMember!(Sys, "system_id")) || !is(typeof(Sys.system_id) == ushort)) { - static assert(0, "Add \"mixin ECS.System;\" in top of system structure;"); //"System should have \"__gshared ushort system_id"); + static assert(0);//, "Add \"mixin ECS.System;\" in top of system structure;"); //"System should have \"__gshared ushort system_id"); } static if (!(hasMember!(Sys, "EntitiesData"))) { - static assert(0, "System should gave \"EntitiesData\" struct for input components"); + static assert(0);//, "System should gave \"EntitiesData\" struct for input components"); } static if (hasMember!(Sys, "handleEvent")) @@ -346,7 +356,7 @@ export class EntityManager }//*/ Type* event = cast(Type*) data.event; - data_system.handleEvent(/*input, */gEM.getEntity(event.entity_id), *event); + data_system.handleEvent(gEM.getEntity(event.entity_id), *event); } void setEventCallers(Sys)(ref System system) @@ -359,18 +369,6 @@ export class EntityManager { alias Params = Parameters!(__traits(getOverloads, Sys, "handleEvent")[j]); - /*static if(Params.length == 2 && is(Params[0] == __traits(getMember, Sys, "EventInput"))) - { - alias EventParamType = Params[1]; - enum EventName = Unqual!(EventParamType).stringof; - ushort evt = events_map.get(cast(char[]) EventName, ushort.max); - assert(evt != ushort.max, "Can't register system \""~Sys.stringof~"\" due to non existing event \""~EventName~"\"."); - - callers[i].callback = cast( - void*)&callEventHandler!(EventParamType); - callers[i].id = EventParamType.event_id; - i++; - }*/ static if(Params.length == 2 && is(Params[0] == Entity*)) { alias EventParamType = Params[1]; @@ -385,12 +383,12 @@ export class EntityManager } } - system.m_event_callers = Mallocator.instance.makeArray(callers[0..i]); + system.m_event_callers = Mallocator.makeArray(callers[0..i]); } static if (__traits(hasMember, Sys, "handleEvent")) { - setEventCallers!(Sys)(system); + //setEventCallers!(Sys)(system); } } @@ -402,11 +400,69 @@ export class EntityManager static struct ComponentsIndices { - CompInfo[] readonly; - CompInfo[] mutable; - CompInfo[] excluded; - CompInfo[] optional; - CompInfo[] req; + + CompInfo[] readonly() + { + return m_readonly[0 .. m_readonly_counter]; + } + + CompInfo[] mutable() + { + return m_mutable[0 .. m_mutable_counter]; + } + + CompInfo[] excluded() + { + return m_excluded[0 .. m_excluded_counter]; + } + + CompInfo[] optional() + { + return m_optional[0 .. m_optional_counter]; + } + + CompInfo[] req() + { + return m_req[0 .. m_req_counter]; + } + + void addReadonly(CompInfo info) + { + m_readonly[m_readonly_counter++] = info; + } + + void addMutable(CompInfo info) + { + m_mutable[m_mutable_counter++] = info; + } + + void addExcluded(CompInfo info) + { + m_excluded[m_excluded_counter++] = info; + } + + void addOptional(CompInfo info) + { + m_optional[m_optional_counter++] = info; + } + + void addReq(CompInfo info) + { + m_req[m_req_counter++] = info; + } + + CompInfo[32] m_readonly; + CompInfo[32] m_mutable; + CompInfo[32] m_excluded; + CompInfo[32] m_optional; + CompInfo[32] m_req; + + uint m_readonly_counter; + uint m_mutable_counter; + uint m_excluded_counter; + uint m_optional_counter; + uint m_req_counter; + string entites_array; } @@ -419,22 +475,25 @@ export class EntityManager size_t modified = components_info.mutable.length; if (req > 0) - system.m_components = Mallocator.instance.makeArray!ushort(req); + system.m_components = Mallocator.makeArray!ushort(req); if (opt > 0) - system.m_optional_components = Mallocator.instance.makeArray!ushort(opt); + system.m_optional_components = Mallocator.makeArray!ushort(opt); if (excluded > 0) - system.m_excluded_components = Mallocator.instance.makeArray!ushort(excluded); + system.m_excluded_components = Mallocator.makeArray!ushort(excluded); if (read_only > 0) - system.m_read_only_components = Mallocator.instance.makeArray!ushort(read_only); + system.m_read_only_components = Mallocator.makeArray!ushort(read_only); if (modified > 0) - system.m_modified_components = Mallocator.instance.makeArray!ushort(modified); + system.m_modified_components = Mallocator.makeArray!ushort(modified); } - static ComponentsIndices getComponentsInfo() + static ComponentsIndices getComponentsInfo()() { ComponentsIndices components_info; + //import core.stdc.stdlib; + //uint[] aaa = (cast(uint*)malloc(400))[0..100]; + bool checkExcludedComponentsSomething(Sys)() { return __traits(compiles, allSameType!(string, typeof(Sys.ExcludedComponents))) && allSameType!(string, @@ -457,7 +516,6 @@ export class EntityManager } bool is_optional; - //bool is_excluded; bool is_read_only; if (is(CopyConstness!(ForeachType!(MemberType), int) == const(int))) @@ -471,10 +529,6 @@ export class EntityManager { is_optional = true; } - /*else if (att == "excluded") - { - is_excluded = true; - }*/ if (att == "readonly") { is_read_only = true; @@ -482,32 +536,32 @@ export class EntityManager } if (is_read_only) { - components_info.readonly ~= CompInfo(member,name); + components_info.addReadonly(CompInfo(member,name)); + //components_info.readonly ~= CompInfo(member,name); } else { - components_info.mutable ~= CompInfo(member,name); + components_info.addMutable(CompInfo(member,name)); + //components_info.mutable ~= CompInfo(member,name); } - /*if (is_excluded) - { - components_info.excluded ~= CompInfo(member,name); - }*/ if (is_optional) { - components_info.optional ~= CompInfo(member,name); + components_info.addOptional(CompInfo(member,name)); + //components_info.optional ~= CompInfo(member,name); } - if (is_read_only) + else { - components_info.readonly ~= CompInfo(member,name); + components_info.addReq(CompInfo(member,name)); + //components_info.req ~= CompInfo(member,name); } - if (/*is_excluded == false &&*/ is_optional == false) + /*if (is_read_only) + { + //components_info.readonly ~= CompInfo(member,name); + } + if (is_optional == false) { //is Req - components_info.req ~= CompInfo(member,name); - } - - /*assert(!(is_optional && is_excluded), - "EntitiesData member can't have both \"@optional\" and \"@excluded\".");*/ - + //components_info.req ~= CompInfo(member,name); + }*/ } static if (__traits(hasMember, Sys, "ExcludedComponents")) @@ -516,18 +570,21 @@ export class EntityManager { foreach (str; __traits(allMembers, Sys.ExcludedComponents)) { - components_info.excluded ~= CompInfo(str,str); + components_info.addExcluded(CompInfo(str,str)); + //components_info.excluded ~= CompInfo(str,str); } } else static if (checkExcludedComponentsSomething!Sys) { foreach (str; Sys.ExcludedComponents) { - components_info.excluded ~= CompInfo(str,str); + components_info.addExcluded(CompInfo(str,str)); + //components_info.excluded ~= CompInfo(str,str); } } } + return components_info; } @@ -557,31 +614,31 @@ export class EntityManager foreach (iii, comp_info; components_info.req) { ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); - assert(comp != ushort.max, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\"."); + assert(comp != ushort.max);//, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\"."); system.m_components[iii] = comp; } foreach (iii, comp_info; components_info.excluded) { ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); - assert(comp != ushort.max, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\"."); + assert(comp != ushort.max);//, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\"."); system.m_excluded_components[iii] = comp; } foreach (iii, comp_info; components_info.optional) { ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); - assert(comp != ushort.max, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\"."); + assert(comp != ushort.max);//, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\"."); system.m_optional_components[iii] = comp; } foreach (iii, comp_info; components_info.readonly) { ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); - assert(comp != ushort.max, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\"."); + assert(comp != ushort.max);//, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\"."); system.m_read_only_components[iii] = comp; } foreach (iii, comp_info; components_info.mutable) { ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); - assert(comp != ushort.max, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\"."); + assert(comp != ushort.max);//, "Can't register system \""~Sys.stringof~"\" due to non existing component \""~comp_info.type~"\"."); system.m_modified_components[iii] = comp; } @@ -741,11 +798,11 @@ export class EntityManager catchEntityFunction!("onRemoveEntity")(&system.m_remove_entity); catchEntityFunction!("onChangeEntity")(&system.m_change_entity); - system.m_system_pointer = cast(void*) Mallocator.instance.make!Sys; + system.m_system_pointer = cast(void*) Mallocator.make!Sys; system.m_priority = priority; //(cast(Sys*) system.m_system_pointer).__ecsInitialize(); //system.jobs = (cast(Sys*) system.m_system_pointer)._ecs_jobs; - system.jobs = Mallocator.instance.makeArray!(Job)((cast(Sys*) system.m_system_pointer).__ecs_jobs_count); + system.jobs = Mallocator.makeArray!(Job)((cast(Sys*) system.m_system_pointer).__ecs_jobs_count); genCompList(system, components_map); @@ -754,8 +811,6 @@ export class EntityManager { system.enable(); - /*if (systems[sys_id].m_destroy) - systems[sys_id].m_destroy(systems[sys_id].m_system_pointer);*/ if (system.m_create) (cast(void function(void*)) system.m_create)(system.m_system_pointer); @@ -764,7 +819,7 @@ export class EntityManager } else { - system.m_name = Mallocator.instance.makeArray(Sys.stringof); + system.m_name = Mallocator.makeArray(cast(char[])Sys.stringof); systems_map.add(system.m_name, cast(ushort) systems.length); system.m_id = cast(ushort)(systems.length); @@ -797,8 +852,10 @@ export class EntityManager export ushort registerPass(const(char)[] name) { - UpdatePass* pass = Mallocator.instance.make!UpdatePass; - pass.name = Mallocator.instance.makeArray(name); + UpdatePass* pass = Mallocator.make!UpdatePass; + pass.name = Mallocator.makeArray(cast(char[])name); + /*pass.name = Mallocator.makeArray!char(name.length); + pass.name[0..$] = name[0..$];*/ passes.add(pass); passes_map.add(name, cast(ushort)(passes.length - 1)); return cast(ushort)(passes.length - 1); @@ -841,7 +898,7 @@ export class EntityManager info.size = Comp.sizeof; info.alignment = Comp.alignof; //8; - info.init_data = Mallocator.instance.makeArray!ubyte(Comp.sizeof); + info.init_data = Mallocator.makeArray!ubyte(Comp.sizeof); *cast(Comp*) info.init_data.ptr = Comp.init; // = Comp(); ushort comp_id = components_map.get(cast(char[])Comp.stringof, ushort.max); @@ -854,7 +911,9 @@ export class EntityManager { components.add(info); Comp.component_id = cast(ushort)(components.length - 1); - char[] name = Mallocator.instance.makeArray(Comp.stringof); + char[] name = Mallocator.makeArray(cast(char[])Comp.stringof); + /*char[] name = Mallocator.makeArray!char(Comp.stringof.length); + name[0..$] = Comp.stringof;*/ components_map.add(name, cast(ushort)(components.length - 1)); } } @@ -982,7 +1041,8 @@ export class EntityManager { CallData[] callers = m_call_data_allocator.getCallData( cast(uint) tmp_datas.length); - callers[0 .. $] = tmp_datas[0 .. $]; + //callers[0 .. $] = tmp_datas[0 .. $]; + memcpy(callers.ptr, &tmp_datas[0], CallData.sizeof * tmp_datas.length); tmp_datas.clear(); sys.jobs[job_id].callers = callers; job_id++; @@ -1100,8 +1160,8 @@ export class EntityManager EntitiesBlock* block = getMetaData(entity); EntityInfo* info = block.type_info; - EntityTemplate* temp = Mallocator.instance.make!EntityTemplate; - temp.entity_data = Mallocator.instance.makeArray!ubyte(info.size); + EntityTemplate* temp = Mallocator.make!EntityTemplate; + temp.entity_data = Mallocator.makeArray!ubyte(info.size); temp.info = info; if(fill_default) @@ -1109,8 +1169,9 @@ export class EntityManager //fill components with default data foreach (comp; info.components) { - temp.entity_data[info.tmpl_deltas[comp] .. info.tmpl_deltas[comp] + components[comp].size] - = components[comp].init_data; + memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], components[comp].init_data.ptr, components[comp].size); + /*temp.entity_data[info.tmpl_deltas[comp] .. info.tmpl_deltas[comp] + components[comp].size] + = components[comp].init_data;*/ } } else @@ -1137,7 +1198,8 @@ export class EntityManager ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * components_ids.length))[0 .. components_ids.length]; - ids[0 .. $] = components_ids[]; + memcpy(ids.ptr, components_ids.ptr, ushort.sizeof * components_ids.length); + //ids[0 .. $] = components_ids[]; qsort(ids.ptr, ids.length, ushort.sizeof, &compareUShorts); { uint j = 1; @@ -1156,15 +1218,16 @@ export class EntityManager EntityInfo* info = getEntityInfo(ids); - EntityTemplate* temp = Mallocator.instance.make!EntityTemplate; - temp.entity_data = Mallocator.instance.makeArray!ubyte(info.size); + EntityTemplate* temp = Mallocator.make!EntityTemplate; + temp.entity_data = Mallocator.makeArray!ubyte(info.size); temp.info = info; //fill components with default data foreach (comp; info.components) { - temp.entity_data[info.tmpl_deltas[comp] .. info.tmpl_deltas[comp] + components[comp].size] - = components[comp].init_data; + memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], components[comp].init_data.ptr, components[comp].size); + /*temp.entity_data[info.tmpl_deltas[comp] .. info.tmpl_deltas[comp] + components[comp].size] + = components[comp].init_data;*/ } return temp; @@ -1181,15 +1244,17 @@ export class EntityManager EntityInfo* info = entities_infos.get(ids, null); if (info is null) { - info = Mallocator.instance.make!EntityInfo; + info = Mallocator.make!EntityInfo; - info.components = Mallocator.instance.makeArray(ids); - info.deltas = Mallocator.instance.makeArray!ushort(ids[$ - 1] + 1); + info.components = Mallocator.makeArray(ids); + /*info.components = Mallocator.makeArray!ushort(ids.length); + info.components[0 .. $] = ids[0 .. $];*/ + info.deltas = Mallocator.makeArray!ushort(ids[$ - 1] + 1); info.size = EntityID.sizeof; info.alignment = EntityID.alignof; - info.tmpl_deltas = Mallocator.instance.makeArray!ushort(ids[$ - 1] + 1, ushort.max); + info.tmpl_deltas = Mallocator.makeArray!ushort(ids[$ - 1] + 1, ushort.max); uint components_size = EntityID.sizeof; foreach (i, id; ids) @@ -1202,18 +1267,11 @@ export class EntityManager } alignNum(info.size, info.alignment); - /**/ - uint block_memory = cast(uint)( page_size - EntitiesBlock.sizeof - (info.size - components_size)); //uint entity_comps_size = EntityID.sizeof; uint mem_begin = EntitiesBlock.sizeof; - /*foreach (id; ids) - { - entity_comps_size += components[id].size; - }*/ - uint entites_in_block = block_memory / info.size; //entity_comps_size; info.max_entities = cast(ushort) entites_in_block; ushort current_delta = cast(ushort)(mem_begin + entites_in_block * EntityID.sizeof); @@ -1225,7 +1283,7 @@ export class EntityManager current_delta += entites_in_block * components[id].size; } - info.systems = Mallocator.instance.makeArray!bool(systems.length); + info.systems = Mallocator.makeArray!bool(systems.length); foreach (i, ref system; systems) { @@ -1245,21 +1303,21 @@ export class EntityManager return info; } - private void generateListeners(EntityInfo* info) + private void generateListeners(EntityInfo* info) nothrow { if (info.add_listeners) { - Mallocator.instance.dispose(info.add_listeners); + Mallocator.dispose(info.add_listeners); info.add_listeners = null; } if (info.remove_listeners) { - Mallocator.instance.dispose(info.remove_listeners); + Mallocator.dispose(info.remove_listeners); info.remove_listeners = null; } if (info.change_listeners) { - Mallocator.instance.dispose(info.change_listeners); + Mallocator.dispose(info.change_listeners); info.change_listeners = null; } //allocate local data @@ -1340,19 +1398,19 @@ export class EntityManager if (add_len) { - info.add_listeners = Mallocator.instance.makeArray!ushort(add_len); + info.add_listeners = Mallocator.makeArray!ushort(add_len); memcpy(info.add_listeners.ptr, tmp_add.ptr, add_len * ushort.sizeof); } if (rem_len) { - info.remove_listeners = Mallocator.instance.makeArray!ushort(rem_len); + info.remove_listeners = Mallocator.makeArray!ushort(rem_len); memcpy(info.remove_listeners.ptr, tmp_rem.ptr, rem_len * ushort.sizeof); } if (ch_len) { - info.change_listeners = Mallocator.instance.makeArray!ushort(ch_len); + info.change_listeners = Mallocator.makeArray!ushort(ch_len); memcpy(info.change_listeners.ptr, tmp_ch.ptr, ch_len * ushort.sizeof); } } @@ -1473,28 +1531,6 @@ export class EntityManager EntityInfo* new_info = info; - /*uint j = 0; - uint k = 0; - foreach (id; info.components) - { - while (k < del_ids.length && del_ids[k] < id) - k++; - if (k >= del_ids.length) - { - ids[j++] = id; - } - else if (del_ids[k] == info.components[j]) - { - k++; - new_info = new_info.getNewInfoAdd(del_ids[k]); - } - else - ids[j++] = id; - } - - if (j == info.components.length) - return;*/ - foreach(id;del_ids) { new_info = new_info.getNewInfoRemove(id); @@ -1588,21 +1624,6 @@ export class EntityManager return; EntitiesBlock* block = getMetaData(entity); EntityInfo* info = block.type_info; - /*ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * (info.components.length + num)))[0 - .. info.components.length + num];*/ - /*ushort[num] new_ids; - - static foreach (i, comp; Components) - { - new_ids[i] = comp.component_id; - }*/ - - /*void*[num] pointers; - - static foreach (i, comp; comps) - { - pointers[i] = ∁ - }*/ foreach (int i; 0 .. num) { @@ -1629,44 +1650,6 @@ export class EntityManager EntityInfo* new_info = info; - /* uint j = 0; - uint k = 0; - uint len = 0; - //foreach (ref id; ids) - for (; len < ids.length; len++) - { - ushort* id = &ids[len]; - if (k >= new_ids.length) - { - if (j >= info.components.length) - break; - *id = info.components[j++]; - //continue; - } - else if (j >= info.components.length) - { - *id = new_ids[k++]; - new_info = new_info.getNewInfoAdd(*id); - //continue; - } - else if (new_ids[k] == info.components[j]) - { - *id = info.components[j++]; - k++; - } - /*debug if (new_ids[k] == info.components[j]) - assert(0, "Trying to add already existing component!");//* - else if (new_ids[k] < info.components[j]) - { - *id = new_ids[k++]; - new_info = new_info.getNewInfoAdd(*id); - } - else - *id = info.components[j++]; - } - if (len == info.components.length) - return;*/ - foreach(id;new_ids) { new_info = new_info.getNewInfoAdd(id); @@ -1702,7 +1685,7 @@ export class EntityManager foreach (ref id; new_info.components)//ids[0 .. len]) { void* dst = cast(void*) new_block + new_info.deltas[id] + ( - new_block.entities_count /*+ new_block.added_count*/ ) * components[id].size; + new_block.entities_count ) * components[id].size; uint size = components[id].size; if (k >= new_ids.length) { @@ -1776,12 +1759,6 @@ export class EntityManager new_ids[i] = comp.component_id; } - /*void*[num] pointers; - - static foreach (i, comp; comps) - { - pointers[i] = ∁ - }*/ ThreadData* data = &threads[thread_id]; data.change_entities_list.add(cast(ubyte)1u); data.change_entities_list.add((cast(ubyte*)&entity_id)[0 .. EntityID.sizeof]); @@ -1803,8 +1780,8 @@ export class EntityManager */ export void freeTemplate(EntityTemplate* template_) { - Mallocator.instance.dispose(template_.entity_data); - Mallocator.instance.dispose(template_); + Mallocator.dispose(template_.entity_data); + Mallocator.dispose(template_); } /************************************************************************************************************************ @@ -1947,9 +1924,9 @@ export class EntityManager if (block is null) { - entity_block_alloc_mutex.lock_nothrow(); + entity_block_alloc_mutex.lock(); scope (exit) - entity_block_alloc_mutex.unlock_nothrow(); + entity_block_alloc_mutex.unlock(); if (info.last_block != null) return info.last_block; @@ -1964,9 +1941,9 @@ export class EntityManager { EntitiesBlock* last_block = info.last_block; - entity_block_alloc_mutex.lock_nothrow(); + entity_block_alloc_mutex.lock(); scope (exit) - entity_block_alloc_mutex.unlock_nothrow(); + entity_block_alloc_mutex.unlock(); if (info.last_block !is last_block) return info.last_block; @@ -2348,9 +2325,9 @@ export class EntityManager { caller.system = &systems[caller.system_id]; if (caller.exclusion) - Mallocator.instance.dispose(caller.exclusion); + Mallocator.dispose(caller.exclusion); if (caller.dependencies) - Mallocator.instance.dispose(caller.dependencies); + Mallocator.dispose(caller.dependencies); } uint index = 0; SystemCaller*[] exclusion; @@ -2361,7 +2338,7 @@ export class EntityManager index = 0; out_for: foreach (caller2; pass.system_callers) { - if ( /*caller.system.priority != caller2.system.priority ||*/ caller is caller2) + if ( caller is caller2) continue; foreach (cmp; caller.system.m_read_only_components) { @@ -2396,15 +2373,13 @@ export class EntityManager } if (index > 0) - caller.exclusion = Mallocator.instance.makeArray(exclusion[0 .. index]); + { + caller.exclusion = Mallocator.makeArray(exclusion[0 .. index]); + /*caller.exclusion = Mallocator.makeArray!(SystemCaller*)(index); + caller.exclusion[0..$] = exclusion[0 .. index];*/ + } else caller.exclusion = null; - - /*import std.stdio; - write("Exclusive systems for system ", caller.system.m_name, ": "); - foreach (ex; exclusion[0 .. index]) - write(ex.system.m_name, " "); - writeln();*/ } extern (C) static int compareSystems(const void* a, const void* b) @@ -2448,8 +2423,10 @@ export class EntityManager if (index > 0) { - caller.dependencies = Mallocator.instance.makeArray(exclusion[0 .. index]); - caller.job_group.dependencies = Mallocator.instance.makeArray!( + caller.dependencies = Mallocator.makeArray(exclusion[0 .. index]); + /*caller.dependencies = Mallocator.makeArray!(SystemCaller*)(index); + caller.dependencies[0..$] = exclusion[0 .. index];*/ + caller.job_group.dependencies = Mallocator.makeArray!( JobGroup*)(index); foreach (j, dep; caller.dependencies) @@ -2459,12 +2436,6 @@ export class EntityManager } else caller.dependencies = null; - - /*import std.stdio; - write("Dependencies for system ", caller.system.m_name, ": "); - foreach (ex; caller.dependencies) - write(ex.system.m_name, " "); - writeln();*/ } } } @@ -2474,6 +2445,7 @@ export class EntityManager */ struct ComponentInfo { + nothrow ~this(){} ///Component size ushort size; ///Component data alignment @@ -2482,8 +2454,10 @@ export class EntityManager ubyte[] init_data; ///Pointer to component destroy callback void function(void* pointer) nothrow @nogc destroy_callback; + //void* destroy_callback; ///Pointer to component create callback void function(void* pointer) nothrow @nogc create_callback; + //void* create_callback; } struct EventCaller @@ -2541,11 +2515,12 @@ export class EntityManager { if(comp_add_info.length < id) { - EntityInfo*[] new_infos = Mallocator.instance.makeArray!(EntityInfo*)(instance.components.length); + EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)(instance.components.length); if(comp_add_info !is null) { - new_infos[0 .. comp_add_info.length] = comp_add_info[0 .. $]; - Mallocator.instance.dispose(comp_add_info); + //new_infos[0 .. comp_add_info.length] = comp_add_info[0 .. $]; + memcpy(new_infos.ptr, comp_add_info.ptr, (EntityInfo*).sizeof * comp_add_info.length); + Mallocator.dispose(comp_add_info); } comp_add_info = new_infos; } @@ -2582,11 +2557,12 @@ export class EntityManager { if(comp_rem_info.length < id) { - EntityInfo*[] new_infos = Mallocator.instance.makeArray!(EntityInfo*)(instance.components.length); + EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)(instance.components.length); if(comp_rem_info !is null) { - new_infos[0 .. comp_rem_info.length] = comp_rem_info[0 .. $]; - Mallocator.instance.dispose(comp_rem_info); + //new_infos[0 .. comp_rem_info.length] = comp_rem_info[0 .. $]; + memcpy(new_infos.ptr, comp_rem_info.ptr, (EntityInfo*).sizeof * comp_rem_info.length); + Mallocator.dispose(comp_rem_info); } comp_rem_info = new_infos; } @@ -2613,15 +2589,15 @@ export class EntityManager return new_info; } - ~this() + ~this() @nogc nothrow { - if(components)Mallocator.instance.dispose(components); - if(deltas)Mallocator.instance.dispose(deltas); - if(tmpl_deltas)Mallocator.instance.dispose(tmpl_deltas); - if(systems)Mallocator.instance.dispose(systems); - if(add_listeners)Mallocator.instance.dispose(add_listeners); - if(remove_listeners)Mallocator.instance.dispose(remove_listeners); - if(change_listeners)Mallocator.instance.dispose(change_listeners); + if(components)Mallocator.dispose(components); + if(deltas)Mallocator.dispose(deltas); + if(tmpl_deltas)Mallocator.dispose(tmpl_deltas); + if(systems)Mallocator.dispose(systems); + if(add_listeners)Mallocator.dispose(add_listeners); + if(remove_listeners)Mallocator.dispose(remove_listeners); + if(change_listeners)Mallocator.dispose(change_listeners); } ///entity components @@ -2772,14 +2748,14 @@ export class EntityManager { if (dependencies) { - Mallocator.instance.dispose(dependencies); + Mallocator.dispose(dependencies); } if(exclusion) { - Mallocator.instance.dispose(exclusion); + Mallocator.dispose(exclusion); } if (job_group.dependencies) - Mallocator.instance.dispose(job_group.dependencies); + Mallocator.dispose(job_group.dependencies); } uint system_id; @@ -2804,10 +2780,10 @@ export class EntityManager { assert(name); if (name) - Mallocator.instance.dispose(name); + Mallocator.dispose(name); foreach(caller; system_callers) { - Mallocator.instance.dispose(caller); + Mallocator.dispose(caller); } system_callers.clear(); } @@ -2832,7 +2808,7 @@ export class EntityManager enum pages_in_block = 128; IDManager id_manager; - BlockAllocator /*!(page_size, pages_in_block)*/ allocator; + BlockAllocator allocator; EventManager event_manager; @@ -2849,7 +2825,7 @@ export class EntityManager Vector!EventInfo events; //Mutex add_mutex; - Mutex entity_block_alloc_mutex; + Mutex* entity_block_alloc_mutex; CallDataAllocator m_call_data_allocator; struct CallDataAllocator @@ -2860,11 +2836,11 @@ export class EntityManager uint allocated = 0; } - ~this() + ~this() nothrow @nogc { foreach(block;blocks) { - Mallocator.instance.dispose(block); + Mallocator.dispose(block); } blocks.clear(); } @@ -2887,13 +2863,9 @@ export class EntityManager { if (blocks.length == 0) { - Block* new_block = Mallocator.instance.make!Block; + Block* new_block = Mallocator.make!Block; blocks.add(new_block); } - /*else if(blocks[$-1].allocated + num >= 256) - { - blocks.add(Block()); - }*/ Block* block = blocks[id]; if (block.allocated + num >= 256) @@ -2901,7 +2873,7 @@ export class EntityManager id++; if (id == blocks.length) { - Block* new_block = Mallocator.instance.make!Block; + Block* new_block = Mallocator.make!Block; blocks.add(new_block); } block = blocks[id]; @@ -2913,15 +2885,5 @@ export class EntityManager } } - export __gshared EntityManager instance = null; + export __gshared EntityManager* instance = null; } - -/* -static ulong defaultHashFunc(T)(auto ref T t) -{ - ulong ret = 0; - foreach(id;t) - { - ret = ret - } -}*/ diff --git a/source/ecs/simple_vector.d b/source/ecs/simple_vector.d index 1751040..7d9cd7a 100644 --- a/source/ecs/simple_vector.d +++ b/source/ecs/simple_vector.d @@ -1,7 +1,9 @@ module ecs.simple_vector; - +/* import std.experimental.allocator; -import std.experimental.allocator.mallocator; +import std.experimental.allocator.mallocator;*/ + +import ecs.std; import core.stdc.string; @@ -14,8 +16,8 @@ struct SimpleVector { while(used >= data.length) { - if(data is null)data = Mallocator.instance.makeArray!ubyte(1024); - else Mallocator.instance.expandArray(data,data.length); + if(data is null)data = Mallocator.makeArray!ubyte(1024); + else data = Mallocator.expandArray(data,data.length); } data[used++] = el; } @@ -24,8 +26,8 @@ struct SimpleVector { while(used + el.length >= data.length) { - if(data is null)data = Mallocator.instance.makeArray!ubyte(1024); - else Mallocator.instance.expandArray(data,data.length); + if(data is null)data = Mallocator.makeArray!ubyte(1024); + else data = Mallocator.expandArray(data,data.length); } memcpy(data.ptr + used, el.ptr, el.length); used += el.length; diff --git a/source/ecs/std.d b/source/ecs/std.d new file mode 100644 index 0000000..8dfbccf --- /dev/null +++ b/source/ecs/std.d @@ -0,0 +1,227 @@ +module ecs.std; + +import core.stdc.stdlib : malloc, free, realloc; +import core.stdc.string : memcpy; +import std.traits; +import core.time; + +version (Windows) +{ + import core.sys.windows.windows; + extern(Windows) void* _aligned_malloc(size_t size,size_t alignment) @nogc nothrow @system; + extern(Windows) void _aligned_free(void* ptr) @nogc nothrow @system; + + version(LDC) + { + /*extern(Windows) void* __alloca(size_t size) @nogc nothrow @system; + alias alloca = __alloca;*/ + + private const uint max_alloca = 10000; + private char[max_alloca] alloca_array; + private uint alloca_pos = 0; + void* alloca(size_t length) @nogc nothrow + { + if(alloca_pos + length > max_alloca)alloca_pos = 0; + void* ret = &alloca_array[alloca_pos]; + alloca_pos += length; + return ret; + } + + extern(Windows) void ___chkstk_ms() @nogc nothrow @system; + + extern(Windows) void __chkstk() + { + ___chkstk_ms(); + } + } + else + { + private const uint max_alloca = 10000; + private char[max_alloca] alloca_array; + private uint alloca_pos = 0; + void* alloca(size_t length) @nogc nothrow + { + if(alloca_pos + length > max_alloca)alloca_pos = 0; + void* ret = &alloca_array[alloca_pos]; + alloca_pos += length; + return ret; + } + } +} +else version (Posix) +{ + import core.sys.posix.pthread; + import core.sys.posix.stdlib; + public import core.stdc.stdlib : alloca; +} + +static struct Mallocator +{ + static T[] makeArray(T)(size_t length) nothrow @nogc + { + T[] ret = (cast(T*)malloc(T.sizeof * length))[0 .. length]; + + /*static if(__traits(isPOD, T)) + { + static immutable T init = T.init; + + foreach(i;0..ret.length) + { + memcpy(&ret[i], &init, T.sizeof); + } + } + else + {*/ + static import std.conv; + foreach(i;0..ret.length) + { + std.conv.emplace(&ret[i]); + } + // } + + //static if(is(T == struct))std.conv.emplace(ret); + //static import std.conv; + //emplace + /*foreach(i;0..ret.length) + { + memcpy(ret); + }*/ + return ret; + } + + static T[] makeArray(T)(size_t length, T initializer) nothrow @nogc + { + T[] ret = (cast(T*)malloc(T.sizeof * length))[0 .. length]; + foreach(ref v; ret)v = initializer; + return ret; + //return (cast(T*)ret)[0 .. length]; + } + + static T[] expandArray(T)(T[] array, size_t length) nothrow @nogc + { + size_t new_length = array.length + length; + return (cast(T*)realloc(array.ptr, T.sizeof * new_length))[0 .. new_length]; + } + + static T[] makeArray(T)(T[] array) nothrow @nogc + { + T[] ret = (cast(T*)malloc(T.sizeof * array.length))[0 .. array.length];//Mallocator.makeArray!(T)(array.length); + foreach(i, ref v;ret)v = array[i]; + //ret[0 .. $] = array; + return ret; + } + + static T* make(T, Args...)(Args args) + { + T* ret = cast(T*)malloc(T.sizeof); + //*ret = T.init; + //static immutable T init = T(); + //memcpy(ret, &init, T.sizeof); + //static if(__traits(hasMember, T, "__ctor"))ret.__ctor(args); + static import std.conv; + static if(__traits(isPOD, T)) + { + static immutable T init = T.init; + memcpy(ret, &init, T.sizeof); + } + else static if(is(T == struct))std.conv.emplace(ret, args); + //else std.conv.emplace(ret, args); + return ret; + } + + static void* alignAlloc(size_t length, size_t alignment) nothrow @nogc + { + + void* ret; + version(Posix)ret = aligned_alloc(alignment, length); + else version(Windows)ret = _aligned_malloc(length, alignment); + else static assert(0, "Unimplemented platform!"); + //posix_memalign(&ret, alignment, length); + return ret; + } + + static void dispose(T)(T object) nothrow @nogc + { + static if(__traits(hasMember, T, "__dtor"))object.__dtor(); + free(cast(void*)object); + } + + static void alignDispose(T)(T object) + { + static if(__traits(hasMember, T, "__dtor"))object.__dtor(); + version(Posix)aligned_free(cast(void*)object); + else version(Windows)_aligned_free(cast(void*)object); + else static assert(0, "Unimplemented platform!"); + + } +} + +struct Mutex +{ + + version (Windows) + { + void initialize() nothrow @nogc + { + InitializeCriticalSection(cast(CRITICAL_SECTION*) &m_handle); + } + + void destroy() nothrow @nogc + { + DeleteCriticalSection(&m_handle); + } + + void lock() nothrow @nogc + { + EnterCriticalSection(&m_handle); + } + + void unlock() nothrow @nogc + { + LeaveCriticalSection(&m_handle); + } + + int tryLock() nothrow @nogc + { + return TryEnterCriticalSection(&m_handle) != 0; + } + + CRITICAL_SECTION m_handle; + } + else version (Posix) + { + void initialize() nothrow @nogc + { + pthread_mutexattr_t attr = void; + + pthread_mutexattr_init(&attr); + + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(cast(pthread_mutex_t*) &m_handle, &attr); + + pthread_mutexattr_destroy(&attr); + } + + void destroy() nothrow @nogc + { + pthread_mutex_destroy(&m_handle); + } + + void lock() nothrow @nogc + { + pthread_mutex_lock(&m_handle); + } + + void unlock() nothrow @nogc + { + pthread_mutex_unlock(&m_handle); + } + + int tryLock() nothrow @nogc + { + return pthread_mutex_trylock(&m_handle) == 0; + } + + private pthread_mutex_t m_handle; + } +} \ No newline at end of file diff --git a/source/ecs/system.d b/source/ecs/system.d index b4ad780..30e9389 100644 --- a/source/ecs/system.d +++ b/source/ecs/system.d @@ -125,14 +125,14 @@ package: //void function(ref EntityManager.CallData data) m_update; void* m_update; ///workaroud for DMD bug with upper line - /*void function(void* system_pointer) m_enable; - void function(void* system_pointer) m_disable; + //void function(void* system_pointer) m_enable; + //void function(void* system_pointer) m_disable; - void function(void* system_pointer) m_create; - void function(void* system_pointer) m_destroy; + //void function(void* system_pointer) m_create; + //void function(void* system_pointer) m_destroy; - void function(void* system_pointer) m_begin; - void function(void* system_pointer) m_end;*/ + //void function(void* system_pointer) m_begin; + //void function(void* system_pointer) m_end; void* m_enable; void* m_disable; diff --git a/source/ecs/vector.d b/source/ecs/vector.d index 47cd761..7c029d0 100644 --- a/source/ecs/vector.d +++ b/source/ecs/vector.d @@ -3,7 +3,7 @@ module ecs.vector; import core.bitop; import core.stdc.stdlib : free, malloc; import core.stdc.string : memcpy, memset; -import std.algorithm : swap; +//import std.algorithm : swap; import std.conv : emplace; import std.traits : hasMember, isCopyable, TemplateOf, Unqual; @@ -28,7 +28,7 @@ public: } - static if (isCopyable!T) { + /*static if (isCopyable!T) { export this(this) { T[] tmp = array[0 .. used]; array = null; @@ -37,7 +37,9 @@ public: } } else { @disable this(this); - } + }*/ + + @disable this(this); export ~this() { clear(); @@ -167,7 +169,8 @@ public: export void remove(size_t elemNum) { destroy(array[elemNum]); - swap(array[elemNum], array[used - 1]); + //swap(array[elemNum], array[used - 1]); + array[elemNum] = array[used - 1]; used--; } diff --git a/source/win_dll.d b/source/win_dll.d index c417b45..1ff8ce4 100644 --- a/source/win_dll.d +++ b/source/win_dll.d @@ -7,7 +7,7 @@ import core.sys.windows.windows; extern(Windows) bool DllMain(void* hInstance, uint ulReason, void*) { - switch (ulReason) + /*switch (ulReason) { default: assert(0); case DLL_PROCESS_ATTACH: @@ -26,5 +26,6 @@ extern(Windows) bool DllMain(void* hInstance, uint ulReason, void*) dll_thread_detach( true, true ); break; } - return true; + return true;*/ + return 0; } \ No newline at end of file diff --git a/tests/tests.d b/tests/tests.d index 30810e2..5b36007 100644 --- a/tests/tests.d +++ b/tests/tests.d @@ -1,7 +1,7 @@ module tests.tests; - +/* import std.experimental.allocator; -import std.experimental.allocator.mallocator; +import std.experimental.allocator.mallocator;*/ import ecs.entity; import ecs.events; @@ -13,6 +13,21 @@ import ecs.core; import core.time; import std.stdio; +version(Windows) +{ + import core.sys.windows.windows; + struct Time + { + static long getUSecTime() + { + LARGE_INTEGER time, freq; + QueryPerformanceFrequency(&freq); + QueryPerformanceCounter(&time); + return time.QuadPart / (freq.QuadPart / 1000_000); + } + } +} + struct TestEvent { mixin ECS.Event; //__gshared ushort event_id; @@ -124,17 +139,20 @@ struct ChangeTestSystem void onCreate() { - writeln("On Change Test System create."); + //writeln("On Change Test System create."); + printf("On Change Test System create."); } void onCreate(int i) { - writeln("On Change Test System create."); + //writeln("On Change Test System create."); + printf("On Change Test System create."); } void onDestroy() { - writeln("On Change Test System destroy."); + //writeln("On Change Test System destroy."); + printf("On Change Test System destroy."); } void onAddEntity(EntitiesData data) @@ -142,30 +160,30 @@ struct ChangeTestSystem //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); + ////writeln("Entity added! ID: ", data.entites[i].id); } void onRemoveEntity(EntitiesData data) { - //writeln("Entity removed! ID: ", data.entites[0].id); + ////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); + ////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."); + ////writeln("On Test System begin."); return true; } void onEnd() { - //writeln("On Test System end."); + ////writeln("On Test System end."); } void initialize(ref Entity entity, ref TestComp comp) @@ -196,34 +214,36 @@ struct TestSystem void onCreate() { - writeln("On Test System create."); + //writeln("On Test System create."); + printf("On Change Test System create."); } void onDestroy() { - writeln("On Test System destroy."); + //writeln("On Test System destroy."); + printf("On Change Test System destroy."); } void onAddEntity(EntitiesData data) { //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) { - //writeln("Entity destroyed ID: ",data.entites[0].id); + ////writeln("Entity destroyed ID: ",data.entites[0].id); }*/ bool onBegin() { - //writeln("On Test System begin."); + ////writeln("On Test System begin."); return true; } void onEnd() { - //writeln("On Test System end."); + ////writeln("On Test System end."); } void initialize(ref Entity entity, ref TestComp comp) @@ -400,14 +420,16 @@ struct TestSystem2 { import std.stdio; - writeln("TestSystem2 enabled"); + //writeln("TestSystem2 enabled"); + printf("TestSystem2 enabled"); } void onDisable() { import std.stdio; - writeln("TestSystem2 disabled"); + //writeln("TestSystem2 disabled"); + printf("TestSystem2 disabled"); } void initialize(ref Entity entity, ref TestComp comp) @@ -446,35 +468,38 @@ struct TestSystem2 }*/ } -int main() +extern(C) int main() { void dispatch(EntityManager.JobGroup jobs) nothrow @nogc { foreach (job; jobs.jobs) { - //writeln(job); + ////writeln(job); job.execute(); } } void writeEntityComponents(Entity* entity) { - write(entity.id); + + printf("EntityID(%u, %u)",entity.id.id,entity.id.counter); + //write(entity.id); TestComp* test_comp = entity.getComponent!TestComp; if (test_comp) - write(*test_comp); + printf("TestComp(%u, %u)",test_comp.a,test_comp.b);//write(*test_comp); TestComp2* test_comp2 = entity.getComponent!TestComp2; if (test_comp2) - write(*test_comp2); + printf("TestComp2(%u, %u)",test_comp2.a,test_comp2.b);//write(*test_comp2); TestComp3* test_comp3 = entity.getComponent!TestComp3; if (test_comp3) - write(*test_comp3); + printf("TestComp3(%u, %u)",test_comp3.gg,test_comp3.bg);//write(*test_comp3); TestComp4* test_comp4 = entity.getComponent!TestComp4; if (test_comp4) - write(*test_comp4); - writeln(); - //writeln((cast(uint*) pp)[0 .. 14], " ", pp); + printf("TestComp4(%u, %u, %u, %u, %u, %u)",test_comp4.gg,test_comp4.bg,test_comp4.a,test_comp4.b,test_comp4.c,test_comp4.g);//write(*test_comp4); + printf("\n"); + //writeln(); + ////writeln((cast(uint*) pp)[0 .. 14], " ", pp); } EntityManager.initialize(1); @@ -484,7 +509,8 @@ int main() gEM.beginRegister(); gEM.registerPass("fixed"); - MonoTime time = MonoTime.currTime; + //MonoTime time = MonoTime.currTime; + long time = Time.getUSecTime(); gEM.registerComponent!TestComp2; gEM.registerComponent!TestComp4; @@ -495,10 +521,13 @@ int main() gEM.registerEvent!TestEvent; gEM.registerEvent!TestEvent2; - ulong dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Components register: ", dur, " usecs"); + /*ulong dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Components register: ", dur, " usecs"); - time = MonoTime.currTime; + time = MonoTime.currTime;*/ + + printf("Components register: %f usecs\n",cast(float)(Time.getUSecTime() - time)); + time = Time.getUSecTime(); gEM.registerSystem!TestSystemWithHighPriority(100, "fixed"); gEM.registerSystem!TestSystem(0); @@ -507,13 +536,15 @@ int main() gEM.registerSystem!Sys2(-100); gEM.registerSystem!Sys3(-2); //gEM.registerSystem!TestSystemWithHighPriority(100); - //gEM.registerSystem!TestSystem2(0); + //gEM.registerSystem!TestSystem2(0);*/ gEM.endRegister(); - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Systems register: ", dur, " usecs"); + /*dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Systems register: ", dur, " usecs"); - time = MonoTime.currTime; + time = MonoTime.currTime;*/ + printf("Systems register: %f usecs\n",cast(float)(Time.getUSecTime() - time)); + time = Time.getUSecTime(); //ushort[3] ids = [TestComp2.component_id, TestComp.component_id, TestComp4.component_id]; ushort[2] ids = [TestComp2.component_id, TestComp.component_id]; @@ -522,11 +553,13 @@ int main() //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[]); + ////writeln(tmpl.info.components[]); //*cast(EntityID*) tmpl.entity_data.ptr = EntityID(1, 1); - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Template allocating: ", dur, " usecs"); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Template allocating: ", dur, " usecs"); + printf("Template allocating: %f usecs\n",cast(float)(Time.getUSecTime() - time)); + time = Time.getUSecTime(); EntityID entity; @@ -536,18 +569,21 @@ int main() EntityManager.EntitiesBlock* block = EntityManager.instance.getMetaData( gEM.getEntity(entity)); EntityManager.EntityInfo* info = block.type_info; - writeln(info.add_listeners); + //writeln(info.add_listeners); //if(info)assert(0); } - time = MonoTime.currTime; + //time = MonoTime.currTime; + time = Time.getUSecTime(); //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); + import ecs.std; + + EntityID[] idss = Mallocator.makeArray!EntityID(5000);//[5000] + //scope(exit)Mallocator.dispose(idss); foreach (i; 0 .. 200) { @@ -560,8 +596,10 @@ int main() } gEM.commit(); - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Entities adding: ", dur, " usecs"); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Entities adding: ", dur, " usecs"); + printf("Entities adding: %f usecs\n",cast(float)(Time.getUSecTime() - time)); + time = Time.getUSecTime(); uint blocks = 0; foreach (info; &gEM.entities_infos.byValue) @@ -573,7 +611,8 @@ int main() blocks++; } } - writeln("Entities blocks: ", blocks); + //writeln("Entities blocks: ", blocks); + printf("Entities blocks: %u\n",blocks); //foreach(j; 0..1_000)gEM.addEntity(tmpl); @@ -590,9 +629,10 @@ int main() EntityID entity2; - time = MonoTime.currTime; + //time = MonoTime.currTime; + time = Time.getUSecTime(); - EntityID[] entities = Mallocator.instance.makeArray!EntityID(1_000_000); + EntityID[] entities = Mallocator.makeArray!EntityID(1_000_000); foreach (i; 0 .. 500_000) { entity2 = gEM.addEntity(tmpl).id; @@ -601,10 +641,12 @@ int main() } gEM.commit(); - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Entities adding2: ", dur, " usecs"); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Entities adding2: ", dur, " usecs"); - time = MonoTime.currTime; + //time = MonoTime.currTime; + printf("Entities adding2: %f usecs\n",cast(float)(Time.getUSecTime() - time)); + time = Time.getUSecTime(); foreach (i; 0 .. 1_000_000) { @@ -613,10 +655,12 @@ int main() } gEM.commit(); - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Components adding: ", dur, " usecs"); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Components adding: ", dur, " usecs"); - time = MonoTime.currTime; + //time = MonoTime.currTime; + printf("Components adding: %f usecs\n",cast(float)(Time.getUSecTime() - time)); + time = Time.getUSecTime(); foreach (i; 0 .. 1_000_000) { @@ -625,44 +669,52 @@ int main() } gEM.commit(); - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Components removing: ", dur, " usecs"); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Components removing: ", dur, " usecs"); + printf("Components removing: %f usecs\n",cast(float)(Time.getUSecTime() - time)); + time = Time.getUSecTime(); - Mallocator.instance.dispose(entities); + Mallocator.dispose(entities); - time = MonoTime.currTime; + //time = MonoTime.currTime; + time = Time.getUSecTime(); gEM.begin(); //gEM.updateMT(); gEM.update(); gEM.end(); - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Update: ", dur, " usecs"); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Update: ", dur, " usecs"); + printf("Update: %f usecs\n",cast(float)(Time.getUSecTime() - time)); writeEntityComponents(gEM.getEntity(entity2)); - time = MonoTime.currTime; + //time = MonoTime.currTime; + time = Time.getUSecTime(); gEM.begin(); gEM.updateMT(); //gEM.update(); gEM.end(); - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Update: ", dur, " usecs"); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Update: ", dur, " usecs"); + printf("Update: %f usecs\n",cast(float)(Time.getUSecTime() - time)); writeEntityComponents(gEM.getEntity(entity2)); - time = MonoTime.currTime; + //time = MonoTime.currTime; + time = Time.getUSecTime(); gEM.begin(); gEM.updateMT(); //gEM.update(); gEM.end(); - dur = (MonoTime.currTime - time).total!"usecs"; - writeln("Update: ", dur, " usecs"); + //dur = (MonoTime.currTime - time).total!"usecs"; + //writeln("Update: ", dur, " usecs"); + printf("Update: %f usecs\n",cast(float)(Time.getUSecTime() - time)); writeEntityComponents(gEM.getEntity(entity2)); @@ -673,10 +725,10 @@ int main() gEM.end(); //Entity* pp;// = gEM.getEntity(entity.id); - //writeln((cast(uint*) pp)[0 .. 14], " ", pp); + ////writeln((cast(uint*) pp)[0 .. 14], " ", pp); writeEntityComponents(gEM.getEntity(entity)); - writeln("Entity, its copy, and template, and default filled tempalte"); + //writeln("Entity, its copy, and template, and default filled tempalte"); gEM.addEntity(tmpl); writeEntityComponents(gEM.getEntity(entity)); writeEntityComponents(gEM.addEntityCopy(entity)); @@ -705,16 +757,22 @@ int main() gEM.removeComponents!(TestComp4)(entity); - gEM.commit();//*/ + gEM.commit(); + + printf("pre end\n"); writeEntityComponents(gEM.getEntity(entity)); //import std.stdio; - //writeln((cast(uint*)tmpl.info.first_block)[0..48]); + ////writeln((cast(uint*)tmpl.info.first_block)[0..48]); gEM.freeTemplate(tmpl); gEM.freeTemplate(tmpl2); gEM.freeTemplate(copy_tempalte); gEM.freeTemplate(copy_default_tempalte); EntityManager.destroy(); + Mallocator.dispose(idss); + + printf("end\n");//*/ + return 0; }