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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
#include "scene.hpp"
#include "ecs.hpp"
#include "pk.h"
#include "serialization.hpp"
#include "game-settings.hpp"
#include <fstream>
#include <string.h>
#include <filesystem>
struct pke_scene_master {
pk_bkt_arr_t<pke_scene> bc;
} scene_mstr;
void pke_scene_master_init() {
new (&scene_mstr.bc) pk_bkt_arr_t<pke_scene>{ pk_bkt_arr_handle_MAX_constexpr };
}
void pke_scene_master_teardown() {
scene_mstr.bc.~pk_bkt_arr_t<pke_scene>();
}
pke_scene *pke_scene_create(const char *scene_name) {
NULL_CHAR_ARR(safe_scene_name, SCENE_NAME_MAX_LEN);
size_t offset;
std::filesystem::path p(scene_name);
sprintf(safe_scene_name, "%.15s", p.stem().c_str());
struct pke_scene *scene = pke_scene_get_by_name(safe_scene_name);
if (scene != nullptr) {
fprintf(stderr, "[pke_scene_create] failed to create scene: pke_scene::name already in use.");
return nullptr;
}
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->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];
}
// TODO remove me? Need to decide if we always read from files or if we should have a serialized representation of a scene
struct pke_scene *pke_scene_get_by_path(const char *file_path) {
std::ifstream f(file_path);
if (!f.is_open()) {
fprintf(stderr, "[pke_scene_get_by_name] Scene not found in memory nor filesystem: '%s'\n", file_path);
return nullptr;
}
srlztn_deserialize_helper *h = pke_deserialize_init(pkeSettings.mem_bkt.game_transient);
h->scene = pke_scene_create(file_path);
pke_deserialize_scene_from_stream(f, h);
pke_deserialize_teardown(h);
return h->scene;
}
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_remove(SceneHandle handle) {
uint32_t i;
pke_scene *scn = &scene_mstr.bc[handle];
assert(scn != nullptr && "[pke_scene_remove] Failed to find scene by requested SceneHandle");
ECS_MarkForRemoval(scn);
for (i = 0; i < scn->cameras.next; ++i) {
PkeCamera_Destroy(scn->cameras[i]);
}
for (i = 0; i < scn->input_handles.next; ++i) {
pke_input_deactivate_set(scn->input_handles[i]);
pke_input_unregister_set(scn->input_handles[i]);
}
if (scn->file_path.reserved > 0) {
pk_delete_arr<char>(scn->file_path.val, scn->file_path.reserved);
}
scn->file_path = {};
scn->name[0] = '\0';
scn->scene_handle = SceneHandle_MAX;
pk_arr_reset(&scn->cameras);
pk_arr_reset(&scn->input_handles);
pk_bkt_arr_free_handle(&scene_mstr.bc, handle);
}
void pke_scene_register_camera(SceneHandle scene_handle, CameraHandle cameraHandle) {
assert(scene_handle != SceneHandle_MAX);
assert(cameraHandle != CameraHandle_MAX);
pke_scene *scene = pke_scene_get_by_handle(scene_handle);
assert(scene != nullptr && "Failed to find scene by requested SceneHandle");
pk_arr_append(&scene->cameras, &cameraHandle);
}
void pke_scene_register_input_action_set(SceneHandle scene_handle, pke_input_action_set_handle handle) {
assert(scene_handle != SceneHandle_MAX);
assert(handle != pke_input_action_set_handle_MAX);
pke_scene *scene = pke_scene_get_by_handle(scene_handle);
assert(scene != nullptr && "Failed to find scene by requested SceneHandle");
pk_arr_append_t(&scene->input_handles, handle);
}
|