[scene] Add has/get component functions

And define nullent as 0 is a valid entity.
This commit is contained in:
Bill Currie 2022-10-21 19:12:20 +09:00
parent 6189142c60
commit b607fe0878
4 changed files with 30 additions and 9 deletions

View file

@ -44,6 +44,7 @@
#define ENT_GROW 1024
#define COMP_GROW 128
#define ENT_IDBITS 20
#define nullent (~0u)
typedef struct ecs_pool_s {
uint32_t *sparse; // indexed by entity id, holds index to dense/data
@ -90,7 +91,11 @@ COMPINLINE void Component_DestroyElements (const component_t *component,
uint32_t index, uint32_t count);
COMPINLINE uint32_t Ent_Index (uint32_t id);
COMPINLINE uint32_t Ent_Generation (uint32_t id);
COMPINLINE uint32_t Ent_NextGen(uint32_t id);
COMPINLINE uint32_t Ent_NextGen (uint32_t id);
COMPINLINE int Ent_HasComponent (uint32_t ent, uint32_t comp,
ecs_registry_t *reg);
COMPINLINE void *Ent_GetComponent (uint32_t ent, uint32_t comp,
ecs_registry_t *reg);
#undef COMPINLINE
#ifndef IMPLEMENT_COMPONENT_Funcs
@ -172,6 +177,22 @@ Ent_NextGen(uint32_t id)
return id + (1 << ENT_IDBITS);
}
COMPINLINE int
Ent_HasComponent (uint32_t ent, uint32_t comp, ecs_registry_t *reg)
{
uint32_t ind = reg->comp_pools[comp].sparse[Ent_Index (ent)];
return ind != nullent;
}
COMPINLINE void *
Ent_GetComponent (uint32_t ent, uint32_t comp, ecs_registry_t *reg)
{
const component_t *component = &reg->components[comp];
uint32_t ind = reg->comp_pools[comp].sparse[Ent_Index (ent)];
byte *data = reg->comp_pools[comp].data;
return data + ind * component->size;
}
ecs_registry_t *ECS_NewRegistry (void);
void ECS_DelRegistry (ecs_registry_t *registry);
void ECS_RegisterComponents (ecs_registry_t *registry,

View file

@ -37,7 +37,7 @@ VISIBLE ecs_registry_t *
ECS_NewRegistry (void)
{
ecs_registry_t *reg = calloc (1, sizeof (ecs_registry_t));
reg->next = Ent_Index (~0);
reg->next = Ent_Index (nullent);
return reg;
}
@ -64,7 +64,7 @@ ECS_RegisterComponents (ecs_registry_t *registry,
size_t size = registry->max_entities * sizeof (uint32_t);
for (uint32_t i = 0; i < registry->num_components; i++) {
registry->comp_pools[i].sparse = malloc (size);
memset (registry->comp_pools[i].sparse, ~0, size);
memset (registry->comp_pools[i].sparse, nullent, size);
}
}
@ -108,7 +108,7 @@ Ent_RemoveComponent (uint32_t ent, uint32_t comp, ecs_registry_t *registry)
ind, last, 1);
}
pool->count--;
pool->sparse[id] = ~0;
pool->sparse[id] = nullent;
}
}
@ -123,7 +123,7 @@ ECS_NewEntity (ecs_registry_t *registry)
registry->next = Ent_Index (registry->entities[next]);
registry->entities[next] = ent;
} else {
if (registry->num_entities == Ent_Index (~0)) {
if (registry->num_entities == Ent_Index (nullent)) {
Sys_Error ("ECS_NewEntity: out of entities");
}
if (registry->num_entities == registry->max_entities) {
@ -133,7 +133,7 @@ ECS_NewEntity (ecs_registry_t *registry)
for (uint32_t i = 0; i < registry->num_components; i++) {
uint32_t *sparse = registry->comp_pools[i].sparse;
sparse = realloc (sparse, size);
memset (sparse + registry->max_entities - ENT_GROW, ~0,
memset (sparse + registry->max_entities - ENT_GROW, nullent,
ENT_GROW * sizeof (uint32_t));
registry->comp_pools[i].sparse = sparse;
}

View file

@ -70,7 +70,7 @@ check_ent_components (const uint32_t *ents, uint32_t count, uint32_t comp,
}
uint32_t num_entities = 0;
for (uint32_t i = 0; i < reg->max_entities; i++) {
if (pool->sparse[i] == ~0u) {
if (pool->sparse[i] == nullent) {
continue;
}
if (pool->sparse[i] < pool->count) {
@ -88,7 +88,7 @@ check_ent_components (const uint32_t *ents, uint32_t count, uint32_t comp,
}
for (uint32_t i = 0; i < count; i++) {
if (pool->sparse[Ent_Index (ents[i])] == ~0u) {
if (pool->sparse[Ent_Index (ents[i])] == nullent) {
printf ("ent not in %s sparse: %x\n", component->name, ents[i]);
return 0;
}

View file

@ -103,7 +103,7 @@ test_entities (void)
printf ("not 2 available entity for recycling\n");
return 0;
}
for (uint32_t i = reg->next, c = 0; i != Ent_Index (~0);
for (uint32_t i = reg->next, c = 0; i != Ent_Index (nullent);
i = Ent_Index (reg->entities[i]), c++) {
if (c >= reg->available || i >= reg->num_entities) {
printf ("invalid deleted entity chain\n");