mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-15 05:41:59 +00:00
[ecs] Adjust subpool range type to return start,end
I found I needed the subrange start as well as the end, but I liked that the subpools themselves used only the end of the range, so switching to just a unint32_t for the value and adding a function to return a tuple made sense. I had kept the struct because I thought I might want to store additional information (eg, the entity "owning" the subpool), but found that I didn't need such information as the systems using subpools that way would have access to the entity by other means. Interestingly, the change found a bug in subpool creation: I really don't know why things worked before, but they work better now :)
This commit is contained in:
parent
34930ba195
commit
3a2877dd9a
4 changed files with 52 additions and 24 deletions
|
@ -63,13 +63,14 @@ typedef struct ecs_pool_s {
|
|||
typedef struct DARRAY_TYPE(component_t) componentset_t;
|
||||
|
||||
typedef struct ecs_range_s {
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
} ecs_range_t;
|
||||
|
||||
typedef struct ecs_subpool_s {
|
||||
ecs_range_t *ranges;
|
||||
uint32_t *rangeids;
|
||||
uint32_t *sorted;
|
||||
uint32_t *ranges;
|
||||
uint32_t next;
|
||||
uint32_t available;
|
||||
uint32_t num_ranges;
|
||||
|
@ -98,6 +99,10 @@ typedef struct ecs_system_s {
|
|||
uint32_t base;
|
||||
} ecs_system_t;
|
||||
|
||||
#include "QF/ecs/entity.h"
|
||||
|
||||
#define ECSINLINE GNU89INLINE inline
|
||||
|
||||
ecs_registry_t *ECS_NewRegistry (void);
|
||||
void ECS_DelRegistry (ecs_registry_t *registry);
|
||||
uint32_t ECS_RegisterComponents (ecs_registry_t *registry,
|
||||
|
@ -120,11 +125,31 @@ void ECS_RemoveEntities (ecs_registry_t *registry, uint32_t component);
|
|||
uint32_t ECS_NewSubpoolRange (ecs_registry_t *registry, uint32_t component);
|
||||
void ECS_DelSubpoolRange (ecs_registry_t *registry, uint32_t component,
|
||||
uint32_t id);
|
||||
ECSINLINE ecs_range_t ECS_GetSubpoolRange (ecs_registry_t *registry,
|
||||
uint32_t component, uint32_t id);
|
||||
|
||||
#undef ECSINLINE
|
||||
#ifndef IMPLEMENT_ECS_Funcs
|
||||
#define ECSINLINE GNU89INLINE inline
|
||||
#else
|
||||
#define ECSINLINE VISIBLE
|
||||
#endif
|
||||
|
||||
ECSINLINE
|
||||
ecs_range_t
|
||||
ECS_GetSubpoolRange (ecs_registry_t *registry, uint32_t component, uint32_t id)
|
||||
{
|
||||
ecs_subpool_t *subpool = ®istry->subpools[component];
|
||||
uint32_t ind = subpool->sorted[Ent_Index (id)];
|
||||
ecs_range_t range = {
|
||||
.start = ind ? subpool->ranges[ind - 1] : 0,
|
||||
.end = subpool->ranges[ind],
|
||||
};
|
||||
return range;
|
||||
}
|
||||
|
||||
#undef ECSINLINE
|
||||
|
||||
///@}
|
||||
|
||||
#include "QF/ecs/entity.h"
|
||||
|
||||
#endif//__QF_ecs_h
|
||||
|
|
|
@ -67,11 +67,11 @@ Ent_AddComponent (uint32_t ent, uint32_t comp, ecs_registry_t *registry)
|
|||
uint32_t rangeind = subpool->sorted[Ent_Index (rangeid)];
|
||||
printf ("ent:%d rangeid:%d rangeind:%d\n", ent, rangeid, rangeind);
|
||||
while (rind-- > rangeind) {
|
||||
if (subpool->ranges[rind].end == ind) {
|
||||
subpool->ranges[rind].end++;
|
||||
if (subpool->ranges[rind] == ind) {
|
||||
subpool->ranges[rind]++;
|
||||
continue;
|
||||
}
|
||||
uint32_t end = subpool->ranges[rind].end++;
|
||||
uint32_t end = subpool->ranges[rind]++;
|
||||
Component_MoveElements (c, pool->data, ind, end, 1);
|
||||
swap_inds (&pool->sparse[Ent_Index (pool->dense[end])],
|
||||
&pool->sparse[Ent_Index (pool->dense[ind])]);
|
||||
|
@ -87,24 +87,24 @@ static int
|
|||
range_cmp (const void *_key, const void *_range, void *_subpool)
|
||||
{
|
||||
const uint32_t *key = _key;
|
||||
const ecs_range_t *range = _range;
|
||||
const uint32_t *range = _range;
|
||||
ecs_subpool_t *subpool = _subpool;
|
||||
|
||||
if (*key >= range->end) {
|
||||
if (*key >= *range) {
|
||||
return -1;
|
||||
}
|
||||
if (range - subpool->ranges > 0) {
|
||||
return *key >= range[-1].end ? 0 : -1;
|
||||
return *key >= range[-1] ? 0 : -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ecs_range_t *
|
||||
static uint32_t *
|
||||
find_range (ecs_subpool_t *subpool, uint32_t ind)
|
||||
{
|
||||
return bsearch_r (&ind, subpool->ranges,
|
||||
subpool->num_ranges - subpool->available,
|
||||
sizeof (ecs_range_t), range_cmp, subpool);
|
||||
sizeof (uint32_t), range_cmp, subpool);
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
|
@ -120,9 +120,9 @@ Ent_RemoveComponent (uint32_t ent, uint32_t comp, ecs_registry_t *registry)
|
|||
Component_DestroyElements (c, pool->data, ind, 1);
|
||||
if (subpool->num_ranges - subpool->available) {
|
||||
uint32_t range_count = subpool->num_ranges - subpool->available;
|
||||
ecs_range_t *range = find_range (subpool, ind);
|
||||
uint32_t *range = find_range (subpool, ind);
|
||||
while (range - subpool->ranges < range_count) {
|
||||
uint32_t end = --range->end;
|
||||
uint32_t end = --*range;
|
||||
range++;
|
||||
pool->sparse[Ent_Index (pool->dense[end])] = ind;
|
||||
pool->dense[ind] = pool->dense[end];
|
||||
|
|
|
@ -64,11 +64,9 @@ ECS_NewSubpoolRange (ecs_registry_t *registry, uint32_t component)
|
|||
}
|
||||
uint32_t end = 0;
|
||||
if (num_ranges) {
|
||||
end = subpool->ranges[num_ranges - 1].end;
|
||||
end = subpool->ranges[num_ranges - 1];
|
||||
}
|
||||
subpool->ranges[Ent_Index (id)] = (ecs_range_t) {
|
||||
.end = end,
|
||||
};
|
||||
subpool->ranges[subpool->sorted[Ent_Index (id)]] = end;
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,13 +52,13 @@ static int
|
|||
check_subpool_ranges (ecs_subpool_t *subpool, uint32_t *expect)
|
||||
{
|
||||
uint32_t count = subpool->num_ranges - subpool->available;
|
||||
ecs_range_t *range = subpool->ranges;
|
||||
uint32_t *range = subpool->ranges;
|
||||
|
||||
while (count--) {
|
||||
ecs_range_t *r = range++;
|
||||
uint32_t e = *expect++;
|
||||
printf ("%d: %d %d\n", (int)(r - subpool->ranges), r->end, e);
|
||||
if (r->end != e++) {
|
||||
uint32_t *r = range++;
|
||||
uint32_t e = *expect++;
|
||||
printf ("%d: %d %d\n", (int)(r - subpool->ranges), *r, e);
|
||||
if (*r != e++) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -109,9 +109,9 @@ main (void)
|
|||
return 1;
|
||||
}
|
||||
for (uint32_t i = 0; i < reg->subpools[base + test_obj].num_ranges; i++) {
|
||||
if (reg->subpools[base + test_obj].ranges[i].end != 0) {
|
||||
if (reg->subpools[base + test_obj].ranges[i] != 0) {
|
||||
printf ("end %d not 0 count: %d\n", i,
|
||||
reg->subpools[base + test_obj].ranges[i].end);
|
||||
reg->subpools[base + test_obj].ranges[i]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -234,6 +234,11 @@ main (void)
|
|||
|
||||
sp2 = ECS_NewSubpoolRange (reg, base + test_obj);
|
||||
printf ("sp2: %d\n", sp2);
|
||||
if (check_subpool_ranges (®->subpools[base + test_obj],
|
||||
(uint32_t[]) { 2, 4, 4 })) {
|
||||
printf ("oops\n");
|
||||
return 1;
|
||||
}
|
||||
Ent_SetComponent (entc, base + test_subpool, reg, &sp2);
|
||||
Ent_SetComponent (entf, base + test_subpool, reg, &sp2);
|
||||
Ent_SetComponent (entg, base + test_subpool, reg, &sp2);
|
||||
|
|
Loading…
Reference in a new issue