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); Mallocator.dispose(pointers);
pointers = next_pointers; pointers = next_pointers;
} }
next_block = null;
} }
private: private:

View file

@ -96,29 +96,7 @@ export struct EntityManager
{ {
foreach (ref system; systems) foreach (ref system; systems)
{ {
system.disable(); system.destroy();
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);
} }
foreach (EntityInfo* info; &entities_infos.byValue) foreach (EntityInfo* info; &entities_infos.byValue)
@ -425,7 +403,8 @@ export struct EntityManager
enum EventName = fullName!(Unqual!(EventParamType)); enum EventName = fullName!(Unqual!(EventParamType));
// enum EventName = fullyQualifiedName!(Unqual!(EventParamType));//.stringof; // enum EventName = fullyQualifiedName!(Unqual!(EventParamType));//.stringof;
ushort evt = events_map.get(cast(char[]) EventName, ushort.max); 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 ~ "\"."); ~ "\" due to non existing event \"" ~ EventName ~ "\".");
callers[i].callback = cast(void*)&callEventHandler!(EventParamType); 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); ushort sys_id = systems_map.get(cast(char[]) SystemName, ushort.max);
if (sys_id < systems.length) if (sys_id < systems.length)
{ {
systems[sys_id].disable(); system.m_name = systems[sys_id].m_name;
if (systems[sys_id].m_destroy) systems[sys_id].m_name = null;
(cast(void function(void*)) systems[sys_id].m_destroy)( systems[sys_id].destroy();
systems[sys_id].m_system_pointer);
if (system.m_create) if (system.m_create)
(cast(void function(void*)) system.m_create)(system.m_system_pointer); (cast(void function(void*)) system.m_create)(system.m_system_pointer);
@ -1199,7 +1177,6 @@ export struct EntityManager
system.enable(); system.enable();
system.m_id = sys_id; system.m_id = sys_id;
system.m_name = systems[sys_id].m_name;
systems[sys_id] = system; systems[sys_id] = system;
} }
else else
@ -1307,6 +1284,8 @@ export struct EntityManager
if (comp_id < components.length) if (comp_id < components.length)
{ {
Comp.component_id = comp_id; Comp.component_id = comp_id;
if (components[comp_id].init_data)
Mallocator.dispose(components[comp_id].init_data);
components[comp_id] = info; components[comp_id] = info;
} }
else else
@ -1874,7 +1853,8 @@ export struct EntityManager
foreach (i, id; ids) 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); alignNum(current_delta, components[id].alignment);
info.deltas[id] = cast(ushort) current_delta; info.deltas[id] = cast(ushort) current_delta;
current_delta += entites_in_block * components[id].size; current_delta += entites_in_block * components[id].size;
@ -3548,6 +3528,10 @@ export struct EntityManager
Mallocator.dispose(deltas); Mallocator.dispose(deltas);
if (tmpl_deltas) if (tmpl_deltas)
Mallocator.dispose(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) if (systems)
Mallocator.dispose(systems); Mallocator.dispose(systems);
if (add_listeners) if (add_listeners)

View file

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

View file

@ -156,7 +156,7 @@ static struct Mallocator
{ {
T[] ret; T[] ret;
if(length > array.length) if (length > array.length)
{ {
ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length]; ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length];
static if (__traits(isPOD, T)) static if (__traits(isPOD, T))
@ -178,21 +178,25 @@ static struct Mallocator
} }
} }
} }
else else
{ {
static if (__traits(hasMember, T, "__xdtor")) static if (__traits(hasMember, T, "__xdtor"))
{
foreach (i; length .. array.length) foreach (i; length .. array.length)
{ {
array[i].__xdtor(); array[i].__xdtor();
} }
}
else static if (__traits(hasMember, T, "__dtor")) else static if (__traits(hasMember, T, "__dtor"))
{
foreach (i; length .. array.length) foreach (i; length .. array.length)
{ {
array[i].__dtor(); array[i].__dtor();
} }
}
ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length]; ret = (cast(T*) realloc(array.ptr, T.sizeof * length))[0 .. length];
} }
return ret; return ret;
} }
@ -297,13 +301,34 @@ static struct Mallocator
return ret; return ret;
} }
static void dispose(T)(T object) nothrow @nogc static void dispose(T)(T object)
{ {
static if (__traits(hasMember, T, "__xdtor")) static if (isArray!T)
object.__xdtor(); {
else static if (__traits(hasMember, T, "__dtor")) alias TT = PointerTarget!(typeof(object.ptr));
object.__dtor(); static if (!isPointer!TT)
free(cast(void*) object); {
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) static void alignDispose(T)(T object)

View file

@ -91,6 +91,38 @@ struct System
package: 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 struct EventCaller
{ {
ushort id; ushort id;