summaryrefslogtreecommitdiff
path: root/src/level.cpp
blob: 15517ac2c26d8571a6fdd76f051cb18db39340a7 (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

#include "level.hpp"

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

struct level_mstr {
	pk_membucket *bkt;
	pk_bkt_arr_t<pke_level> bc;
} level_mstr;

void pke_level_init() {
	level_mstr.bkt = pk_mem_bucket_create("pk_bkt_arr level", 1024 * 1024, PK_MEMBUCKET_FLAG_NONE);
	new (&level_mstr.bc) pk_bkt_arr_t<pke_level>{ pk_bkt_arr_handle_MAX_constexpr, level_mstr.bkt, level_mstr.bkt };
}

void pke_level_teardown() {
	pk_bkt_arr_teardown(&level_mstr.bc);
	pk_mem_bucket_destroy(level_mstr.bkt);
}

/*
pke_level *pke_level_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];
}
*/

pke_level *pke_level_create(const char *levelName, pk_uuid level_uuid, pk_uuid ev_mgr_uuid) {
	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);

	pke_level *lvl = pke_level_get_by_name(levelName);
	if (lvl != nullptr) {
		fprintf(stderr, "[pke_level_Create] Failed to create new level: name already exists.");
		return nullptr;
	}

	LevelHandle level_handle { pk_bkt_arr_new_handle(&level_mstr.bc) };
	if (level_handle == LevelHandle_MAX) {
		fprintf(stderr, "[pke_level_Create] Failed to create new level handle from BucketContainer");
		return nullptr;
	}

	lvl = &level_mstr.bc[level_handle];
	new (lvl) pke_level{};
	lvl->uuid = level_uuid;
	ECS_CreateEntity(lvl);
	(void)ev_mgr_uuid;
	// ECS_CreateEvManager(lvl, ev_mgr_uuid); // TODO

	if (lvl->bkt == nullptr) {
		lvl->bkt = pk_mem_bucket_create(levelName, PK_MEM_DEFAULT_BUCKET_SIZE, PK_MEMBUCKET_FLAG_NONE);
	}

	return lvl;
}

pke_level *pke_level_get(LevelHandle handle) {
	return &level_mstr.bc[handle];
}

pke_level *pke_level_get_by_name(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);

	using LevelFindFn = pk_tmpln_2<bool, const struct pke_level *, const struct pke_level *, const void *, const void *>;
	LevelFindFn scene_find_cb{};
	scene_find_cb.func = [&safe_name](const struct pke_level *user_obj_data, const struct pke_level *arr_obj_data) {
		(void)user_obj_data;
		return memcmp(safe_name, arr_obj_data->name, PK_MIN(strlen(safe_name), LEVEL_NAME_MAX_LEN)) == 0;
	};

	LevelHandle handle { pk_bkt_arr_find_first_handle(&level_mstr.bc, &LevelFindFn::invoke, &scene_find_cb, NULL) };
	if (handle == LevelHandle_MAX) return nullptr;
	return &level_mstr.bc[handle];
}

struct pk_bkt_arr *pke_level_get_levels() {
	return &level_mstr.bc;
}

void pke_level_remove(LevelHandle handle) {
	pke_level *lvl = &level_mstr.bc[handle];
	assert(lvl == nullptr && "Failed to find level to remove by requested LevelHandle");
	ECS_MarkForRemoval(lvl);
	pk_mem_bucket_destroy(lvl->bkt);
	pk_bkt_arr_free_handle(&level_mstr.bc, handle);
}