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
This commit is contained in:
Mergul 2020-07-17 13:34:08 +02:00
parent 74179b4fc8
commit 96bbcb9956
5 changed files with 87 additions and 39 deletions

View file

@ -54,6 +54,7 @@ struct BlockAllocator
Mallocator.dispose(pointers);
pointers = next_pointers;
}
next_block = null;
}
private:

View file

@ -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)

View file

@ -13,6 +13,12 @@ struct SimpleVector
@disable this(this);
~this() nothrow @nogc
{
if(data)
Mallocator.dispose(data);
}
///Add element to vector
void add(ubyte el) nothrow @nogc
{

View file

@ -181,15 +181,19 @@ static struct Mallocator
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];
}
@ -297,7 +301,27 @@ static struct Mallocator
return ret;
}
static void dispose(T)(T object) nothrow @nogc
static void dispose(T)(T 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();
@ -305,6 +329,7 @@ static struct Mallocator
object.__dtor();
free(cast(void*) object);
}
}
static void alignDispose(T)(T object)
{

View file

@ -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;