From 5f4ba90b3e97746f7560ca7ce8b59b07fda8a83c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Masiukiewicz?= Date: Thu, 10 Nov 2022 10:18:46 +0100 Subject: [PATCH 1/2] Add unregisterSystem functionality --- source/bubel/ecs/manager.d | 29 +++++++++++++++++++++++++++++ source/bubel/ecs/system.d | 8 ++++++++ 2 files changed, 37 insertions(+) diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index 7861649..3140ca2 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -172,6 +172,8 @@ export struct EntityManager foreach (ref system; systems) { + if (system.isAlive() == false) + continue; if (system.m_empty) { if (system.m_update) @@ -236,6 +238,8 @@ export struct EntityManager foreach (ref system; systems) { + if (system.isAlive() == false) + continue; foreach (caller; system.m_event_callers) { event_callers[caller.id]++; @@ -252,6 +256,8 @@ export struct EntityManager foreach (ref system; systems) { + if (system.isAlive() == false) + continue; foreach (caller; system.m_event_callers) { events[caller.id].callers[event_callers[caller.id]].callback = caller.callback; @@ -328,6 +334,21 @@ export struct EntityManager allocator.freeMemory(); } + + /************************************************************************************************************************ + Unregister given system form EntityManager. + */ + void unregisterSystem(Sys)() + { + assert(register_state, "unregisterSystem must be called between beginRegister() and endRegister()."); + ushort system_id = becsID!Sys; + System* system = getSystem(system_id); + assert(system, "System was not registered"); + assert(system.isAlive, "System already unregistered"); + system.destroy(); + *system = System.init; + } + /************************************************************************************************************************ Same as "void registerSystem(Sys)(int priority, int pass = 0)" but use pass name instead of id. */ @@ -1887,6 +1908,8 @@ export struct EntityManager foreach (i, ref system; systems) { + if (system.isAlive() == false) + continue; if (system.m_empty) continue; if (system.m_update is null) @@ -3095,6 +3118,8 @@ export struct EntityManager foreach (ref system; systems) { + if (system.isAlive() == false) + continue; if (system.enabled && system.m_begin) system.m_execute = (cast(bool function(void*)) system.m_begin)( system.m_system_pointer); @@ -3109,6 +3134,10 @@ export struct EntityManager foreach (ref system; systems) { + if (system.isAlive() == false) + { + continue; + } if (system.enabled && system.m_end) (cast(void function(void*)) system.m_end)(system.m_system_pointer); } diff --git a/source/bubel/ecs/system.d b/source/bubel/ecs/system.d index e571e8b..0da2d96 100644 --- a/source/bubel/ecs/system.d +++ b/source/bubel/ecs/system.d @@ -89,6 +89,14 @@ struct System return cast(const(char)[]) m_name; } + /************************************************************************************************************************ + Return false if system was unregistered, true otherwise. + */ + export bool isAlive() nothrow @nogc + { + return m_system_pointer != null; + } + package: void destroy() From c2ba4c632a4767931478380c77c68c73eeb1bfd9 Mon Sep 17 00:00:00 2001 From: Mergul Date: Sat, 12 Nov 2022 12:10:09 +0100 Subject: [PATCH 2/2] Fixes -Assert if callEntitiesFunction is called for system which is not alive -cleanup and formatting --- dub.json | 2 +- source/bubel/ecs/manager.d | 235 +++++++++++++++++++------------------ 2 files changed, 121 insertions(+), 116 deletions(-) diff --git a/dub.json b/dub.json index b3bfa66..1461c9d 100755 --- a/dub.json +++ b/dub.json @@ -63,7 +63,7 @@ ], "dflags": [ "-unittest", - "-cov" + "-cov=ctfe" ] }, { diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index 3140ca2..323d2ab 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -69,11 +69,10 @@ export struct EntityManager Initialize ECS. */ export static void initialize(uint threads_count = 1, uint page_size = 32768, - uint block_pages_count = 128) + uint block_pages_count = 128) { if (gEntityManager is null) { - //gEntityManager = Mallocator.make!EntityManager(threads_count); gEntityManager = Mallocator.make!EntityManager(threads_count, page_size, block_pages_count); with (gEntityManager) @@ -183,7 +182,7 @@ export struct EntityManager if (system.m_update is null) { if (system.m_add_entity || system.m_remove_entity - || system.m_change_entity || system.m_event_callers.length) + || system.m_change_entity || system.m_event_callers.length) { foreach (info; &entities_infos.byValue) { @@ -281,7 +280,7 @@ export struct EntityManager foreach (ref event; events) { qsort(event.callers.ptr, event.callers.length, - EventCaller.sizeof, &comapreEventCaller); + EventCaller.sizeof, &comapreEventCaller); } //qsort(event_callers.ptr, event_callers.length, EventInfo.sizeof, &compareUShorts); @@ -334,17 +333,19 @@ export struct EntityManager allocator.freeMemory(); } - /************************************************************************************************************************ Unregister given system form EntityManager. */ void unregisterSystem(Sys)() { - assert(register_state, "unregisterSystem must be called between beginRegister() and endRegister()."); + assert(register_state, "unregisterSystem must be called between beginRegister() and endRegister()."); + ushort system_id = becsID!Sys; System* system = getSystem(system_id); + assert(system, "System was not registered"); assert(system.isAlive, "System already unregistered"); + system.destroy(); *system = System.init; } @@ -376,7 +377,7 @@ export struct EntityManager //alias STC = ParameterStorageClass; assert(register_state, - "registerSystem must be called between beginRegister() and endRegister()."); + "registerSystem must be called between beginRegister() and endRegister()."); version (D_BetterC) assert(pass < passes.length, "Update pass doesn't exist."); else @@ -426,7 +427,7 @@ export struct EntityManager // enum EventName = fullyQualifiedName!(Unqual!(EventParamType));//.stringof; ushort evt = events_map.get(cast(char[]) EventName, ushort.max); assert(evt != ushort.max, - "Can't register system \"" ~ SystemName + "Can't register system \"" ~ SystemName ~ "\" due to non existing event \"" ~ EventName ~ "\"."); callers[i].callback = cast(void*)&callEventHandler!(EventParamType); @@ -469,14 +470,14 @@ export struct EntityManager bool checkExcludedComponentsSomething(Sys)() { return __traits(compiles, allSameType!(string, typeof(Sys.ExcludedComponents))) && allSameType!(string, - typeof(Sys.ExcludedComponents)) && isExpressions!(Sys.ExcludedComponents); + typeof(Sys.ExcludedComponents)) && isExpressions!(Sys.ExcludedComponents); } foreach (member; __traits(allMembers, Sys.EntitiesData)) { alias MemberType = typeof(__traits(getMember, Sys.EntitiesData, member)); if (member == "length" || member == "thread_id" || member == "job_id" - || is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) + || is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) { //continue; } @@ -659,7 +660,7 @@ export struct EntityManager } static void allocateSystemComponents(ComponentsIndices!component_counts components_info)( - ref System system) + ref System system) { size_t req = components_info.req.length; size_t opt = components_info.optional.length; @@ -693,14 +694,14 @@ export struct EntityManager bool checkExcludedComponentsSomething(Sys)() { return __traits(compiles, allSameType!(string, typeof(Sys.ExcludedComponents))) && allSameType!(string, - typeof(Sys.ExcludedComponents)) && isExpressions!(Sys.ExcludedComponents); + typeof(Sys.ExcludedComponents)) && isExpressions!(Sys.ExcludedComponents); } foreach (member; __traits(allMembers, Sys.EntitiesData)) { alias MemberType = typeof(__traits(getMember, Sys.EntitiesData, member)); if (member == "length" || member == "thread_id" || member == "job_id" - || is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) + || is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) { if (is(MemberType == Entity[]) || is(MemberType == const(Entity)[])) components_info.entites_array = member; @@ -808,23 +809,23 @@ export struct EntityManager else static if (member == "length") { static assert(isIntegral!(MemberType), - "EntitiesData 'length' member must be integral type."); + "EntitiesData 'length' member must be integral type."); static assert(MemberType.sizeof > 1, - "EntitiesData 'length' member can't be byte or ubyte."); + "EntitiesData 'length' member can't be byte or ubyte."); } else static if (member == "thread_id") { static assert(isIntegral!(MemberType), - "EntitiesData 'thread_id' member must be integral type."); + "EntitiesData 'thread_id' member must be integral type."); static assert(MemberType.sizeof > 1, - "EntitiesData 'thread_id' member can't be byte or ubyte."); + "EntitiesData 'thread_id' member can't be byte or ubyte."); } else static if (member == "job_id") { static assert(isIntegral!(MemberType), - "EntitiesData 'job_id' member must be integral type."); + "EntitiesData 'job_id' member must be integral type."); static assert(MemberType.sizeof > 1, - "EntitiesData 'job_id' member can't be byte or ubyte."); + "EntitiesData 'job_id' member can't be byte or ubyte."); } else static if (!(isArray!(MemberType))) static assert(0, "EntitiesData members should be arrays of elements!"); @@ -838,7 +839,7 @@ export struct EntityManager ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); version (D_BetterC) assert(comp != ushort.max, - "Can't register system \"" ~ SystemName + "Can't register system \"" ~ SystemName ~ "\" due to non existing component."); else assert(comp != ushort.max, "Can't register system \"" ~ SystemName @@ -850,7 +851,7 @@ export struct EntityManager ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); version (D_BetterC) assert(comp != ushort.max, - "Can't register system \"" ~ SystemName + "Can't register system \"" ~ SystemName ~ "\" due to non existing component."); else assert(comp != ushort.max, "Can't register system \"" ~ SystemName @@ -862,7 +863,7 @@ export struct EntityManager ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); version (D_BetterC) assert(comp != ushort.max, - "Can't register system \"" ~ SystemName + "Can't register system \"" ~ SystemName ~ "\" due to non existing component."); else assert(comp != ushort.max, "Can't register system \"" ~ SystemName @@ -874,7 +875,7 @@ export struct EntityManager ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); version (D_BetterC) assert(comp != ushort.max, - "Can't register system \"" ~ SystemName + "Can't register system \"" ~ SystemName ~ "\" due to non existing component."); else assert(comp != ushort.max, "Can't register system \"" ~ SystemName @@ -886,7 +887,7 @@ export struct EntityManager ushort comp = components_map.get(cast(char[]) comp_info.type, ushort.max); version (D_BetterC) assert(comp != ushort.max, - "Can't register system \"" ~ SystemName + "Can't register system \"" ~ SystemName ~ "\" due to non existing component."); else assert(comp != ushort.max, "Can't register system \"" ~ SystemName @@ -896,14 +897,14 @@ export struct EntityManager } static void fillInputData(ref Sys.EntitiesData input_data, EntityInfo* info, - EntitiesBlock* block, uint offset, uint entities_count, System* system) + EntitiesBlock* block, uint offset, uint entities_count, System* system) { //enum ComponentsIndices components_info = getComponentsInfo(); static if (components_info.entites_array) { __traits(getMember, input_data, components_info.entites_array) = ( - cast(Entity*) block.dataBegin())[offset .. entities_count]; + cast(Entity*) block.dataBegin())[offset .. entities_count]; } static if (hasMember!(Sys.EntitiesData, "length")) @@ -923,8 +924,7 @@ export struct EntityManager __traits(getMember, input_data, comp_info.name) = ( cast(typeof( (typeof(__traits(getMember, Sys.EntitiesData, comp_info.name))).init[0] - )*) - (cast(void*) block + info.deltas[system.m_components[iii]]) + )*)(cast(void*) block + info.deltas[system.m_components[iii]]) )[offset .. entities_count]; } @@ -932,7 +932,7 @@ export struct EntityManager .. components_info.m_optional_counter]) { if (system.m_optional_components[iii] < info.deltas.length - && info.deltas[system.m_optional_components[iii]] != 0) + && info.deltas[system.m_optional_components[iii]] != 0) { __traits(getMember, input_data, comp_info.name) = (cast(ForeachType!(typeof(__traits(getMember, Sys.EntitiesData, comp_info.name)))*)(cast( @@ -1031,7 +1031,7 @@ export struct EntityManager static if (hasMember!(Sys.EntitiesData, "thread_id")) { input_data.thread_id = cast( - typeof(input_data.thread_id)) data.thread_id; + typeof(input_data.thread_id)) data.thread_id; } static if (hasMember!(Sys.EntitiesData, "job_id")) @@ -1042,7 +1042,7 @@ export struct EntityManager //s.onUpdate(input_data); (cast(typeof(&__traits(getOverloads, s, "onUpdate")[OnUpdateOverloadNum])) data.update_delegate)( - input_data); + input_data); } block = block.next_block; offset = 0; @@ -1112,15 +1112,15 @@ export struct EntityManager foreach (func; __traits(getOverloads, Sys, func_name)) { static if ((Parameters!(func)).length == 1 - && is(Parameters!(func)[0] == Sys.EntitiesData) - && is(ReturnType!(func) == RetType)) + && is(Parameters!(func)[0] == Sys.EntitiesData) + && is(ReturnType!(func) == RetType)) { static RetType callFunc(ref ListenerCallData data) { Sys* s = cast(Sys*) data.system.m_system_pointer; Sys.EntitiesData input_data; fillInputData(input_data, data.block.type_info, - data.block, data.begin, data.end, data.system); + data.block, data.begin, data.end, data.system); static if (is(RetTyp == void)) mixin("s." ~ func_name ~ "(input_data)"); else @@ -1141,8 +1141,8 @@ export struct EntityManager foreach (func; __traits(getOverloads, Sys, func_name)) { static if ((Parameters!(func)).length == 1 - && is(Parameters!(func)[0] == EntityInfo*) - && is(ReturnType!(func) == RetType)) + && is(Parameters!(func)[0] == EntityInfo*) + && is(ReturnType!(func) == RetType)) { static RetType callFunc(void* system_pointer, EntityInfo* info) { @@ -1177,14 +1177,16 @@ export struct EntityManager system.m_priority = priority; //(cast(Sys*) system.m_system_pointer).__ecsInitialize(); //system.jobs = (cast(Sys*) system.m_system_pointer)._ecs_jobs; - static if(__traits(hasMember, Sys ,"__becs_jobs_count"))system.jobs = Mallocator.makeArray!(Job)(Sys.__becs_jobs_count); - else system.jobs = Mallocator.makeArray!(Job)(32); + static if (__traits(hasMember, Sys, "__becs_jobs_count")) + system.jobs = Mallocator.makeArray!(Job)(Sys.__becs_jobs_count); + else + system.jobs = Mallocator.makeArray!(Job)(32); static if (OnUpdateOverloadNum != -1) { Sys* s = cast(Sys*) system.m_system_pointer; system.m_update_delegate = cast(void delegate())&__traits(getOverloads, - s, "onUpdate")[OnUpdateOverloadNum]; + s, "onUpdate")[OnUpdateOverloadNum]; } genCompList(system, components_map); @@ -1192,10 +1194,10 @@ export struct EntityManager foreach (iii, comp_info; components_info.readonlyDeps) { ushort comp = external_dependencies_map.get(cast(const(char)[]) comp_info.type, - ushort.max); + ushort.max); version (D_BetterC) assert(comp != ushort.max, - "Can't register system \"" ~ SystemName + "Can't register system \"" ~ SystemName ~ "\" due to non existing dependency."); else assert(comp != ushort.max, "Can't register system \"" ~ SystemName @@ -1208,7 +1210,7 @@ export struct EntityManager ushort comp = external_dependencies_map.get(cast(char[]) comp_info.type, ushort.max); version (D_BetterC) assert(comp != ushort.max, - "Can't register system \"" ~ SystemName + "Can't register system \"" ~ SystemName ~ "\" due to non existing dependency."); else assert(comp != ushort.max, "Can't register system \"" ~ SystemName @@ -1300,8 +1302,8 @@ export struct EntityManager // } static if (hasMember!(Comp, "onDestroy") && isFunction!(Comp.onDestroy) - && is(ReturnType!(Comp.onDestroy) == void) - && Parameters!(Comp.onDestroy).length == 0) + && is(ReturnType!(Comp.onDestroy) == void) + && Parameters!(Comp.onDestroy).length == 0) { static void callDestroy(void* pointer) nothrow @nogc { @@ -1312,7 +1314,7 @@ export struct EntityManager } static if (hasMember!(Comp, "onCreate") && isFunction!(Comp.onCreate) - && is(ReturnType!(Comp.onCreate) == void) && Parameters!(Comp.onCreate).length == 0) + && is(ReturnType!(Comp.onCreate) == void) && Parameters!(Comp.onCreate).length == 0) { static void callCreate(void* pointer) nothrow @nogc { @@ -1358,7 +1360,7 @@ export struct EntityManager // } static if (hasMember!(Ev, "onDestroy") && isFunction!(Ev.onDestroy) - && is(ReturnType!(Ev.onDestroy) == void) && Parameters!(Ev.onDestroy).length == 0) + && is(ReturnType!(Ev.onDestroy) == void) && Parameters!(Ev.onDestroy).length == 0) { static void callDestroy(void* pointer) { @@ -1392,10 +1394,10 @@ export struct EntityManager Sys* s; static assert(isDelegate!func, "Function must be delegate."); static assert(__traits(hasMember, Sys, "EntitiesData"), - "Can't call function with system which hasn't EntitesData structure."); + "Can't call function with system which hasn't EntitesData structure."); ///TODO: make possibly to call function to group without system with onUpdate function static assert(__traits(hasMember, Sys, "onUpdate"), - "Can't call function with system which hasn't onUpdate function callback."); + "Can't call function with system which hasn't onUpdate function callback."); // static assert(is(SetFunctionAttributes!(T, functionLinkage!(s.onUpdate), // functionAttributes!(s.onUpdate)) == typeof(&s.onUpdate)), // "Function must match system update function."); FIXME: It's lead to crash on android build @@ -1403,7 +1405,9 @@ export struct EntityManager System* system = getSystem(becsID!Sys); assert(system != null, - "System must be registered in EntityManager before any funcion can be called."); + "System must be registered in EntityManager before any funcion can be called."); + assert(system.isAlive(), "System must be alive (registered) in order to call entities function on its entities"); + if (!system.m_any_system_caller) return; @@ -1445,7 +1449,7 @@ export struct EntityManager foreach (info; caller.infos) { CallData data = CallData(caller.system_id, sys, info, - sys.m_update_delegate); + sys.m_update_delegate); data.update(); } } @@ -1467,7 +1471,7 @@ export struct EntityManager assert(!register_state); assert(pass < passes.length); assert(m_dispatch_jobs, - "Can't update with multithreading without JobDispatch function. Please use setJobDispatchFunc()."); + "Can't update with multithreading without JobDispatch function. Please use setJobDispatchFunc()."); Vector!CallData tmp_datas; tmp_datas.reserve(8); @@ -1480,7 +1484,7 @@ export struct EntityManager void nextJob() { CallData[] callers = m_call_data_allocator.getCallData( - cast(uint) tmp_datas.length); + cast(uint) tmp_datas.length); //callers[0 .. $] = tmp_datas[0 .. $]; memcpy(callers.ptr, &tmp_datas[0], CallData.sizeof * tmp_datas.length); tmp_datas.clear(); @@ -1535,7 +1539,7 @@ export struct EntityManager //if this info will fill job if ((blocks_count - 1) * info.max_entities + entities_count - + info.last_block.entities_count - first_elem >= entities_per_job) + + info.last_block.entities_count - first_elem >= entities_per_job) { int reamaining_entities = (entities_per_job - entities_count - ( first_block.entities_count - first_elem)); @@ -1556,9 +1560,9 @@ export struct EntityManager assert(entities_per_job == full_blocks_count * info.max_entities + entities_count + ( first_block.entities_count - first_elem)); CallData data = CallData(caller.system_id, sys, - info, sys.m_update_delegate, first_block, - cast(ushort)(full_blocks_count + 1), - cast(ushort) first_elem, 0); + info, sys.m_update_delegate, first_block, + cast(ushort)(full_blocks_count + 1), + cast(ushort) first_elem, 0); tmp_datas.add(data); first_elem = 0; blocks_count -= full_blocks_count + 1; @@ -1567,14 +1571,14 @@ export struct EntityManager else { entities_count += full_blocks_count * info.max_entities + ( - first_block.entities_count - first_elem); // - first_elem; + first_block.entities_count - first_elem); // - first_elem; uint last_elem = entities_per_job - entities_count; // + first_elem - 1; assert(last_elem > 0); assert(last_elem <= block.entities_count); CallData data = CallData(caller.system_id, sys, - info, sys.m_update_delegate, first_block, - cast(ushort)(full_blocks_count + 2), - cast(ushort) first_elem, cast(ushort) last_elem); + info, sys.m_update_delegate, first_block, + cast(ushort)(full_blocks_count + 2), + cast(ushort) first_elem, cast(ushort) last_elem); tmp_datas.add(data); first_elem = last_elem; blocks_count -= full_blocks_count + 1; @@ -1591,8 +1595,8 @@ export struct EntityManager uint last_elem = entities_per_job - entities_count; assert(last_elem > 0); CallData data = CallData(caller.system_id, sys, - info, sys.m_update_delegate, first_block, 1, - cast(ushort) first_elem, cast(ushort)(first_elem + last_elem)); + info, sys.m_update_delegate, first_block, 1, + cast(ushort) first_elem, cast(ushort)(first_elem + last_elem)); tmp_datas.add(data); first_elem += last_elem; assert(first_elem <= first_block.entities_count); @@ -1612,7 +1616,7 @@ export struct EntityManager { //take whole info blocks CallData data = CallData(caller.system_id, sys, info, sys.m_update_delegate, - first_block, cast(ushort) blocks_count, cast(ushort) first_elem); + first_block, cast(ushort) blocks_count, cast(ushort) first_elem); tmp_datas.add(data); entities_count += (blocks_count - 1) * info.max_entities + info.last_block.entities_count - first_elem; @@ -1627,7 +1631,7 @@ export struct EntityManager } export void setMultithreadingCallbacks(void delegate(JobGroup) dispatch_callback, - uint delegate() get_id_callback) + uint delegate() get_id_callback) { m_dispatch_jobs = cast(void delegate(JobGroup jobs) nothrow @nogc) dispatch_callback; m_thread_id_func = cast(uint delegate() nothrow @nogc) get_id_callback; @@ -1692,7 +1696,7 @@ export struct EntityManager if (components[comp].size == 0) continue; memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], - components[comp].init_data.ptr, components[comp].size); + components[comp].init_data.ptr, components[comp].size); } } else @@ -1703,8 +1707,8 @@ export struct EntityManager if (components[comp].size == 0) continue; memcpy(cast(void*) temp.entity_data.ptr + info.tmpl_deltas[comp], - cast(void*) block + info.deltas[comp] + components[comp].size * index, - components[comp].size); + cast(void*) block + info.deltas[comp] + components[comp].size * index, + components[comp].size); } } @@ -1753,7 +1757,7 @@ export struct EntityManager if (components[comp].size == 0) continue; memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], - components[comp].init_data.ptr, components[comp].size); + components[comp].init_data.ptr, components[comp].size); } return temp; @@ -1769,18 +1773,18 @@ export struct EntityManager remove_components_ids = array of components to remove from base template */ export EntityTemplate* allocateTemplate(EntityTemplate* base_tmpl, - ushort[] components_ids, ushort[] remove_components_ids = null) + ushort[] components_ids, ushort[] remove_components_ids = null) { size_t len = base_tmpl.info.components.length + components_ids.length; ushort[] ids = (cast(ushort*) alloca(ushort.sizeof * len))[0 .. len]; memcpy(ids.ptr, base_tmpl.info.components.ptr, - ushort.sizeof * base_tmpl.info.components.length); + ushort.sizeof * base_tmpl.info.components.length); memcpy(ids.ptr + base_tmpl.info.components.length, components_ids.ptr, - ushort.sizeof * components_ids.length); + ushort.sizeof * components_ids.length); qsort(ids.ptr, ids.length, ushort.sizeof, &compareUShorts); qsort(remove_components_ids.ptr, remove_components_ids.length, - ushort.sizeof, &compareUShorts); + ushort.sizeof, &compareUShorts); { uint k = 0; uint j = 1; @@ -1820,20 +1824,20 @@ export struct EntityManager foreach (comp; info.components) { if (comp < base_tmpl.info.tmpl_deltas.length - && base_tmpl.info.tmpl_deltas[comp] != ushort.max) //copy data from base component - { + && base_tmpl.info.tmpl_deltas[comp] != ushort.max) //copy data from base component + { if (components[comp].size == 0) continue; memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], - base_tmpl.entity_data.ptr + base_tmpl.info.tmpl_deltas[comp], - components[comp].size); + base_tmpl.entity_data.ptr + base_tmpl.info.tmpl_deltas[comp], + components[comp].size); } else //fill with default data { if (components[comp].size == 0) continue; memcpy(temp.entity_data.ptr + info.tmpl_deltas[comp], - components[comp].init_data.ptr, components[comp].size); + components[comp].init_data.ptr, components[comp].size); } } @@ -1887,7 +1891,7 @@ export struct EntityManager alignNum(info.size, info.alignment); uint block_memory = cast(uint)( - m_page_size - EntitiesBlock.sizeof - (info.size - components_size)); + m_page_size - EntitiesBlock.sizeof - (info.size - components_size)); //uint entity_comps_size = EntityID.sizeof; uint mem_begin = EntitiesBlock.sizeof; @@ -1915,15 +1919,14 @@ export struct EntityManager if (system.m_update is null) { if (system.m_add_entity || system.m_remove_entity - || system.m_change_entity || system.m_event_callers.length) + || system.m_change_entity || system.m_event_callers.length) connectListenerToEntityInfo(*info, cast(uint) i); continue; } addSystemCaller(*info, cast(uint) i); } - info.comp_add_info = Mallocator.makeArray!(EntityInfo*)(gEntityManager.components.length); - //info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(gEntityManager.components.length); + info.comp_add_info = Mallocator.makeArray!(EntityInfo*)(info.deltas.length); info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(info.deltas.length); foreach (comp; info.components) @@ -2082,7 +2085,9 @@ export struct EntityManager } ///call Custom Entity Filter test if function exists - if(system.m_filter_entity && !(cast(bool function(void* system_pointer, EntityInfo* info) @nogc nothrow)system.m_filter_entity)(system, &entity))return; + if (system.m_filter_entity && !(cast(bool function(void* system_pointer, EntityInfo* info) @nogc nothrow) system + .m_filter_entity)(system, &entity)) + return; entity.systems[system_id] = true; } @@ -2127,7 +2132,8 @@ export struct EntityManager System* system = &systems[system_id]; connectListenerToEntityInfo(info, system_id); - if(!info.systems[system_id])return; + if (!info.systems[system_id]) + return; uint index = 0; for (; index < passes[system.m_pass].system_callers.length; index++) @@ -2236,7 +2242,7 @@ export struct EntityManager if (comp_size == 0) continue; memcpy(cast(void*) new_block + new_info.deltas[comp] + new_block.entities_count * comp_size, - cast(void*) block + info.deltas[comp] + ind * comp_size, comp_size); + cast(void*) block + info.deltas[comp] + ind * comp_size, comp_size); } new_block.entities_count++; @@ -2250,7 +2256,7 @@ export struct EntityManager if (!info.systems[listener]) { callAddEntityListener(&systems[listener], new_info, new_block, - new_block.entities_count - 1, new_block.entities_count); + new_block.entities_count - 1, new_block.entities_count); } } } @@ -2262,7 +2268,7 @@ export struct EntityManager if (info.systems[listener]) { callChangeEntityListener(&systems[listener], new_info, new_block, - new_block.entities_count - 1, new_block.entities_count, del_ids); + new_block.entities_count - 1, new_block.entities_count, del_ids); } } } @@ -2413,7 +2419,7 @@ export struct EntityManager if (!info.systems[listener]) { callAddEntityListener(&systems[listener], new_info, new_block, - new_block.entities_count - 1, new_block.entities_count); + new_block.entities_count - 1, new_block.entities_count); } } } @@ -2425,7 +2431,7 @@ export struct EntityManager if (info.systems[listener]) { callChangeEntityListener(&systems[listener], new_info, new_block, - new_block.entities_count - 1, new_block.entities_count, new_ids); + new_block.entities_count - 1, new_block.entities_count, new_ids); } } } @@ -2468,7 +2474,7 @@ export struct EntityManager { if (components[ref_.component_id].size != 0) data.changeEntitiesList.add( - (cast(ubyte*) ref_.ptr)[0 .. components[ref_.component_id].size]); + (cast(ubyte*) ref_.ptr)[0 .. components[ref_.component_id].size]); } } @@ -2518,12 +2524,12 @@ export struct EntityManager ushort size = components[comp].size; if (size != 0) memcpy(cast(void*) new_block + info.deltas[comp] + new_id * size, - cast(void*) block + info.deltas[comp] + size * index, size); + cast(void*) block + info.deltas[comp] + size * index, size); if (components[comp].create_callback) { components[comp].create_callback( - cast(void*) new_block + info.deltas[comp] + new_id * size); + cast(void*) new_block + info.deltas[comp] + new_id * size); } } @@ -2580,7 +2586,7 @@ export struct EntityManager uint size = components[comp].size; if (size != 0) memcpy(cast(void*) block + info.deltas[comp] + size * id, - tmpl.entity_data.ptr + info.tmpl_deltas[comp], size); + tmpl.entity_data.ptr + info.tmpl_deltas[comp], size); } foreach (comp; replacement) @@ -2602,7 +2608,7 @@ export struct EntityManager if (components[comp].create_callback) { components[comp].create_callback( - cast(void*) block + info.deltas[comp] + id * components[comp].size); + cast(void*) block + info.deltas[comp] + id * components[comp].size); } } @@ -2737,7 +2743,7 @@ export struct EntityManager } private void removeEntityNoID(Entity* entity, EntitiesBlock* block, - bool call_destructors = false) nothrow @nogc + bool call_destructors = false) nothrow @nogc { EntityInfo* info = block.type_info; @@ -2869,7 +2875,7 @@ export struct EntityManager } private static void callAddEntityListener(System* system, EntityInfo* info, - EntitiesBlock* block, int begin, int end) @nogc nothrow + EntitiesBlock* block, int begin, int end) @nogc nothrow { ListenerCallData data; data.system = system; @@ -2880,7 +2886,7 @@ export struct EntityManager } private void callRemoveEntityListeners(EntityInfo* info, EntitiesBlock* block, int begin, - int end) @nogc nothrow + int end) @nogc nothrow { foreach (listener; info.remove_listeners) { @@ -2890,7 +2896,7 @@ export struct EntityManager } private static void callRemoveEntityListener(System* system, - EntityInfo* info, EntitiesBlock* block, int begin, int end) @nogc nothrow + EntityInfo* info, EntitiesBlock* block, int begin, int end) @nogc nothrow { ListenerCallData data; data.system = system; @@ -2901,7 +2907,7 @@ export struct EntityManager } private void callChangeEntityListener(System* system, EntityInfo* info, - EntitiesBlock* block, int begin, int end, ushort[] ch_ids) @nogc nothrow + EntitiesBlock* block, int begin, int end, ushort[] ch_ids) @nogc nothrow { int i = 0; int j = 0; @@ -3055,7 +3061,7 @@ export struct EntityManager foreach (caller; events[i].callers) { if (call_data.block.type_info.systems[caller.system.m_id] == false - || !caller.system.enabled || !caller.system.willExecute) + || !caller.system.enabled || !caller.system.willExecute) continue; call_data.system_pointer = caller.system.m_system_pointer; (cast(void function(ref EventCallData) nothrow @nogc) caller @@ -3122,7 +3128,7 @@ export struct EntityManager continue; if (system.enabled && system.m_begin) system.m_execute = (cast(bool function(void*)) system.m_begin)( - system.m_system_pointer); + system.m_system_pointer); } } @@ -3135,9 +3141,8 @@ export struct EntityManager foreach (ref system; systems) { if (system.isAlive() == false) - { continue; - } + if (system.enabled && system.m_end) (cast(void function(void*)) system.m_end)(system.m_system_pointer); } @@ -3276,7 +3281,7 @@ export struct EntityManager } qsort(pass.system_callers.array.ptr, pass.system_callers.length, - (SystemCaller*).sizeof, &compareSystems); + (SystemCaller*).sizeof, &compareSystems); foreach (i, caller; pass.system_callers) caller.job_group.id = cast(uint) i; @@ -3403,7 +3408,7 @@ export struct EntityManager if (comp_add_info.length <= id) { EntityInfo*[] new_infos = Mallocator.makeArray!(EntityInfo*)( - gEntityManager.components.length); + gEntityManager.components.length); if (comp_add_info !is null) { //new_infos[0 .. comp_add_info.length] = comp_add_info[0 .. $]; @@ -3448,7 +3453,7 @@ export struct EntityManager return new_info; } - EntityInfo* getNewInfoRemove(ushort id) return + EntityInfo* getNewInfoRemove(ushort id) return { /*if (comp_rem_info.length <= id) { @@ -3491,7 +3496,8 @@ export struct EntityManager export bool hasComponent(ushort component_id) { - if(component_id >= deltas.length || !deltas[component_id])return false; + if (component_id >= deltas.length || !deltas[component_id]) + return false; return true; } @@ -3560,7 +3566,7 @@ export struct EntityManager struct EntitiesBlock { ///return pointer to first element in block - export void* dataBegin() nothrow @nogc pure return + export void* dataBegin() nothrow @nogc pure return { ushort dif = EntitiesBlock.sizeof; return cast(void*)&this + dif; @@ -3643,7 +3649,6 @@ export struct EntityManager export void execute() nothrow @nogc { - //gEntityManager.getThreadID(); foreach (ref caller; callers) { caller.thread_id = gEntityManager.threadID(); @@ -3688,32 +3693,32 @@ export struct EntityManager struct ThreadData { - ref Vector!EntityID entitesToRemove() @nogc nothrow return + ref Vector!EntityID entitesToRemove() @nogc nothrow return { return entities_to_remove[data_index]; } - ref SimpleVector changeEntitiesList() @nogc nothrow return + ref SimpleVector changeEntitiesList() @nogc nothrow return { return change_entities_list[data_index]; } - ref Vector!(EntityInfo*) infosToUpdate() @nogc nothrow return + ref Vector!(EntityInfo*) infosToUpdate() @nogc nothrow return { return infos_to_update[data_index]; } - ref Vector!EntityID entitiesToRemovePrev() @nogc nothrow return + ref Vector!EntityID entitiesToRemovePrev() @nogc nothrow return { return entities_to_remove[1 - data_index]; } - ref SimpleVector changeEntitiesListPrev() @nogc nothrow return + ref SimpleVector changeEntitiesListPrev() @nogc nothrow return { return change_entities_list[1 - data_index]; } - ref Vector!(EntityInfo*) infosToUpdatePrev() @nogc nothrow return + ref Vector!(EntityInfo*) infosToUpdatePrev() @nogc nothrow return { return infos_to_update[1 - data_index]; } @@ -3849,5 +3854,5 @@ export struct EntityManager return ret; } } - + }