Finished up API functions, left query work to do

This commit is contained in:
Rodolfo Barcelli Jo 2026-01-21 22:55:28 +08:00
parent a98430ad4f
commit 8d0db596a9

97
becs3.h
View file

@ -1,8 +1,15 @@
/* /*
* Usage: * Usage:
* Define BECS_IMPLEMENTATION in exactly _one_ file before including this file
* *
* Eg: * Define BECS_MAX_ENTITIES and BECS_MAX_COMPONENTS. Otherwise they will have
* the following defaults:
*
* #define BECS_MAX_ENTITIES 4096
* #define BECS_MAX_COMPONENTS 64
*
* Then define BECS_IMPLEMENTATION in exactly _one_ file before including this
* file as follows:
*
* #define BECS_IMPLEMENTATION * #define BECS_IMPLEMENTATION
* #include "becs.h" * #include "becs.h"
*/ */
@ -28,6 +35,10 @@ typedef struct BECS_ECS BECS_ECS;
typedef uint32_t BECS_Entity; typedef uint32_t BECS_Entity;
typedef uint32_t BECS_ComponentID; typedef uint32_t BECS_ComponentID;
size_t BECS_GetMinMemoryArenaSize(size_t *componentSizes, size_t arrayLength);
BECS_ECS BECS_InitECS(void *memory, size_t size);
void BECS_ResetECS(BECS_ECS *ecs);
BECS_Entity BECS_EntityCreate(BECS_ECS *ecs); BECS_Entity BECS_EntityCreate(BECS_ECS *ecs);
void BECS_EntityDestroy(BECS_ECS *ecs, BECS_Entity entity); void BECS_EntityDestroy(BECS_ECS *ecs, BECS_Entity entity);
bool BECS_IsEntityAlive(BECS_ECS *ecs, BECS_Entity entity); bool BECS_IsEntityAlive(BECS_ECS *ecs, BECS_Entity entity);
@ -72,6 +83,7 @@ struct BECS_ECS {
BECS_Arena arena; BECS_Arena arena;
/* Entity Management */ /* Entity Management */
BECS_Entity nextEntity;
uint32_t entityCount; uint32_t entityCount;
BECS_Signature entitySignatures[BECS_MAX_ENTITIES]; BECS_Signature entitySignatures[BECS_MAX_ENTITIES];
bool aliveEntites[BECS_MAX_ENTITIES]; bool aliveEntites[BECS_MAX_ENTITIES];
@ -90,12 +102,12 @@ static BECS_Signature BECS_SignatureSet(BECS_Signature sig, BECS_ComponentID com
return sig | (1ULL << componentId); return sig | (1ULL << componentId);
} }
static bool ecs_signature_has(BECS_Signature sig, BECS_ComponentID component_id) static bool BECS_SignatureHas(BECS_Signature sig, BECS_ComponentID component_id)
{ {
return (sig & (1ULL << component_id)) != 0; return (sig & (1ULL << component_id)) != 0;
} }
static bool ecs_signature_matches(BECS_Signature entitySig, BECS_Signature querySig) static bool BECS_SignatureMatches(BECS_Signature entitySig, BECS_Signature querySig)
{ {
return (entitySig & querySig) == querySig; return (entitySig & querySig) == querySig;
} }
@ -197,6 +209,29 @@ static bool BECS_ComponentPoolHas(BECS_ComponentPool *pool, BECS_Entity entity)
return pool->sparseArray[entity] != UINT32_MAX; return pool->sparseArray[entity] != UINT32_MAX;
} }
/* Helper API Functions */
size_t BECS_GetMinMemoryArenaSize(size_t *componentSizes, size_t arrayLength)
{
assert(arrayLength < BECS_MAX_COMPONENTS);
size_t totalSize = 0;
totalSize += sizeof(BECS_ECS);
totalSize += sizeof(BECS_ComponentPool) * BECS_MAX_COMPONENTS;
totalSize += sizeof(BECS_Entity) * BECS_MAX_ENTITIES * BECS_MAX_COMPONENTS;
size_t sumCompSizes = 0;
uint32_t i;
for (i = 0; i < arrayLength; i++)
{
sumCompSizes += componentSizes[i];
}
sumCompSizes *= BECS_MAX_ENTITIES;
totalSize += sumCompSizes;
return totalSize;
}
/* World API Functions */ /* World API Functions */
BECS_ECS BECS_InitECS(void *memory, size_t size) BECS_ECS BECS_InitECS(void *memory, size_t size)
@ -205,9 +240,10 @@ BECS_ECS BECS_InitECS(void *memory, size_t size)
ecs.arena = BECS_CreateArena(memory, size); ecs.arena = BECS_CreateArena(memory, size);
ecs.entityCount = 0; ecs.entityCount = 0;
memset(ecs.entitySignatures, 0, sizeof(BECS_Signature) * BECS_MAX_ENTITIES); memset(ecs.entitySignatures, 0, sizeof(BECS_Signature) * BECS_MAX_ENTITIES);
memset(ecs.aliveEntites, 0, sizeof(bool) * BECS_MAX_ENTITIES); memset(ecs.aliveEntites, false, sizeof(bool) * BECS_MAX_ENTITIES);
memset(ecs.freeEntities, BECS_NULL_ENTITY, sizeof(BECS_Entity) * BECS_MAX_ENTITIES); memset(ecs.freeEntities, BECS_NULL_ENTITY, sizeof(BECS_Entity) * BECS_MAX_ENTITIES);
ecs.freeEntityCount = 0; ecs.freeEntityCount = 0;
ecs.nextEntity = 0;
ecs.componentTypeCount = 0; ecs.componentTypeCount = 0;
uint32_t i; uint32_t i;
@ -225,9 +261,10 @@ void BECS_ResetECS(BECS_ECS *ecs)
ecs->arena = BECS_CreateArena(ecs->arena.memory, ecs->arena.capacity); ecs->arena = BECS_CreateArena(ecs->arena.memory, ecs->arena.capacity);
ecs->entityCount = 0; ecs->entityCount = 0;
memset(ecs->entitySignatures, 0, sizeof(BECS_Signature) * BECS_MAX_ENTITIES); memset(ecs->entitySignatures, 0, sizeof(BECS_Signature) * BECS_MAX_ENTITIES);
memset(ecs->aliveEntites, 0, sizeof(bool) * BECS_MAX_ENTITIES); memset(ecs->aliveEntites, false, sizeof(bool) * BECS_MAX_ENTITIES);
memset(ecs->freeEntities, BECS_NULL_ENTITY, sizeof(BECS_Entity) * BECS_MAX_ENTITIES); memset(ecs->freeEntities, BECS_NULL_ENTITY, sizeof(BECS_Entity) * BECS_MAX_ENTITIES);
ecs->freeEntityCount = 0; ecs->freeEntityCount = 0;
ecs->nextEntity = 0;
ecs->componentTypeCount = 0; ecs->componentTypeCount = 0;
uint32_t i; uint32_t i;
@ -240,20 +277,60 @@ void BECS_ResetECS(BECS_ECS *ecs)
/* Entity API Functions */ /* Entity API Functions */
/* TODO: Implement Entity API Functions
BECS_Entity BECS_EntityCreate(BECS_ECS *ecs) BECS_Entity BECS_EntityCreate(BECS_ECS *ecs)
{ {
BECS_Entity entity = BECS_NULL_ENTITY;
if (ecs->nextEntity + 1 > BECS_NULL_ENTITY)
{
return entity;
}
if (ecs->freeEntityCount)
{
/* Pop entity off the back of the free list */
entity = ecs->freeEntities[--ecs->freeEntityCount];
ecs->entitySignatures[entity] = 0;
ecs->aliveEntites[entity] = true;
return entity;
}
entity = ecs->nextEntity;
ecs->aliveEntites[entity] = true;
ecs->entitySignatures[entity] = 0;
ecs->nextEntity++;
ecs->entityCount++;
return entity;
} }
void BECS_EntityDestroy(BECS_ECS *ecs, BECS_Entity entity) void BECS_EntityDestroy(BECS_ECS *ecs, BECS_Entity entity)
{ {
if (!ecs->aliveEntites[entity])
{
return;
}
uint32_t i;
for (i = 0; i < BECS_MAX_COMPONENTS; i++)
{
BECS_Signature sig = ecs->entitySignatures[entity];
if (BECS_SignatureHas(sig, i))
{
BECS_ComponentRemove(ecs, entity, i);
}
}
ecs->aliveEntites[entity] = false;
ecs->entitySignatures[entity] = 0;
ecs->freeEntities[ecs->freeEntityCount] = entity;
ecs->entityCount--;
ecs->freeEntityCount++;
} }
bool BECS_IsEntityAlive(BECS_ECS *ecs, BECS_Entity entity) bool BECS_IsEntityAlive(BECS_ECS *ecs, BECS_Entity entity)
{ {
return ecs->aliveEntites[entity];
} }
*/
/* Component API Functions */ /* Component API Functions */
@ -306,7 +383,7 @@ bool BECS_ComponentHas(BECS_ECS *ecs, BECS_Entity entity, BECS_ComponentID compo
{ {
return false; return false;
} }
return ecs_signature_has(ecs->entitySignatures[entity], componentId); return BECS_SignatureHas(ecs->entitySignatures[entity], componentId);
} }
#endif /* BECS_IMPLEMENTATION */ #endif /* BECS_IMPLEMENTATION */