#ifndef BECS_H #define BECS_H #include #include typedef struct BECS_ComponentArray BECS_ComponentArray; typedef struct BECS_Properties BECS_Properties; typedef struct BECS_ECS BECS_ECS; size_t BECS_GetMinMemorySize(BECS_Properties props); BECS_ECS *BECS_Init(void *memory, size_t size, BECS_Properties *props); int32_t BECS_AddComponent(BECS_ECS *ecs, uint32_t entityID, uint64_t componentBitMask, void *component); #define MAX_ENTITY_COUNT 100 #ifdef BECS_IMPLEMENTATION #ifdef MAX_ENTITY_COUNT struct BECS_ComponentArray { uint32_t lastEntityAdded; size_t unitSize; uint32_t length; uint32_t capacity; void *array; }; struct BECS_Properties { uint32_t maxEntities; uint32_t numComponents; size_t *componentSizes; }; struct BECS_ECS { uint64_t *bitMasks; BECS_Properties props; BECS_ComponentArray *componentSets; }; size_t BECS_GetMinMemorySize (BECS_Properties props) { size_t totalSize = 0; totalSize += sizeof(BECS_ECS); totalSize += sizeof(BECS_ComponentArray) * props.numComponents; for (uint32_t i = 0; i < props.numComponents; i++) { totalSize += props.componentSizes[i] * props.maxEntities; totalSize += sizeof(uint64_t); } return totalSize; } BECS_ECS *BECS_Init (void *memory, size_t size, BECS_Properties *props) { BECS_ECS *ecs = (BECS_ECS *)memory; uint64_t *bitMasks = (uint64_t *)(ecs + 1); BECS_ComponentArray *componentSets = (BECS_ComponentArray *)((uint8_t *)(ecs + 1) + props->maxEntities); ecs->bitMasks = bitMasks; ecs->componentSets = componentSets; ecs->props = *props; for (uint32_t i = 0; i < props->maxEntities; i++) { ecs->bitMasks[i] = 0; } for (uint32_t i = 0; i < props->numComponents; i++) { ecs->componentSets[i].unitSize = props->componentSizes[i]; ecs->componentSets[i].capacity = ecs->componentSets[i].unitSize * props->maxEntities; ecs->componentSets[i].lastEntityAdded = props->maxEntities + 1; ecs->componentSets[i].length = 0; } uint32_t index = 0; // FIX: This is completely fucked. I feel like I am overcomplicating this... Might be easier to use a defined constant :/ for (uint32_t i = 0; i < props->numComponents; i++) { uint32_t index = i; if (index - 1 > props->numComponents) { index = 1; } ecs->componentSets[index - 1].array = componentSets + 4; } return ecs; } int32_t BECS_AddComponent(BECS_ECS *ecs, uint32_t entityID, uint64_t componentBitMask, void *component) { int32_t result = 0; if (componentBitMask == 0) { return result; } uint32_t componentType = 0; while (!(componentBitMask & 1)) { componentBitMask >>= 1; componentType++; } ecs->bitMasks[entityID] = ecs->bitMasks[entityID] | componentBitMask; uint32_t insertIndex = ecs->componentSets[componentType].length; if (insertIndex > ecs->props.maxEntities) { return result; } size_t componentSize = ecs->props.componentSizes[componentType]; uint8_t *componentArray = (uint8_t *)ecs->componentSets[componentType].array; uint8_t *source = (uint8_t *)component; componentArray += componentSize; while (componentSize > 0) { *componentArray = *source; componentSize--; } ecs->componentSets[componentType].length++; result = 1; return result; } // int32_t // BECS_RemoveComponent() // { // } #endif #endif #endif