From 96bbcb9956cd8e0d3cc2fcceb8c0d0126d41abf8 Mon Sep 17 00:00:00 2001 From: Mergul Date: Fri, 17 Jul 2020 13:34:08 +0200 Subject: [PATCH] Fixed issues and bugs -moved system destroy functionality to System structure "destroy()" function -now arrays are properly destroyed (with destructor calling (__xdtor)) -fixed bug which makes BlockAllocator crashing after freeing it's memory -fixed many smaller memory leaks --- source/bubel/ecs/block_allocator.d | 1 + source/bubel/ecs/manager.d | 44 ++++++++++-------------------- source/bubel/ecs/simple_vector.d | 6 ++++ source/bubel/ecs/std.d | 43 +++++++++++++++++++++++------ source/bubel/ecs/system.d | 32 ++++++++++++++++++++++ 5 files changed, 87 insertions(+), 39 deletions(-) diff --git a/source/bubel/ecs/block_allocator.d b/source/bubel/ecs/block_allocator.d index d3070c4..6894a17 100644 --- a/source/bubel/ecs/block_allocator.d +++ b/source/bubel/ecs/block_allocator.d @@ -54,6 +54,7 @@ struct BlockAllocator Mallocator.dispose(pointers); pointers = next_pointers; } + next_block = null; } private: diff --git a/source/bubel/ecs/manager.d b/source/bubel/ecs/manager.d index 7fb79f8..c26a414 100644 --- a/source/bubel/ecs/manager.d +++ b/source/bubel/ecs/manager.d @@ -96,29 +96,7 @@ export struct EntityManager { foreach (ref system; systems) { - system.disable(); - if (system.m_destroy) - (cast(void function(void*)) system.m_destroy)(system.m_system_pointer); - - if (system.jobs) - Mallocator.dispose(system.jobs); - if (system.m_read_only_components) - Mallocator.dispose(system.m_read_only_components); - if (system.m_writable_components) - Mallocator.dispose(system.m_writable_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.dispose(system.m_system_pointer); + system.destroy(); } foreach (EntityInfo* info; &entities_infos.byValue) @@ -425,7 +403,8 @@ export struct EntityManager enum EventName = fullName!(Unqual!(EventParamType)); // 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 + assert(evt != ushort.max, + "Can't register system \"" ~ SystemName ~ "\" due to non existing event \"" ~ EventName ~ "\"."); callers[i].callback = cast(void*)&callEventHandler!(EventParamType); @@ -1188,10 +1167,9 @@ export struct EntityManager ushort sys_id = systems_map.get(cast(char[]) SystemName, ushort.max); if (sys_id < systems.length) { - systems[sys_id].disable(); - if (systems[sys_id].m_destroy) - (cast(void function(void*)) systems[sys_id].m_destroy)( - systems[sys_id].m_system_pointer); + system.m_name = systems[sys_id].m_name; + systems[sys_id].m_name = null; + systems[sys_id].destroy(); if (system.m_create) (cast(void function(void*)) system.m_create)(system.m_system_pointer); @@ -1199,7 +1177,6 @@ export struct EntityManager system.enable(); system.m_id = sys_id; - system.m_name = systems[sys_id].m_name; systems[sys_id] = system; } else @@ -1307,6 +1284,8 @@ export struct EntityManager if (comp_id < components.length) { Comp.component_id = comp_id; + if (components[comp_id].init_data) + Mallocator.dispose(components[comp_id].init_data); components[comp_id] = info; } else @@ -1874,7 +1853,8 @@ export struct EntityManager foreach (i, id; ids) { - if(current_delta == 0)current_delta = ushort.max; + if (current_delta == 0) + current_delta = ushort.max; alignNum(current_delta, components[id].alignment); info.deltas[id] = cast(ushort) current_delta; current_delta += entites_in_block * components[id].size; @@ -3548,6 +3528,10 @@ export struct EntityManager Mallocator.dispose(deltas); if (tmpl_deltas) Mallocator.dispose(tmpl_deltas); + if (comp_add_info) + Mallocator.dispose(comp_add_info); + if (comp_rem_info) + Mallocator.dispose(comp_rem_info); if (systems) Mallocator.dispose(systems); if (add_listeners) diff --git a/source/bubel/ecs/simple_vector.d b/source/bubel/ecs/simple_vector.d index bb4b610..acf01ee 100644 --- a/source/bubel/ecs/simple_vector.d +++ b/source/bubel/ecs/simple_vector.d @@ -12,6 +12,12 @@ struct SimpleVector { @disable this(this); + + ~this() nothrow @nogc + { + if(data) + Mallocator.dispose(data); + } ///Add element to vector void add(ubyte el) nothrow @nogc diff --git a/source/bubel/ecs/std.d b/source/bubel/ecs/std.d index 38ad0d8..d99a05c 100644 --- a/source/bubel/ecs/std.d +++ b/source/bubel/ecs/std.d @@ -156,7 +156,7 @@ static struct Mallocator { T[] ret; - if(length > array.length) + if (length > array.length) { ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length]; static if (__traits(isPOD, T)) @@ -178,21 +178,25 @@ static struct Mallocator } } } - else + else { static if (__traits(hasMember, T, "__xdtor")) + { foreach (i; length .. array.length) { array[i].__xdtor(); } + } else static if (__traits(hasMember, T, "__dtor")) + { foreach (i; length .. array.length) { array[i].__dtor(); } + } ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length]; } - + return ret; } @@ -297,13 +301,34 @@ static struct Mallocator return ret; } - static void dispose(T)(T object) nothrow @nogc + static void dispose(T)(T object) { - static if (__traits(hasMember, T, "__xdtor")) - object.__xdtor(); - else static if (__traits(hasMember, T, "__dtor")) - object.__dtor(); - free(cast(void*) object); + static if (isArray!T) + { + alias TT = PointerTarget!(typeof(object.ptr)); + static if (!isPointer!TT) + { + static if (__traits(hasMember, TT, "__xdtor")) + { + foreach (ref TT t; object) + t.__xdtor(); + } + else static if (__traits(hasMember, TT, "__dtor")) + { + foreach (TT t; object) + t.__dtor(); + } + } + free(cast(void*) object.ptr); + } + else + { + static if (__traits(hasMember, T, "__xdtor")) + object.__xdtor(); + else static if (__traits(hasMember, T, "__dtor")) + object.__dtor(); + free(cast(void*) object); + } } static void alignDispose(T)(T object) diff --git a/source/bubel/ecs/system.d b/source/bubel/ecs/system.d index 7bcaf01..cd8d2e3 100644 --- a/source/bubel/ecs/system.d +++ b/source/bubel/ecs/system.d @@ -91,6 +91,38 @@ struct System package: + void destroy() + { + import bubel.ecs.std : Mallocator; + disable(); + if (m_destroy) + (cast(void function(void*)) m_destroy)(m_system_pointer); + + if (m_name) + Mallocator.dispose(m_name); + if (m_components) + Mallocator.dispose(m_components); + if (m_excluded_components) + Mallocator.dispose(m_excluded_components); + if (m_optional_components) + Mallocator.dispose(m_optional_components); + if (jobs) + Mallocator.dispose(jobs); + if (m_read_only_components) + Mallocator.dispose(m_read_only_components); + if (m_writable_components) + Mallocator.dispose(m_writable_components); + if (m_readonly_dependencies) + Mallocator.dispose(m_readonly_dependencies); + if (m_writable_dependencies) + Mallocator.dispose(m_writable_dependencies); + if (m_event_callers) + Mallocator.dispose(m_event_callers); + + if (m_system_pointer) + Mallocator.dispose(m_system_pointer); + } + struct EventCaller { ushort id;