summaryrefslogtreecommitdiff
path: root/src/scene.cpp
blob: 7d7ee209c1f0668521a342e049e3c2c5bb1b9645 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

#include "scene.hpp"
#include "ecs.hpp"
#include "pk.h"

#include <string.h>

#include <filesystem>

struct pke_scene_master {
	pk_membucket *bkt;
	pk_bkt_arr_t<pke_scene> 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<pke_scene>{ 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<pke_scene> 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<bool, const struct pke_scene *, const struct pke_scene *, const void *, const void *>;
	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<pke_scene> 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<char>(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);
	}
}