mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-16 17:01:53 +00:00
[ecs] Support sorting subpools
Sorting the whole pool when subpools are in use could break the subpools (very high probability, depending on the sort criteria and subpool criteria).
This commit is contained in:
parent
2383c12a4a
commit
8833518826
4 changed files with 61 additions and 11 deletions
|
@ -117,6 +117,9 @@ typedef int (*__compar_d_fn_t)(const void *, const void *, void *);
|
|||
#endif
|
||||
void ECS_SortComponentPool (ecs_registry_t *registry, uint32_t component,
|
||||
__compar_d_fn_t cmp, void *arg);
|
||||
void ECS_SortComponentPoolRange (ecs_registry_t *registry, uint32_t component,
|
||||
ecs_range_t range,
|
||||
__compar_d_fn_t cmp, void *arg);
|
||||
|
||||
uint32_t ECS_NewEntity (ecs_registry_t *registry);
|
||||
void ECS_DelEntity (ecs_registry_t *registry, uint32_t ent);
|
||||
|
|
|
@ -78,5 +78,8 @@ typedef struct canvas_subpic_s {
|
|||
|
||||
void Canvas_AddToEntity (canvas_system_t canvas_sys, uint32_t ent);
|
||||
void Canvas_Draw (canvas_system_t canvas_sys);
|
||||
void Canvas_SortComponentPool (canvas_system_t canvas_sys, uint32_t ent,
|
||||
uint32_t component);
|
||||
|
||||
|
||||
#endif//__QF_scene_canvas_h
|
||||
|
|
|
@ -125,6 +125,26 @@ ecs_swap (void *_a, void *_b, void *arg)
|
|||
swap_uint32 (&pool->sparse[a_ent_ind], &pool->sparse[b_ent_ind]);
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
ECS_SortComponentPoolRange (ecs_registry_t *registry, uint32_t component,
|
||||
ecs_range_t range, __compar_d_fn_t cmp, void *arg)
|
||||
{
|
||||
if (component >= registry->components.size) {
|
||||
Sys_Error ("ECS_SortComponentPoolRange: invalid component: %u",
|
||||
component);
|
||||
}
|
||||
ecs_pool_t *pool = ®istry->comp_pools[component];
|
||||
if (!pool->count || range.end <= range.start) {
|
||||
return;
|
||||
}
|
||||
uint32_t count = range.end - range.start;
|
||||
uint32_t *start = pool->dense + range.start;
|
||||
__auto_type comp = ®istry->components.a[component];
|
||||
ecs_sort_t sortctx = { .cmp = cmp, .arg = arg, .pool = pool, .comp = comp };
|
||||
heapsort_s (start, count, sizeof (uint32_t),
|
||||
ecs_compare, ecs_swap, &sortctx);
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
ECS_SortComponentPool (ecs_registry_t *registry, uint32_t component,
|
||||
__compar_d_fn_t cmp, void *arg)
|
||||
|
@ -133,13 +153,8 @@ ECS_SortComponentPool (ecs_registry_t *registry, uint32_t component,
|
|||
Sys_Error ("ECS_SortComponentPool: invalid component: %u", component);
|
||||
}
|
||||
ecs_pool_t *pool = ®istry->comp_pools[component];
|
||||
if (!pool->count) {
|
||||
return;
|
||||
}
|
||||
__auto_type comp = ®istry->components.a[component];
|
||||
ecs_sort_t sortctx = { .cmp = cmp, .arg = arg, .pool = pool, .comp = comp };
|
||||
heapsort_s (pool->dense, pool->count, sizeof (uint32_t),
|
||||
ecs_compare, ecs_swap, &sortctx);
|
||||
ecs_range_t range = { .start = 0, .end = pool->count };
|
||||
ECS_SortComponentPoolRange (registry, component, range, cmp, arg);
|
||||
}
|
||||
|
||||
VISIBLE uint32_t
|
||||
|
|
|
@ -312,10 +312,10 @@ Canvas_Draw (canvas_system_t canvas_sys)
|
|||
};
|
||||
|
||||
uint32_t comp = canvas_sys.base + canvas_canvas;
|
||||
ecs_pool_t *pool = &canvas_sys.reg->comp_pools[comp];
|
||||
uint32_t count = pool->count;
|
||||
//uint32_t *entities = pool->dense;
|
||||
__auto_type canvases = (canvas_t *) pool->data;
|
||||
ecs_pool_t *canvas_pool = &canvas_sys.reg->comp_pools[comp];
|
||||
uint32_t count = canvas_pool->count;
|
||||
//uint32_t *entities = canvas_pool->dense;
|
||||
__auto_type canvases = (canvas_t *) canvas_pool->data;
|
||||
|
||||
while (count-- > 0) {
|
||||
canvas_t *canvas = canvases++;
|
||||
|
@ -347,3 +347,32 @@ Canvas_AddToEntity (canvas_system_t canvas_sys, uint32_t ent)
|
|||
(ecs_system_t) { canvas_sys.reg, canvas_sys.view_base },
|
||||
nullview);
|
||||
}
|
||||
|
||||
static int
|
||||
canvas_href_cmp (const void *_a, const void *_b, void *arg)
|
||||
{
|
||||
uint32_t enta = *(const uint32_t *)_a;
|
||||
uint32_t entb = *(const uint32_t *)_b;
|
||||
canvas_system_t *canvas_sys = arg;
|
||||
ecs_registry_t *reg = canvas_sys->reg;
|
||||
uint32_t href = canvas_sys->view_base + view_href;
|
||||
hierref_t *ref_a = Ent_GetComponent (enta, href, reg);
|
||||
hierref_t *ref_b = Ent_GetComponent (entb, href, reg);
|
||||
if (ref_a->hierarchy == ref_b->hierarchy) {
|
||||
return ref_a->index - ref_b->index;
|
||||
}
|
||||
ptrdiff_t diff = ref_a->hierarchy - ref_b->hierarchy;
|
||||
return diff > 0 ? 1 : diff < 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
void
|
||||
Canvas_SortComponentPool (canvas_system_t canvas_sys, uint32_t ent,
|
||||
uint32_t component)
|
||||
{
|
||||
canvas_t *canvas = Ent_GetComponent (ent, canvas_sys.base + canvas_canvas,
|
||||
canvas_sys.reg);
|
||||
uint32_t rid = canvas->range[component - canvas_sys.base];
|
||||
ecs_range_t range = ECS_GetSubpoolRange (canvas_sys.reg, component, rid);
|
||||
ECS_SortComponentPoolRange (canvas_sys.reg, component, range,
|
||||
canvas_href_cmp, &canvas_sys);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue