Merge branch 'unregister_system' into 'master'

Add unregisterSystem functionality

See merge request Mergul/bubel-ecs!25
This commit is contained in:
Dawid Masiukiewicz 2022-11-12 11:15:31 +00:00
commit 6af3028070
3 changed files with 154 additions and 112 deletions

View file

@ -63,7 +63,7 @@
], ],
"dflags": [ "dflags": [
"-unittest", "-unittest",
"-cov" "-cov=ctfe"
] ]
}, },
{ {

View file

@ -73,7 +73,6 @@ export struct EntityManager
{ {
if (gEntityManager is null) if (gEntityManager is null)
{ {
//gEntityManager = Mallocator.make!EntityManager(threads_count);
gEntityManager = Mallocator.make!EntityManager(threads_count, page_size, block_pages_count); gEntityManager = Mallocator.make!EntityManager(threads_count, page_size, block_pages_count);
with (gEntityManager) with (gEntityManager)
@ -172,6 +171,8 @@ export struct EntityManager
foreach (ref system; systems) foreach (ref system; systems)
{ {
if (system.isAlive() == false)
continue;
if (system.m_empty) if (system.m_empty)
{ {
if (system.m_update) if (system.m_update)
@ -236,6 +237,8 @@ export struct EntityManager
foreach (ref system; systems) foreach (ref system; systems)
{ {
if (system.isAlive() == false)
continue;
foreach (caller; system.m_event_callers) foreach (caller; system.m_event_callers)
{ {
event_callers[caller.id]++; event_callers[caller.id]++;
@ -252,6 +255,8 @@ export struct EntityManager
foreach (ref system; systems) foreach (ref system; systems)
{ {
if (system.isAlive() == false)
continue;
foreach (caller; system.m_event_callers) foreach (caller; system.m_event_callers)
{ {
events[caller.id].callers[event_callers[caller.id]].callback = caller.callback; events[caller.id].callers[event_callers[caller.id]].callback = caller.callback;
@ -328,6 +333,23 @@ export struct EntityManager
allocator.freeMemory(); 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. Same as "void registerSystem(Sys)(int priority, int pass = 0)" but use pass name instead of id.
*/ */
@ -902,8 +924,7 @@ export struct EntityManager
__traits(getMember, input_data, comp_info.name) = ( __traits(getMember, input_data, comp_info.name) = (
cast(typeof( cast(typeof(
(typeof(__traits(getMember, Sys.EntitiesData, comp_info.name))).init[0] (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]; )[offset .. entities_count];
} }
@ -1156,8 +1177,10 @@ export struct EntityManager
system.m_priority = priority; system.m_priority = priority;
//(cast(Sys*) system.m_system_pointer).__ecsInitialize(); //(cast(Sys*) system.m_system_pointer).__ecsInitialize();
//system.jobs = (cast(Sys*) system.m_system_pointer)._ecs_jobs; //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); static if (__traits(hasMember, Sys, "__becs_jobs_count"))
else system.jobs = Mallocator.makeArray!(Job)(32); system.jobs = Mallocator.makeArray!(Job)(Sys.__becs_jobs_count);
else
system.jobs = Mallocator.makeArray!(Job)(32);
static if (OnUpdateOverloadNum != -1) static if (OnUpdateOverloadNum != -1)
{ {
@ -1383,6 +1406,8 @@ export struct EntityManager
System* system = getSystem(becsID!Sys); System* system = getSystem(becsID!Sys);
assert(system != null, 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) if (!system.m_any_system_caller)
return; return;
@ -1887,6 +1912,8 @@ export struct EntityManager
foreach (i, ref system; systems) foreach (i, ref system; systems)
{ {
if (system.isAlive() == false)
continue;
if (system.m_empty) if (system.m_empty)
continue; continue;
if (system.m_update is null) if (system.m_update is null)
@ -1899,8 +1926,7 @@ export struct EntityManager
addSystemCaller(*info, cast(uint) i); addSystemCaller(*info, cast(uint) i);
} }
info.comp_add_info = Mallocator.makeArray!(EntityInfo*)(gEntityManager.components.length); info.comp_add_info = Mallocator.makeArray!(EntityInfo*)(info.deltas.length);
//info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(gEntityManager.components.length);
info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(info.deltas.length); info.comp_rem_info = Mallocator.makeArray!(EntityInfo*)(info.deltas.length);
foreach (comp; info.components) foreach (comp; info.components)
@ -2059,7 +2085,9 @@ export struct EntityManager
} }
///call Custom Entity Filter test if function exists ///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; entity.systems[system_id] = true;
} }
@ -2104,7 +2132,8 @@ export struct EntityManager
System* system = &systems[system_id]; System* system = &systems[system_id];
connectListenerToEntityInfo(info, system_id); connectListenerToEntityInfo(info, system_id);
if(!info.systems[system_id])return; if (!info.systems[system_id])
return;
uint index = 0; uint index = 0;
for (; index < passes[system.m_pass].system_callers.length; index++) for (; index < passes[system.m_pass].system_callers.length; index++)
@ -3095,6 +3124,8 @@ export struct EntityManager
foreach (ref system; systems) foreach (ref system; systems)
{ {
if (system.isAlive() == false)
continue;
if (system.enabled && system.m_begin) if (system.enabled && system.m_begin)
system.m_execute = (cast(bool function(void*)) system.m_begin)( system.m_execute = (cast(bool function(void*)) system.m_begin)(
system.m_system_pointer); system.m_system_pointer);
@ -3109,6 +3140,9 @@ export struct EntityManager
foreach (ref system; systems) foreach (ref system; systems)
{ {
if (system.isAlive() == false)
continue;
if (system.enabled && system.m_end) if (system.enabled && system.m_end)
(cast(void function(void*)) system.m_end)(system.m_system_pointer); (cast(void function(void*)) system.m_end)(system.m_system_pointer);
} }
@ -3462,7 +3496,8 @@ export struct EntityManager
export bool hasComponent(ushort component_id) 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; return true;
} }
@ -3614,7 +3649,6 @@ export struct EntityManager
export void execute() nothrow @nogc export void execute() nothrow @nogc
{ {
//gEntityManager.getThreadID();
foreach (ref caller; callers) foreach (ref caller; callers)
{ {
caller.thread_id = gEntityManager.threadID(); caller.thread_id = gEntityManager.threadID();

View file

@ -89,6 +89,14 @@ struct System
return cast(const(char)[]) m_name; 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: package:
void destroy() void destroy()