mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-24 12:42:32 +00:00
[ecs] Pass the registry in to the component destroy function
This makes it possible for hierarchies to clean themselves up (by deleting their entities (though that will cause other problems later when the hierarchy doesn't own the entities)), thus plugging a memory leak when parsing passage text.
This commit is contained in:
parent
35eec0b2e5
commit
f5ebc1083f
11 changed files with 43 additions and 34 deletions
|
@ -46,7 +46,7 @@ struct ecs_registry_s;
|
|||
typedef struct component_s {
|
||||
size_t size;
|
||||
void (*create) (void *);
|
||||
void (*destroy) (void *);
|
||||
void (*destroy) (void *, struct ecs_registry_s *reg);
|
||||
// comp is the registry component id (base + system component id)
|
||||
uint32_t (*rangeid) (struct ecs_registry_s *reg, uint32_t ent,
|
||||
uint32_t comp);
|
||||
|
@ -78,7 +78,8 @@ COMPINLINE void *Component_CreateElements (const component_t *component,
|
|||
uint32_t index, uint32_t count);
|
||||
COMPINLINE void Component_DestroyElements (const component_t *component,
|
||||
void *array,
|
||||
uint32_t index, uint32_t count);
|
||||
uint32_t index, uint32_t count,
|
||||
struct ecs_registry_s *reg);
|
||||
|
||||
#undef COMPINLINE
|
||||
#ifndef IMPLEMENT_ECS_COMPONENT_Funcs
|
||||
|
@ -186,12 +187,13 @@ Component_CreateElements (const component_t *component, void *array,
|
|||
|
||||
COMPINLINE void
|
||||
Component_DestroyElements (const component_t *component, void *array,
|
||||
uint32_t index, uint32_t count)
|
||||
uint32_t index, uint32_t count,
|
||||
struct ecs_registry_s *reg)
|
||||
{
|
||||
if (component->destroy) {
|
||||
for (uint32_t i = index; count-- > 0; i++) {
|
||||
__auto_type dst = (byte *) array + i * component->size;
|
||||
component->destroy (dst);
|
||||
component->destroy (dst, reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ void Hierarchy_RemoveHierarchy (hierarchy_t *hierarchy, uint32_t index,
|
|||
|
||||
hierref_t Hierarchy_SetParent (hierref_t dref, hierref_t sref,
|
||||
struct ecs_registry_s *reg);
|
||||
void Hierref_DestroyComponent (void *href);
|
||||
void Hierref_DestroyComponent (void *href, struct ecs_registry_s *reg);
|
||||
|
||||
///@}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ ecs_system_t effect_system;
|
|||
static psystem_t *cl_tsystem;
|
||||
|
||||
static void
|
||||
cl_destroy_trail (void *comp)
|
||||
cl_destroy_trail (void *comp, ecs_registry_t *reg)
|
||||
{
|
||||
auto trail = *(uint32_t *) comp;
|
||||
R_Trail_Destroy (cl_tsystem, trail);
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "QF/ecs.h"
|
||||
|
||||
static void
|
||||
ecs_name_destroy (void *name)
|
||||
ecs_name_destroy (void *name, ecs_registry_t *reg)
|
||||
{
|
||||
free (name);
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ ecs_hierarchy_create (void *hierarchy)
|
|||
}
|
||||
|
||||
static void
|
||||
ecs_hierarchy_destroy (void *hierarchy)
|
||||
ecs_hierarchy_destroy (void *hierarchy, ecs_registry_t *reg)
|
||||
{
|
||||
Hierarchy_Destroy (hierarchy);
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ ECS_DelRegistry (ecs_registry_t *registry)
|
|||
for (uint32_t i = registry->components.size; i-- > 0 ;) {
|
||||
__auto_type comp = ®istry->components.a[i];
|
||||
__auto_type pool = ®istry->comp_pools[i];
|
||||
Component_DestroyElements (comp, pool->data, 0, pool->count);
|
||||
Component_DestroyElements (comp, pool->data, 0, pool->count, registry);
|
||||
pool->count = 0;
|
||||
}
|
||||
free (registry->entities);
|
||||
|
@ -268,7 +268,7 @@ ECS_RemoveEntities (ecs_registry_t *registry, uint32_t component)
|
|||
if (destroy) {
|
||||
byte *data = registry->comp_pools[component].data;
|
||||
for (uint32_t i = 0; i < pool->count; i++) {
|
||||
destroy (data + i * comp->size);
|
||||
destroy (data + i * comp->size, registry);
|
||||
}
|
||||
}
|
||||
pool->count = 0;
|
||||
|
|
|
@ -120,7 +120,7 @@ Ent_RemoveComponent (uint32_t ent, uint32_t comp, ecs_registry_t *registry)
|
|||
// being double-removed due to deletion of the component resulting
|
||||
// in the entity being deleted (happens with hierarchies)
|
||||
pool->dense[ind] = -1;
|
||||
Component_DestroyElements (c, pool->data, ind, 1);
|
||||
Component_DestroyElements (c, pool->data, ind, 1, registry);
|
||||
uint32_t range_count = subpool->num_ranges - subpool->available;
|
||||
// if ind >= the last range, then it is outside the subpools
|
||||
if (range_count && ind < subpool->ranges[range_count - 1]) {
|
||||
|
|
|
@ -474,8 +474,8 @@ Hierarchy_Create (hierarchy_t *hierarchy)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Hierarchy_Destroy (hierarchy_t *hierarchy)
|
||||
static void
|
||||
hierarchy_destroy (hierarchy_t *hierarchy)
|
||||
{
|
||||
free (hierarchy->ent);
|
||||
free (hierarchy->childCount);
|
||||
|
@ -491,6 +491,16 @@ Hierarchy_Destroy (hierarchy_t *hierarchy)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Hierarchy_Destroy (hierarchy_t *hierarchy)
|
||||
{
|
||||
hierarchy_InvalidateReferences (hierarchy, 0, hierarchy->num_objects);
|
||||
for (uint32_t i = 0; i < hierarchy->num_objects; i++) {
|
||||
ECS_DelEntity (hierarchy->reg, hierarchy->ent[i]);
|
||||
}
|
||||
hierarchy_destroy (hierarchy);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Hierarchy_New (ecs_registry_t *reg, uint32_t href_comp,
|
||||
const hierarchy_type_t *type, bool createRoot)
|
||||
|
@ -641,7 +651,7 @@ Hierarchy_SetTreeMode (hierarchy_t *hierarchy, bool tree_mode)
|
|||
swap_pointers (&tmp.components[i], &src->components[i]);
|
||||
}
|
||||
}
|
||||
Hierarchy_Destroy (&tmp);
|
||||
hierarchy_destroy (&tmp);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
@ -693,7 +703,6 @@ Hierarchy_SetParent (hierref_t dref, hierref_t sref, ecs_registry_t *reg)
|
|||
if (src->tree_mode) {
|
||||
Sys_Error ("Hierarchy_SetParent tree mode not implemented");
|
||||
}
|
||||
hierref_t r = {};
|
||||
if (ECS_EntValid (dref.id, reg)) {
|
||||
hierarchy_t *dst = Ent_GetComponent (dref.id, ecs_hierarchy, reg);
|
||||
if (dst->type != src->type) {
|
||||
|
@ -713,20 +722,19 @@ Hierarchy_SetParent (hierref_t dref, hierref_t sref, ecs_registry_t *reg)
|
|||
if (!src->num_objects) {
|
||||
Hierarchy_Delete (sref.id, reg);
|
||||
}
|
||||
return r;
|
||||
return dref;
|
||||
}
|
||||
|
||||
void
|
||||
Hierref_DestroyComponent (void *href)
|
||||
Hierref_DestroyComponent (void *href, ecs_registry_t *reg)
|
||||
{
|
||||
#if 0
|
||||
hierref_t ref = *(hierref_t *) href;
|
||||
if (ref.hierarchy) {
|
||||
ref.hierarchy->ent[ref.index] = -1;
|
||||
Hierarchy_RemoveHierarchy (ref.hierarchy, ref.index, 1);
|
||||
if (!ref.hierarchy->num_objects) {
|
||||
Hierarchy_Delete (ref.hierarchy);
|
||||
if (ECS_EntValid (ref.id, reg)) {
|
||||
hierarchy_t *h = Ent_GetComponent (ref.id, ecs_hierarchy, reg);
|
||||
h->ent[ref.index] = -1;
|
||||
Hierarchy_RemoveHierarchy (h, ref.index, 1);
|
||||
if (!h->num_objects) {
|
||||
Hierarchy_Delete (ref.id, reg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ create_colormap (void *_colormap)
|
|||
}
|
||||
|
||||
static void
|
||||
destroy_visibility (void *_visibility)
|
||||
destroy_visibility (void *_visibility, ecs_registry_t *reg)
|
||||
{
|
||||
visibility_t *visibility = _visibility;
|
||||
if (visibility->efrag) {
|
||||
|
@ -77,7 +77,7 @@ destroy_visibility (void *_visibility)
|
|||
}
|
||||
|
||||
static void
|
||||
destroy_renderer (void *_renderer)
|
||||
destroy_renderer (void *_renderer, ecs_registry_t *reg)
|
||||
{
|
||||
renderer_t *renderer = _renderer;
|
||||
if (renderer->skin) {
|
||||
|
@ -86,7 +86,7 @@ destroy_renderer (void *_renderer)
|
|||
}
|
||||
|
||||
static void
|
||||
destroy_efrags (void *_efrags)
|
||||
destroy_efrags (void *_efrags, ecs_registry_t *reg)
|
||||
{
|
||||
efrag_t **efrags = _efrags;
|
||||
R_ClearEfragChain (*efrags);
|
||||
|
|
|
@ -78,10 +78,9 @@ canvas_rangeid(outline)
|
|||
#undef canvas_rangeid
|
||||
|
||||
static void
|
||||
canvas_canvas_destroy (void *_canvas)
|
||||
canvas_canvas_destroy (void *_canvas, ecs_registry_t *reg)
|
||||
{
|
||||
canvas_t *canvas = _canvas;
|
||||
auto reg = canvas->reg;
|
||||
for (uint32_t i = 0; i < canvas_subpool_count; i++) {
|
||||
ECS_DelSubpoolRange (reg, canvas->base + i, canvas->range[i]);
|
||||
}
|
||||
|
|
|
@ -129,7 +129,7 @@ struct imui_ctx_s {
|
|||
};
|
||||
|
||||
static void
|
||||
imui_reference_destroy (void *_ref)
|
||||
imui_reference_destroy (void *_ref, ecs_registry_t *reg)
|
||||
{
|
||||
imui_reference_t *ref = _ref;
|
||||
if (ref->ctx) {
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
#include "compat.h"
|
||||
|
||||
static void
|
||||
text_passage_glyphs_destroy (void *_glyphset)
|
||||
text_passage_glyphs_destroy (void *_glyphset, ecs_registry_t *reg)
|
||||
{
|
||||
glyphset_t *glyphset = _glyphset;
|
||||
free (glyphset->glyphs);
|
||||
|
@ -59,7 +59,7 @@ text_features_create (void *_features)
|
|||
}
|
||||
|
||||
static void
|
||||
text_features_destroy (void *_features)
|
||||
text_features_destroy (void *_features, ecs_registry_t *reg)
|
||||
{
|
||||
featureset_t *features = _features;
|
||||
DARRAY_CLEAR (features);
|
||||
|
|
|
@ -56,7 +56,7 @@ enum trails_components {
|
|||
};
|
||||
|
||||
static void
|
||||
destroy_pointset (void *comp)
|
||||
pointset_destroy (void *comp, ecs_registry_t *reg)
|
||||
{
|
||||
pointset_t *pointset = comp;
|
||||
int base = pointset->base / 64;
|
||||
|
@ -71,7 +71,7 @@ static const component_t trails_components[trails_comp_count] = {
|
|||
.size = sizeof (pointset_t),
|
||||
.create = 0,
|
||||
.name = "pointset",
|
||||
.destroy = destroy_pointset,
|
||||
.destroy = pointset_destroy,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue