mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-15 05:41:59 +00:00
[ecs] Delay component destruction
Copy the component out of the pool so that it can be overwritten now, thus removing it from the pool, before actually destroying the component so that any recursive removals of the same component don't mess up the indices, and also don't try to remove the component from the same entity. This fixes a rather sneaky component leak caused by said recursion.
This commit is contained in:
parent
0307e9d165
commit
ce7c2183d3
2 changed files with 16 additions and 13 deletions
|
@ -116,11 +116,14 @@ Ent_RemoveComponent (uint32_t ent, uint32_t comp, ecs_registry_t *registry)
|
|||
uint32_t ind = pool->sparse[id];
|
||||
component_t *c = ®istry->components.a[comp];
|
||||
if (ind < pool->count && pool->dense[ind] == ent) {
|
||||
// invalidate the entity for this component to prevent the component
|
||||
// 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, registry);
|
||||
// copy the component out of the pool so that it can be overwritten
|
||||
// now, thus removing it from the pool, before actually destroying
|
||||
// the component so that any recursive removals of the same component
|
||||
// don't mess up the indices, and also don't try to remove the
|
||||
// component from the same entity
|
||||
byte tmp_comp[c->size];
|
||||
Component_CopyElements (c, tmp_comp, 0, pool->data, ind, 1);
|
||||
|
||||
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]) {
|
||||
|
@ -144,5 +147,9 @@ Ent_RemoveComponent (uint32_t ent, uint32_t comp, ecs_registry_t *registry)
|
|||
}
|
||||
pool->count--;
|
||||
pool->sparse[id] = nullent;
|
||||
|
||||
// the component has been fully removed from the pool so it is now
|
||||
// safe to destroy it
|
||||
Component_DestroyElements (c, tmp_comp, 0, 1, registry);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1213,14 +1213,10 @@ IMUI_Passage (imui_ctx_t *ctx, const char *name, struct passage_s *passage)
|
|||
Canvas_SetReference (ctx->csys, psg_view.id,
|
||||
Canvas_Entity (ctx->csys,
|
||||
View_GetRoot (anchor_view).id));
|
||||
if (Ent_HasComponent (psg_view.id, c_passage_glyphs, reg)) {
|
||||
// FIXME this shouldn't be necessary and is a sign of bigger problems
|
||||
Ent_RemoveComponent (psg_view.id, c_passage_glyphs, reg);
|
||||
}
|
||||
if (Ent_HasComponent (psg_view.id, c_updateonce, reg)) {
|
||||
// FIXME this shouldn't be necessary and is a sign of bigger problems
|
||||
Ent_RemoveComponent (psg_view.id, c_updateonce, reg);
|
||||
}
|
||||
// FIXME this shouldn't be necessary and is a sign of bigger problems
|
||||
Ent_RemoveComponent (psg_view.id, c_passage_glyphs, reg);
|
||||
// FIXME this shouldn't be necessary and is a sign of bigger problems
|
||||
Ent_RemoveComponent (psg_view.id, c_updateonce, reg);
|
||||
Ent_SetComponent (psg_view.id, c_passage_glyphs, reg,
|
||||
Ent_GetComponent (psg_view.id, t_passage_glyphs, reg));
|
||||
void *update = passage_update;
|
||||
|
|
Loading…
Reference in a new issue