#include "level.hpp" #include "bucketed-array.hpp" #include "ecs.hpp" #include "pk.h" struct level_mstr { BucketContainer bc; } level_mstr; void PkeLevel_Init() { Buckets_Init(level_mstr.bc); } void PkeLevel_Teardown() { Buckets_Destroy(level_mstr.bc); } /* PkeLevel *PkeLevel_Get_Inner(LevelHandle handle) { if ( || handle.itemIndex >= level_mstr.bc.limits.itemIndex || (handle.bucketIndex == handle.bucketIndex) { } return &level_mstr.bc.buckets[handle.bucketIndex][handle.itemIndex]; } */ PkeLevel *PkeLevel_Create(const char *levelName) { NULL_CHAR_ARR(safe_name, LEVEL_NAME_MAX_LEN + 1); size_t len = strlen(levelName); size_t start = len <= (LEVEL_NAME_MAX_LEN - 1) ? 0 : len - (LEVEL_NAME_MAX_LEN - 1); sprintf(safe_name, pke_level_name_printf_format, levelName + start); PkeLevel *lvl = PkeLevel_GetByName(levelName); if (lvl != nullptr) { fprintf(stderr, "[PkeLevel_Create] Failed to create new level: name already exists."); return nullptr; } LevelHandle level_handle = Buckets_NewHandle(level_mstr.bc); if (level_handle == LevelHandle_MAX) { fprintf(stderr, "[PkeLevel_Create] Failed to create new level handle from BucketContainer"); return nullptr; } lvl = &level_mstr.bc[level_handle]; ECS_CreateEntity(lvl); if (lvl->bkt == nullptr) { lvl->bkt = pk_bucket_create(levelName, PK_DEFAULT_BUCKET_SIZE, false); } return lvl; } PkeLevel *PkeLevel_Get(LevelHandle handle) { return &level_mstr.bc[handle]; } PkeLevel *PkeLevel_GetByName(const char *levelName) { NULL_CHAR_ARR(safe_name, LEVEL_NAME_MAX_LEN + 1); auto len = strlen(levelName); auto start = len <= (LEVEL_NAME_MAX_LEN - 1) ? 0 : len - (LEVEL_NAME_MAX_LEN - 1); sprintf(safe_name, pke_level_name_printf_format, levelName + start); pk_handle_bucket_index_T b; pk_handle_item_index_T i, ii; for (b = 0; b < level_mstr.bc.pkeHandle.bucketIndex; ++b) { ii = level_mstr.bc.pkeHandle.bucketIndex == b ? level_mstr.bc.pkeHandle.itemIndex : level_mstr.bc.limits.itemIndex; for (i = 0; i < ii; ++i) { if (memcmp(safe_name, level_mstr.bc.buckets[b][i].name, LEVEL_NAME_MAX_LEN) == 0) { return &level_mstr.bc.buckets[b][i]; } } } return nullptr; } pk_handle_bucket_index_T pke_level_get_bucket_count() { return level_mstr.bc.pkeHandle.bucketIndex + 1; } struct PkeLevel *pke_level_get_levels(pk_handle_bucket_index_T bucket_index, pk_handle_item_index_T *item_count) { assert(bucket_index <= level_mstr.bc.pkeHandle.bucketIndex); assert(item_count != nullptr); *item_count = bucket_index == level_mstr.bc.pkeHandle.bucketIndex ? level_mstr.bc.pkeHandle.itemIndex : level_mstr.bc.limits.itemIndex; return level_mstr.bc.buckets[bucket_index]; } void PkeLevel_Remove(LevelHandle handle) { PkeLevel *lvl = &level_mstr.bc[handle]; assert(lvl == nullptr && "Failed to find level to remove by requested LevelHandle"); // TODO mark bucket slot as open ECS_MarkForRemoval(lvl); pk_bucket_reset(lvl->bkt); lvl->levelHandle = LevelHandle_MAX; }