From b607fe0878e7b67462dc8f5e63f58ee5fcc54bc5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 21 Oct 2022 19:12:20 +0900 Subject: [PATCH] [scene] Add has/get component functions And define nullent as 0 is a valid entity. --- include/QF/scene/component.h | 23 ++++++++++++++++++++++- libs/scene/component.c | 10 +++++----- libs/scene/test/test-components.c | 4 ++-- libs/scene/test/test-registry.c | 2 +- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/include/QF/scene/component.h b/include/QF/scene/component.h index 6d05f835d..45fb86d16 100644 --- a/include/QF/scene/component.h +++ b/include/QF/scene/component.h @@ -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 = ®->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, diff --git a/libs/scene/component.c b/libs/scene/component.c index e8e83fa24..0860896ce 100644 --- a/libs/scene/component.c +++ b/libs/scene/component.c @@ -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; } diff --git a/libs/scene/test/test-components.c b/libs/scene/test/test-components.c index b2d2c11b9..354fbab6c 100644 --- a/libs/scene/test/test-components.c +++ b/libs/scene/test/test-components.c @@ -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; } diff --git a/libs/scene/test/test-registry.c b/libs/scene/test/test-registry.c index b9625dfc2..2ffff8a92 100644 --- a/libs/scene/test/test-registry.c +++ b/libs/scene/test/test-registry.c @@ -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");