#include "scene.hpp" #include "ecs.hpp" #include "pk.h" #include #include struct pke_scene_master { pk_membucket *bkt; pk_bkt_arr_t bc; } scene_mstr; void pke_scene_master_init() { scene_mstr.bkt = pk_mem_bucket_create("pk_bkt_arr scene", 1024 * 1024, PK_MEMBUCKET_FLAG_NONE); new (&scene_mstr.bc) pk_bkt_arr_t{ pk_bkt_arr_handle_MAX_constexpr, scene_mstr.bkt, scene_mstr.bkt }; } void pke_scene_master_teardown() { pk_bkt_arr_teardown(&scene_mstr.bc); pk_mem_bucket_destroy(scene_mstr.bkt); } pke_scene *pke_scene_create(const char *scene_name) { NULL_CHAR_ARR(safe_scene_name, SCENE_NAME_MAX_LEN); size_t offset; pk_iter_t it{}; bool valid; std::filesystem::path p(scene_name); struct pke_scene *scene = nullptr; sprintf(safe_scene_name, "%.15s", p.stem().c_str()); /* 2025-09-05 JCB * There used to be logic here enforcing names unique scene names. */ valid = pk_bkt_arr_iter_begin(&scene_mstr.bc, &it); while (valid == true) { // TODO add uuid logic here. if (false) { fprintf(stderr, "[pke_scene_create] failed to create scene: pke_scene::name already in use."); } valid = pk_bkt_arr_iter_increment(&scene_mstr.bc, &it); } SceneHandle scene_handle{ pk_bkt_arr_new_handle(&scene_mstr.bc) }; if (scene_handle == SceneHandle_MAX) { fprintf(stderr, "[pke_scene_create] failed to get new scene handle from BucketContainer."); return nullptr; } scene = &scene_mstr.bc[scene_handle]; new (scene) pke_scene{}; ECS_CreateEntity(scene); scene->file_path.val = 0; scene->file_path.length = 0; scene->file_path.reserved = 0; scene->scene_handle = scene_handle; offset = (strlen(safe_scene_name) > SCENE_NAME_MAX_LEN ? strlen(safe_scene_name) - SCENE_NAME_MAX_LEN : 0); for (int i = 0; i < SCENE_NAME_MAX_LEN; ++i) { scene->name[i] = safe_scene_name[i + offset]; } return scene; } struct pke_scene *pke_scene_get_by_handle(SceneHandle scene_handle) { return &scene_mstr.bc[scene_handle]; } struct pke_scene *pke_scene_get_by_name(const char *scene_name) { assert(scene_name != nullptr); NULL_CHAR_ARR(safe_name, SCENE_NAME_MAX_LEN + 1); strncpy(safe_name, scene_name, SCENE_NAME_MAX_LEN + 1); using SceneFindFn = pk_tmpln_2; SceneFindFn scene_find_cb{}; scene_find_cb.func = [&safe_name](const struct pke_scene *user_obj_data, const struct pke_scene *arr_obj_data) { (void)user_obj_data; return memcmp(safe_name, arr_obj_data->name, PK_MIN(strlen(safe_name), SCENE_NAME_MAX_LEN)) == 0; }; SceneHandle handle { pk_bkt_arr_find_first_handle(&scene_mstr.bc, &SceneFindFn::invoke, &scene_find_cb, NULL) }; if (handle == SceneHandle_MAX) return nullptr; return &scene_mstr.bc[handle]; } pk_bkt_arr *pke_scene_get_scenes() { return &scene_mstr.bc; } void pke_scene_tick(double delta) { (void)delta; pk_iter_t iter; bool b; b = pk_bkt_arr_iter_begin(&scene_mstr.bc, &iter); while (b == true) { if (iter->isMarkedForRemoval == true) { if (iter->file_path.reserved > 0) { pk_delete_arr(iter->file_path.val, iter->file_path.reserved); } pk_bkt_arr_free_handle(&scene_mstr.bc, iter->scene_handle); new (&*iter) pke_scene{}; } b = pk_bkt_arr_iter_increment(&scene_mstr.bc, &iter); } }