diff --git a/include/QF/ecs/component.h b/include/QF/ecs/component.h index 86e468088..de6cc84c0 100644 --- a/include/QF/ecs/component.h +++ b/include/QF/ecs/component.h @@ -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); } } } diff --git a/include/QF/ecs/hierarchy.h b/include/QF/ecs/hierarchy.h index 542741ccf..669490940 100644 --- a/include/QF/ecs/hierarchy.h +++ b/include/QF/ecs/hierarchy.h @@ -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); ///@} diff --git a/libs/client/cl_effects.c b/libs/client/cl_effects.c index 77f9a0004..648525709 100644 --- a/libs/client/cl_effects.c +++ b/libs/client/cl_effects.c @@ -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); diff --git a/libs/ecs/ecs.c b/libs/ecs/ecs.c index b345f20f0..06ca38bb2 100644 --- a/libs/ecs/ecs.c +++ b/libs/ecs/ecs.c @@ -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; diff --git a/libs/ecs/entity.c b/libs/ecs/entity.c index 2d579cc04..e9815f3f0 100644 --- a/libs/ecs/entity.c +++ b/libs/ecs/entity.c @@ -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]) { diff --git a/libs/ecs/hierarchy.c b/libs/ecs/hierarchy.c index 2aa1968b4..41cd2690d 100644 --- a/libs/ecs/hierarchy.c +++ b/libs/ecs/hierarchy.c @@ -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 } diff --git a/libs/scene/scene.c b/libs/scene/scene.c index 0c8f46f07..5ebdd464b 100644 --- a/libs/scene/scene.c +++ b/libs/scene/scene.c @@ -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); diff --git a/libs/ui/canvas.c b/libs/ui/canvas.c index 321c4b6bb..8ae1e9c15 100644 --- a/libs/ui/canvas.c +++ b/libs/ui/canvas.c @@ -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]); } diff --git a/libs/ui/imui.c b/libs/ui/imui.c index 20f5260f3..3ddc75bb7 100644 --- a/libs/ui/imui.c +++ b/libs/ui/imui.c @@ -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) { diff --git a/libs/ui/text.c b/libs/ui/text.c index 743135977..6f1db0f7d 100644 --- a/libs/ui/text.c +++ b/libs/ui/text.c @@ -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); diff --git a/libs/video/renderer/r_trails.c b/libs/video/renderer/r_trails.c index 95fd10767..3a2732db3 100644 --- a/libs/video/renderer/r_trails.c +++ b/libs/video/renderer/r_trails.c @@ -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, }, };