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

101
becs3.h
View file

@ -1,8 +1,15 @@
/*
* 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
* #include "becs.h"
*/
@ -28,6 +35,10 @@ typedef struct BECS_ECS BECS_ECS;
typedef uint32_t BECS_Entity;
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);
void BECS_EntityDestroy(BECS_ECS *ecs, BECS_Entity entity);
bool BECS_IsEntityAlive(BECS_ECS *ecs, BECS_Entity entity);
@ -35,7 +46,7 @@ bool BECS_IsEntityAlive(BECS_ECS *ecs, BECS_Entity entity);
BECS_ComponentID BECS_ComponentRegister(BECS_ECS *ecs, size_t componentSize, size_t maximumComponentCount);
void *BECS_ComponentAdd(BECS_ECS *ecs, BECS_Entity entity, BECS_ComponentID componentId);
void BECS_ComponentRemove(BECS_ECS *ecs, BECS_Entity entity, BECS_ComponentID componentId);
void* BECS_ComponentGet(BECS_ECS *ecs, BECS_Entity entity, BECS_ComponentID componentId);
void *BECS_ComponentGet(BECS_ECS *ecs, BECS_Entity entity, BECS_ComponentID componentId);
bool BECS_ComponentHas(BECS_ECS *ecs, BECS_Entity entity, BECS_ComponentID componentId);
#ifdef BECS_IMPLEMENTATION
@ -72,6 +83,7 @@ struct BECS_ECS {
BECS_Arena arena;
/* Entity Management */
BECS_Entity nextEntity;
uint32_t entityCount;
BECS_Signature entitySignatures[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);
}
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;
}
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;
}
@ -197,6 +209,29 @@ static bool BECS_ComponentPoolHas(BECS_ComponentPool *pool, BECS_Entity entity)
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 */
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.entityCount = 0;
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);
ecs.freeEntityCount = 0;
ecs.nextEntity = 0;
ecs.componentTypeCount = 0;
uint32_t i;
@ -225,9 +261,10 @@ void BECS_ResetECS(BECS_ECS *ecs)
ecs->arena = BECS_CreateArena(ecs->arena.memory, ecs->arena.capacity);
ecs->entityCount = 0;
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);
ecs->freeEntityCount = 0;
ecs->nextEntity = 0;
ecs->componentTypeCount = 0;
uint32_t i;
@ -240,20 +277,60 @@ void BECS_ResetECS(BECS_ECS *ecs)
/* Entity API Functions */
/* TODO: Implement Entity API Functions
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)
{
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)
{
return ecs->aliveEntites[entity];
}
*/
/* Component API Functions */
@ -290,7 +367,7 @@ void BECS_ComponentRemove(BECS_ECS *ecs, BECS_Entity entity, BECS_ComponentID co
ecs->entitySignatures[entity] &= ~(1ULL << componentId);
}
void* BECS_ComponentGet(BECS_ECS *ecs, BECS_Entity entity, BECS_ComponentID componentId)
void *BECS_ComponentGet(BECS_ECS *ecs, BECS_Entity entity, BECS_ComponentID componentId)
{
if (!ecs->aliveEntites[entity])
@ -306,7 +383,7 @@ bool BECS_ComponentHas(BECS_ECS *ecs, BECS_Entity entity, BECS_ComponentID compo
{
return false;
}
return ecs_signature_has(ecs->entitySignatures[entity], componentId);
return BECS_SignatureHas(ecs->entitySignatures[entity], componentId);
}
#endif /* BECS_IMPLEMENTATION */