From 0702b007d17546243ca8172ce26148331220d99e Mon Sep 17 00:00:00 2001 From: Mergul Date: Thu, 9 Mar 2023 11:04:12 +0100 Subject: [PATCH] Fix unregisterSystem function and add function to get m_system_pointer from System --- source/bubel/ecs/hash_map.d | 6 ++-- source/bubel/ecs/manager.d | 26 ++++++++++------ source/bubel/ecs/system.d | 62 ++++++++++++++++++++++++++++++++++--- 3 files changed, 78 insertions(+), 16 deletions(-) diff --git a/source/bubel/ecs/hash_map.d b/source/bubel/ecs/hash_map.d index 0ad4dc5..66a0756 100755 --- a/source/bubel/ecs/hash_map.d +++ b/source/bubel/ecs/hash_map.d @@ -341,7 +341,7 @@ nothrow: int result; foreach (ref Key k; this) { - result = (cast(int delegate(ref Key k) nothrow)dg)(k); + result = (cast(int delegate(ref Key k) nothrow @nogc)dg)(k); if (result) break; } @@ -353,7 +353,7 @@ nothrow: int result; foreach (ref Value v; this) { - result = (cast(int delegate(ref Value v) nothrow)dg)(v); + result = (cast(int delegate(ref Value v) nothrow @nogc)dg)(v); if (result) break; } @@ -365,7 +365,7 @@ nothrow: int result; foreach (ref Key k, ref Value v; this) { - result = (cast(int delegate(ref Key k, ref Value v) nothrow)dg)(k, v); + result = (cast(int delegate(ref Key k, ref Value v) nothrow @nogc)dg)(k, v); if (result) break; } diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index a34d81c..801068d 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -76,7 +76,7 @@ export struct EntityManager UpdatePass* pass = Mallocator.make!UpdatePass; pass.name = Mallocator.makeArray(cast(char[]) "update"); passes.add(pass); - passes_map.add(cast(string) pass.name, cast(ushort)(passes.length - 1)); + passes_map.add(cast(const(char)[]) pass.name, cast(ushort)(passes.length - 1)); } } } @@ -84,7 +84,7 @@ export struct EntityManager /************************************************************************************************************************ Deinitialize and destroy ECS. This function release whole memory. */ - export static void destroy() + export static void destroy() nothrow @nogc { if (gEntityManager is null) return; @@ -334,16 +334,23 @@ export struct 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"); + unregisterSystem(system); + } - system.destroy(); - *system = System.init; + /************************************************************************************************************************ + Unregister given system form EntityManager. + */ + export void unregisterSystem(System* system) nothrow @nogc + { + assert(register_state, "unregisterSystem must be called between beginRegister() and endRegister()."); + assert(system !is null, "System was not registered"); + assert(system.isAlive, "System already unregistered"); + + //disable, destroy and dispose user created system but keep name and other data + system.destroySystemData(); } /************************************************************************************************************************ @@ -1248,7 +1255,8 @@ export struct EntityManager } /************************************************************************************************************************ - Return system ECS api by id + Return system ECS api by id. + System pointer might become invalid after registration process. It should be get once again after new systems are registered. */ export System* getSystem(ushort id) nothrow @nogc { diff --git a/source/bubel/ecs/system.d b/source/bubel/ecs/system.d index 8e9d0ba..24098c0 100644 --- a/source/bubel/ecs/system.d +++ b/source/bubel/ecs/system.d @@ -97,38 +97,92 @@ struct System return m_system_pointer != null; } + /************************************************************************************************************************ + Return pointer to user side system object + */ + export void* ptr() nothrow @nogc + { + return m_system_pointer; + } + package: - void destroy() + ///destory system. Dispose all data + void destroy() nothrow @nogc + { + import bubel.ecs.std : Mallocator; + + destroySystemData(); + + if (m_name) + { + Mallocator.dispose(m_name); + m_name = null; + } + } + + ///destroy all system data but keeps name which is used for case of system re-registration + void destroySystemData() nothrow @nogc { import bubel.ecs.std : Mallocator; disable(); if (m_destroy) - (cast(void function(void*)) m_destroy)(m_system_pointer); + { + (cast(void function(void*) nothrow @nogc) m_destroy)(m_system_pointer); + m_destroy = null; + } - if (m_name) - Mallocator.dispose(m_name); if (m_components) + { Mallocator.dispose(m_components); + m_components = null; + } if (m_excluded_components) + { Mallocator.dispose(m_excluded_components); + m_excluded_components = null; + } if (m_optional_components) + { Mallocator.dispose(m_optional_components); + m_optional_components = null; + } if (jobs) + { Mallocator.dispose(jobs); + jobs = null; + } if (m_read_only_components) + { Mallocator.dispose(m_read_only_components); + m_read_only_components = null; + } if (m_writable_components) + { Mallocator.dispose(m_writable_components); + m_writable_components = null; + } if (m_readonly_dependencies) + { Mallocator.dispose(m_readonly_dependencies); + m_readonly_dependencies = null; + } if (m_writable_dependencies) + { Mallocator.dispose(m_writable_dependencies); + m_writable_dependencies = null; + } if (m_event_callers) + { Mallocator.dispose(m_event_callers); + m_event_callers = null; + } if (m_system_pointer) + { Mallocator.dispose(m_system_pointer); + m_system_pointer = null; + } } struct EventCaller