diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-04-21 15:46:46 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-04-21 15:46:46 -0400 |
| commit | ef37d054dfe5812efa9eefb4b9b18621fdabac25 (patch) | |
| tree | 713042c875004da0058bf5813c4b2b736b6c4ed3 | |
| parent | a066448effaa9a56c049136067a73ba0156f65d3 (diff) | |
pke: first-pass serializing ui and font renders
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | src/camera.cpp | 2 | ||||
| -rw-r--r-- | src/components.hpp | 18 | ||||
| -rw-r--r-- | src/font.cpp | 19 | ||||
| -rw-r--r-- | src/font.hpp | 9 | ||||
| -rw-r--r-- | src/game.cpp | 9 | ||||
| -rw-r--r-- | src/serialization-camera.cpp | 19 | ||||
| -rw-r--r-- | src/serialization-camera.hpp | 4 | ||||
| -rw-r--r-- | src/serialization-font.cpp | 143 | ||||
| -rw-r--r-- | src/serialization-font.hpp | 13 | ||||
| -rw-r--r-- | src/serialization-static-ui.cpp | 245 | ||||
| -rw-r--r-- | src/serialization-static-ui.hpp | 10 | ||||
| -rw-r--r-- | src/serialization.cpp | 7 | ||||
| -rw-r--r-- | src/serialization.hpp | 29 | ||||
| -rw-r--r-- | src/static-ui.cpp | 13 | ||||
| -rw-r--r-- | src/static-ui.hpp | 7 |
16 files changed, 512 insertions, 39 deletions
@@ -186,6 +186,8 @@ $(DIR_BIN)/libpke.a: $(DIR_OBJ)/scene.o $(DIR_BIN)/libpke.a: $(DIR_OBJ)/serialization.o $(DIR_BIN)/libpke.a: $(DIR_OBJ)/serialization-camera.o $(DIR_BIN)/libpke.a: $(DIR_OBJ)/serialization-component.o +$(DIR_BIN)/libpke.a: $(DIR_OBJ)/serialization-font.o +$(DIR_BIN)/libpke.a: $(DIR_OBJ)/serialization-static-ui.o $(DIR_BIN)/libpke.a: $(DIR_OBJ)/static-cube.o $(DIR_BIN)/libpke.a: $(DIR_OBJ)/static-plane.o $(DIR_BIN)/libpke.a: $(DIR_OBJ)/static-ui.o @@ -223,6 +225,8 @@ $(DIR_DBG)/libpke.a: $(DIR_OBJ)/scene.so $(DIR_DBG)/libpke.a: $(DIR_OBJ)/serialization.so $(DIR_DBG)/libpke.a: $(DIR_OBJ)/serialization-camera.so $(DIR_DBG)/libpke.a: $(DIR_OBJ)/serialization-component.so +$(DIR_DBG)/libpke.a: $(DIR_OBJ)/serialization-font.so +$(DIR_DBG)/libpke.a: $(DIR_OBJ)/serialization-static-ui.so $(DIR_DBG)/libpke.a: $(DIR_OBJ)/static-cube.so $(DIR_DBG)/libpke.a: $(DIR_OBJ)/static-plane.so $(DIR_DBG)/libpke.a: $(DIR_OBJ)/static-ui.so diff --git a/src/camera.cpp b/src/camera.cpp index 1bc1465..8b7abe9 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -20,7 +20,7 @@ btSphereShape CameraShape{1.f}; PkeCamera &PkeCamera_Register_Inner(PkeCamera &cam, CompInstance &inst, const InstPos &instPos) { btVector3 gravity(0.f, 0.f, 0.f); - inst.flags |= COMPONENT_INSTANCE_FLAG_DO_NOT_SERIALIZE; + inst.comp_instance_flags |= COMPONENT_INSTANCE_FLAG_DO_NOT_SERIALIZE; cam.phys.instHandle = inst.instanceHandle; inst.physicsLayer = PhysicsCollision{0}; inst.physicsMask = PhysicsCollision{0}; diff --git a/src/components.hpp b/src/components.hpp index 44aaa30..968cd23 100644 --- a/src/components.hpp +++ b/src/components.hpp @@ -25,10 +25,22 @@ constexpr InstanceHandle InstanceHandle_MAX = InstanceHandle{ pk_handle_MAX_cons constexpr SceneHandle SceneHandle_MAX = SceneHandle{ pk_handle_MAX_constexpr }; constexpr LevelHandle LevelHandle_MAX = LevelHandle{ pk_handle_MAX_constexpr }; +TypeSafeInt_constexpr(ENTITY_FLAGS, uint64_t, 0xFFFFFFFFFFFFFFFF); +TypeSafeInt_constexpr(COMPONENT_INSTANCE_FLAGS, uint64_t, 0xFFFFFFFFFFFFFFFF); + +constexpr ENTITY_FLAGS ENTITY_FLAG_NONE = ENTITY_FLAGS(0x00); +constexpr ENTITY_FLAGS ENTITY_FLAG_DO_NOT_SERIALIZE = ENTITY_FLAGS(0x01); + +constexpr COMPONENT_INSTANCE_FLAGS COMPONENT_INSTANCE_FLAG_NONE + = COMPONENT_INSTANCE_FLAGS(0x00); +constexpr COMPONENT_INSTANCE_FLAGS COMPONENT_INSTANCE_FLAG_DO_NOT_SERIALIZE + = COMPONENT_INSTANCE_FLAGS(0x01); + struct Entity_Base { EntityHandle handle = EntityHandle_MAX; EntityHandle parentHandle = EntityHandle_MAX; pk_uuid uuid = pk_uuid_max; + ENTITY_FLAGS entity_flags = ENTITY_FLAG_NONE; bool isMarkedForRemoval = false; }; @@ -53,10 +65,6 @@ struct CompGrBinds { PkeCallback collisionCallback{}; }; -enum COMPONENT_INSTANCE_FLAGS : unsigned long long { - COMPONENT_INSTANCE_FLAG_NONE = 0x00, - COMPONENT_INSTANCE_FLAG_DO_NOT_SERIALIZE = 0x01, -}; struct InstPos { btTransform posRot; btVector3 scale; @@ -67,7 +75,7 @@ struct InstBt { btRigidBody *rigidBody = nullptr; }; struct CompInstance { - unsigned long long flags = COMPONENT_INSTANCE_FLAG_NONE; + COMPONENT_INSTANCE_FLAGS comp_instance_flags = COMPONENT_INSTANCE_FLAG_NONE; EntityHandle entHandle = EntityHandle_MAX; GrBindsHandle grBindsHandle = GrBindsHandle_MAX; InstanceHandle instanceHandle = InstanceHandle_MAX; diff --git a/src/font.cpp b/src/font.cpp index 9c8f1bc..c94890b 100644 --- a/src/font.cpp +++ b/src/font.cpp @@ -7,6 +7,7 @@ #include "static-plane.hpp" #include "vendor-stb-image-include.h" #include "game-settings.hpp" +#include "ecs.hpp" #include <vulkan/vulkan_core.h> @@ -734,7 +735,7 @@ void FontType_Unload(FontTypeIndex idx) { // However, the new buffer is exactly the length it needs to be and no greater. // Consider using a heuristic to allocate a buffer larger than needed. // At the time of writing, the only way to do this is to un-register text. -FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_str str, FontRenderSettings *settings) { +FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent) { assert(settings != nullptr); PKVK_TmpBufferDetails tmpBufferDetails{}; VkDeviceSize byteCount; @@ -755,9 +756,12 @@ FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_str str ft->renders = arr; } fr = &ft->renders[(FontRenderIndex_T)idx_fr]; - fr->handle.index_ft = idx_ft; - fr->handle.index_fr = idx_fr; + *fr = {}; + ECS_CreateEntity(fr, parent); + fr->fr_handle.index_ft = idx_ft; + fr->fr_handle.index_fr = idx_fr; fr->settings = *settings; + fr->text = str; // insert new characters into tmp buffer { @@ -940,7 +944,7 @@ FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_str str } PKVK_EndBuffer(tmpBufferDetails); - return fr->handle; + return fr->fr_handle; } void FontType_UpdateStringRender(FontRenderHandle frh, FontRenderSettings *settings) { @@ -968,4 +972,11 @@ void FontType_RemoveStringRender(FontRenderHandle handle) { fr->buffer_start_index = buffer_start_index; buffer_start_index += fr->n_glyphs; } + if (fr->text.reserved > 0) { + // 2025-04-16 - JCB + // not passing a specific bucket because pk_cstr doesn't store it. + // font.cpp assumes the user has already cloned the string if necessary - only assigns the value. + pk_delete<char>(fr->text.val, fr->text.reserved); + } + ECS_MarkForRemoval(fr); } diff --git a/src/font.hpp b/src/font.hpp index 0396e8d..d31209c 100644 --- a/src/font.hpp +++ b/src/font.hpp @@ -53,16 +53,17 @@ struct FontRenderSettings { float char_scale; float line_height_scale; float char_spacing_scale; - glm::ivec2 surface_area_size; // TODO + glm::ivec2 surface_area_size; glm::ivec2 surface_area_pos; FONT_RENDER_SURFACE_AREA_TYPE_FLAG surface_area_type_flags; // TODO }; -struct FontRender { - FontRenderHandle handle; +struct FontRender : public Entity_Base { uint32_t *glyph_indices; + FontRenderHandle fr_handle; uint32_t n_glyphs; uint32_t buffer_start_index; FontRenderSettings settings; + pk_cstr text; }; struct FontTypeMSDFSettings { float minimum_scale; @@ -120,7 +121,7 @@ void FontType_Deserialize(std::istream &stream); FontType* FontType_GetFonts(FontTypeIndex &count); FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle, AssetHandle glyphsHandle, FontTypeMSDFSettings *msdf_settings, FontTypeSpacing *spacing); void FontType_Unload(FontTypeIndex idx); -FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, pk_str str, FontRenderSettings *settings); +FontRenderHandle FontType_AddStringRender(FontTypeIndex idx_ft, const pk_cstr &&str, FontRenderSettings *settings, Entity_Base *parent = nullptr); void FontType_UpdateStringRender(FontRenderHandle frh, FontRenderSettings *settings); void FontType_RemoveStringRender(FontRenderHandle frh); diff --git a/src/game.cpp b/src/game.cpp index f00d613..fc6318a 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -162,11 +162,6 @@ void Game_Main(PKEWindowProperties windowProps, const char *executablePath) { } // TODO remove me: temp stuff for testing - pk_cstr test_text = cstring_to_pk_cstr("012\n3456789\tThe quick\r\nbrown fox jumped over the lazy dog."); - // pk_cstr test_text = cstring_to_pk_cstr("%+-*0123456789$"); - // pk_cstr test_text = cstring_to_pk_cstr("$#"); - // pk_cstr test_text = cstring_to_pk_cstr("$"); - pk_cstr test_text2 = cstring_to_pk_cstr("+0123456\n789\tThe quick brown fox jumped over the lazy dog."); FontTypeIndex font_type_count; FontRenderSettings fr_set; FontRenderHandle fr_1; @@ -180,12 +175,12 @@ void Game_Main(PKEWindowProperties windowProps, const char *executablePath) { fr_set.surface_area_pos.y = 1080 / 3.0; fr_set.surface_area_type_flags = FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_NONE; if ((FontType_GetFonts(font_type_count)); font_type_count != FontTypeIndex{0}) { - fr_1 = FontType_AddStringRender(FontTypeIndex{0}, pk_cstr_to_pk_str(&test_text), &fr_set); + fr_1 = FontType_AddStringRender(FontTypeIndex{0}, std::move(cstring_to_pk_cstr("012\n3456789\tThe quick\r\nbrown fox jumped over the lazy dog.")), &fr_set); } if ((FontType_GetFonts(font_type_count)); font_type_count > FontTypeIndex{1}) { fr_set.surface_area_pos.y *= 2; fr_set.surface_area_size.y = 1080 - fr_set.surface_area_pos.y; - fr_2 = FontType_AddStringRender(FontTypeIndex{1}, pk_cstr_to_pk_str(&test_text2), &fr_set); + fr_2 = FontType_AddStringRender(FontTypeIndex{1}, std::move(cstring_to_pk_cstr("+0123456\n789\tThe quick brown fox jumped over the lazy dog.")), &fr_set); } // TODO remove me: temp stuff for testing diff --git a/src/serialization-camera.cpp b/src/serialization-camera.cpp index 0183e29..714ea2c 100644 --- a/src/serialization-camera.cpp +++ b/src/serialization-camera.cpp @@ -10,7 +10,12 @@ #include "vendor-glm-include.hpp" -void pke_serialize_camera(srlztn_serialize_helper *h, const PkeCamera *cam) { +bool pke_serialize_camera(srlztn_serialize_helper *h, const PkeCamera *cam) { + assert(h != nullptr); + assert(cam != nullptr); + if (PK_HAS_FLAG(cam->entity_flags, ENTITY_FLAG_DO_NOT_SERIALIZE)) { + return false; + } PkeCamera c{}; if (cam->uuid != pk_uuid_zed && cam->uuid != pk_uuid_max) { h->o << SRLZTN_CAMERA_UUID << cam->uuid << std::endl; @@ -46,13 +51,10 @@ void pke_serialize_camera(srlztn_serialize_helper *h, const PkeCamera *cam) { BulletToGlm(rot, quat_rot); BulletToGlm(scale, glm_scale); pke_serialize_inst_pos(h, glm_pos, quat_rot, glm_scale); + return true; } -bool FindFirstInstanceHandle(void *handle, void *mapping) { - srlztn_instance_mapping *inst_mapping = reinterpret_cast<srlztn_instance_mapping *>(mapping); - return inst_mapping->serialized_uuid == *reinterpret_cast<pk_uuid *>(handle); -} -void pke_deserialize_camera(srlztn_deserialize_helper *h) { +bool pke_deserialize_camera(srlztn_deserialize_helper *h) { PK_STN_RES stn_res = PK_STN_RES(0); PkeCamera cam{}; cam.type = PKE_CAMERA_TYPE_PERSPECTIVE; @@ -70,7 +72,7 @@ void pke_deserialize_camera(srlztn_deserialize_helper *h) { uint32_t targetInstanceIndex = -1; if (target_uuid != pk_uuid_zed) { - targetInstanceIndex = pk_arr_find_first_index(&h->mapping, &target_uuid, FindFirstInstanceHandle); + targetInstanceIndex = pk_arr_find_first_index(&h->mapping, &target_uuid, srlztn_mapping_find_first_handle_by_uuid); if (targetInstanceIndex == uint32_t(-1)) { fprintf(stderr, "[pke_deserialize_camera] Camera has target instance uuid '" pk_uuid_printf_format "', but failed to find target instance.", pk_uuid_printf_var(target_uuid)); } @@ -95,7 +97,7 @@ void pke_deserialize_camera(srlztn_deserialize_helper *h) { if (rCam.isPrimary == true) { ActiveCamera = &rCam; } - return; + return true; } if (pke_deserialize_inst_pos(h, pos, quat_rot, scale)) { continue; @@ -139,4 +141,5 @@ void pke_deserialize_camera(srlztn_deserialize_helper *h) { continue; } } + return false; } diff --git a/src/serialization-camera.hpp b/src/serialization-camera.hpp index 778febd..ddc2ec4 100644 --- a/src/serialization-camera.hpp +++ b/src/serialization-camera.hpp @@ -4,8 +4,8 @@ #include "serialization.hpp" #include "camera.hpp" -void pke_serialize_camera(srlztn_serialize_helper *helper, const PkeCamera *cam); +bool pke_serialize_camera(srlztn_serialize_helper *helper, const PkeCamera *cam); -void pke_deserialize_camera(srlztn_deserialize_helper *helper); +bool pke_deserialize_camera(srlztn_deserialize_helper *helper); #endif /* PKE_SERIALIZATION_CAMERA_HPP */ diff --git a/src/serialization-font.cpp b/src/serialization-font.cpp new file mode 100644 index 0000000..60ba61d --- /dev/null +++ b/src/serialization-font.cpp @@ -0,0 +1,143 @@ + +#include "serialization-font.hpp" +#include "pk.h" +#include <sstream> + +bool pke_serialize_font_render(srlztn_serialize_helper *h, FontRender *fr) { + assert(h != nullptr); + assert(fr != nullptr); + if (PK_HAS_FLAG(fr->entity_flags, ENTITY_FLAG_DO_NOT_SERIALIZE)) { + return false; + } + if (fr->uuid != pk_uuid_zed && fr->uuid != pk_uuid_max) { + h->o << SRLZTN_UI_FONT_RENDER_UUID << std::endl; + } + if (fr->text.val != nullptr) { + h->o << SRLZTN_UI_FONT_RENDER_TEXT_BEGIN << std::endl; + h->o << fr->text.val << std::endl; + h->o << SRLZTN_UI_FONT_RENDER_TEXT_END << std::endl; + } + return pke_serialize_font_render_settings(h, &fr->settings); +} + +bool pke_deserialize_font_render(srlztn_deserialize_helper *h, FontRender *fr) { + assert(h != nullptr); + assert(fr != nullptr); + uint64_t prefix_len; + if (strncmp(h->read_line, SRLZTN_UI_FONT_RENDER_UUID, strlen(SRLZTN_UI_FONT_RENDER_UUID)) == 0) { + prefix_len = strlen(SRLZTN_UI_FONT_RENDER_UUID); + (h->read_line + prefix_len) >> fr->uuid; + return true; + } + if (strncmp(h->read_line, SRLZTN_UI_FONT_RENDER_TEXT_BEGIN, strlen(SRLZTN_UI_FONT_RENDER_TEXT_BEGIN)) == 0) { + // TODO replace with something that doesn't give the code stds + std::ostringstream ss{}; + bool first = true; + while (h->i->getline(h->read_line, h->read_line_len)) { + if (strncmp(h->read_line, SRLZTN_UI_FONT_RENDER_TEXT_END, strlen(SRLZTN_UI_FONT_RENDER_TEXT_END)) == 0) { + std::string s = ss.str(); + fr->text = cstring_to_pk_cstr(s.c_str()); + break; + } + if (!first) { + first = false; + ss << std::endl; + } + ss << h->read_line; + } + return true; + } + return false; +} + +bool pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRenderSettings *frs) { + if (frs->char_scale != 0.0) { + h->o << SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SCALE << frs->char_scale << std::endl; + } + if (frs->line_height_scale != 0.0) { + h->o << SRLZTN_UI_FONT_RENDER_SETTINGS_LINE_HEIGHT_SCALE << frs->line_height_scale << std::endl; + } + if (frs->char_spacing_scale != 0.0) { + h->o << SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SPACING_SCALE << frs->char_spacing_scale << std::endl; + } + if (frs->surface_area_size != glm::ivec2(0)) { + h->o << SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE << frs->surface_area_size.x << SRLZTN_FILE_NUM_SEPARATOR << frs->surface_area_size.y << std::endl; + } + if (frs->surface_area_pos != glm::ivec2(0)) { + h->o << SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS << frs->surface_area_pos.x << SRLZTN_FILE_NUM_SEPARATOR << frs->surface_area_pos.y << std::endl; + } + if (frs->surface_area_type_flags != FONT_RENDER_SURFACE_AREA_TYPE_FLAGS_NONE) { + h->o << SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_FLAGS << FONT_RENDER_SURFACE_AREA_TYPE_FLAG_T(frs->surface_area_type_flags) << std::endl; + } + return true; +} + +bool pke_deserialize_font_render_settings(srlztn_deserialize_helper *h, FontRenderSettings *frs) { + uint64_t prefix_len; + PK_STN_RES stn_res; + char *str_end; + if (strncmp(h->read_line, SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SCALE, strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SCALE)) == 0) { + prefix_len = strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SCALE); + stn_res = pk_stn(&frs->char_scale, h->read_line + prefix_len, &str_end); + if (stn_res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[%s] Err '%u' parsing '%s' primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SCALE, h->read_line); + } + return true; + } + if (strncmp(h->read_line, SRLZTN_UI_FONT_RENDER_SETTINGS_LINE_HEIGHT_SCALE, strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_LINE_HEIGHT_SCALE)) == 0) { + prefix_len = strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_LINE_HEIGHT_SCALE); + stn_res = pk_stn(&frs->line_height_scale, h->read_line + prefix_len, &str_end); + if (stn_res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[%s] Err '%u' parsing '%s' primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_LINE_HEIGHT_SCALE, h->read_line); + } + return true; + } + if (strncmp(h->read_line, SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SPACING_SCALE, strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SPACING_SCALE)) == 0) { + prefix_len = strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SPACING_SCALE); + stn_res = pk_stn(&frs->char_spacing_scale, h->read_line + prefix_len, &str_end); + if (stn_res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[%s] Err '%u' parsing '%s' primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SPACING_SCALE, h->read_line); + } + return true; + } + if (strncmp(h->read_line, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE, strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE)) == 0) { + prefix_len = strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE); + stn_res = pk_stn(&frs->surface_area_size.x, h->read_line + prefix_len, &str_end); + if (stn_res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[%s] Err '%u' parsing '%s' (x) primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE, h->read_line); + return true; + } + prefix_len += strchr(h->read_line + prefix_len, ',') - (h->read_line + prefix_len); + stn_res = pk_stn(&frs->surface_area_size.y, h->read_line + prefix_len, &str_end); + if (stn_res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[%s] Err '%u' parsing '%s' (y) primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE, h->read_line); + } + return true; + } + if (strncmp(h->read_line, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS, strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS)) == 0) { + prefix_len = strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS); + stn_res = pk_stn(&frs->surface_area_pos.x, h->read_line + prefix_len, &str_end); + if (stn_res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[%s] Err '%u' parsing '%s' (x) primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS, h->read_line); + return true; + } + prefix_len += strchr(h->read_line + prefix_len, ',') - (h->read_line + prefix_len); + stn_res = pk_stn(&frs->surface_area_pos.y, h->read_line + prefix_len, &str_end); + if (stn_res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[%s] Err '%u' parsing '%s' (y) primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS, h->read_line); + } + return true; + } + if (strncmp(h->read_line, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_FLAGS, strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_FLAGS)) == 0) { + prefix_len = strlen(SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_FLAGS); + FONT_RENDER_SURFACE_AREA_TYPE_FLAG_T flags; + stn_res = pk_stn(&flags, h->read_line + prefix_len, &str_end); + if (stn_res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[%s] Err '%u' parsing '%s' primary from: '%s'\n", __FILE__, stn_res, SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_FLAGS, h->read_line); + return true; + } + frs->surface_area_type_flags = FONT_RENDER_SURFACE_AREA_TYPE_FLAG(flags); + return true; + } + return false; +} diff --git a/src/serialization-font.hpp b/src/serialization-font.hpp new file mode 100644 index 0000000..9261a19 --- /dev/null +++ b/src/serialization-font.hpp @@ -0,0 +1,13 @@ +#ifndef PKE_SERIALIZATION_FONT_HPP +#define PKE_SERIALIZATION_FONT_HPP + +#include "serialization.hpp" +#include "font.hpp" + +bool pke_serialize_font_render(srlztn_serialize_helper *h, FontRender *fr); +bool pke_deserialize_font_render(srlztn_deserialize_helper *h, FontRender **fr); + +bool pke_serialize_font_render_settings(srlztn_serialize_helper *h, FontRenderSettings *frs); +bool pke_deserialize_font_render_settings(srlztn_deserialize_helper *h, FontRenderSettings *frs); + +#endif /* PKE_SERIALIZATION_FONT_HPP */ diff --git a/src/serialization-static-ui.cpp b/src/serialization-static-ui.cpp new file mode 100644 index 0000000..ca17c10 --- /dev/null +++ b/src/serialization-static-ui.cpp @@ -0,0 +1,245 @@ + +#include "serialization-static-ui.hpp" +#include "ecs.hpp" +#include "pk.h" +#include "serialization-font.hpp" +#include "static-ui.hpp" + +bool pke_serialize_ui_box_internal(srlztn_serialize_helper *h, pke_ui_box_type_data_text *data) { + if (data->font_render_uuid != pk_uuid_zed) { + h->o << SRLZTN_UI_BOX_DATA_TEXT_FONT_RENDER_UUID << data->font_render_uuid << std::endl; + } + pke_serialize_font_render_settings(h, &data->font_render_settings); + return true; +} + +bool pke_deserialize_ui_box_internal(srlztn_deserialize_helper *h, pke_ui_box_type_data_text *data) { + uint64_t prefix_len; + if (strstr(SRLZTN_UI_BOX_DATA_TEXT_FONT_RENDER_UUID, h->read_line)) { + prefix_len = strlen(SRLZTN_UI_BOX_UUID); + (h->read_line + prefix_len) >> data->font_render_uuid; + return true; + } + return pke_deserialize_font_render_settings(h, &data->font_render_settings); + return false; +} + +bool pke_serialize_ui_box(srlztn_serialize_helper *h, pke_ui_box *box) { + if (box->uuid != pk_uuid_zed && box->uuid != pk_uuid_max) { + h->o << SRLZTN_UI_BOX_UUID << box->uuid << std::endl; + } + if (box->parentHandle != EntityHandle_MAX) { + Entity_Base *e = ECS_GetEntity(box->parentHandle); + h->o << SRLZTN_UI_BOX_PARENT_UUID << e->uuid << std::endl; + } + if (box->flags != PKE_UI_BOX_FLAG_NONE) { + h->o << SRLZTN_UI_BOX_FLAGS << (PKE_UI_BOX_FLAG_T)box->flags << std::endl; + } + if (box->pos_top_left_x != 0.0) { + h->o << SRLZTN_UI_BOX_POS_TOP_LEFT_X << box->pos_top_left_x << std::endl; + } + if (box->pos_top_left_y != 0.0) { + h->o << SRLZTN_UI_BOX_POS_TOP_LEFT_Y << box->pos_top_left_y << std::endl; + } + if (box->min_width != 0.0) { + h->o << SRLZTN_UI_BOX_MIN_WIDTH << box->min_width << std::endl; + } + if (box->min_height != 0.0) { + h->o << SRLZTN_UI_BOX_MIN_HEIGHT << box->min_height << std::endl; + } + if (box->max_width != 0.0) { + h->o << SRLZTN_UI_BOX_MAX_WIDTH << box->max_width << std::endl; + } + if (box->max_height != 0.0) { + h->o << SRLZTN_UI_BOX_MAX_HEIGHT << box->max_height << std::endl; + } + if (box->flex_weight != 0.0) { + h->o << SRLZTN_UI_BOX_FLEX_WEIGHT << box->flex_weight << std::endl; + } + if (box->type != PKE_UI_BOX_TYPE_STANDARD) { + h->o << SRLZTN_UI_BOX_TYPE << (PKE_UI_BOX_TYPE_T)box->type << std::endl; + } + if (box->flex_direction != 0) { + h->o << SRLZTN_UI_BOX_FLEX_DIRECTION << box->flex_direction << std::endl; + } + if (box->layer != 0) { + h->o << SRLZTN_UI_BOX_LAYER << box->layer << std::endl; + } + if (box->type == PKE_UI_BOX_TYPE_TEXT) { + pke_ui_box_type_data_text *d = reinterpret_cast<pke_ui_box_type_data_text *>(box->type_data); + pke_serialize_ui_box_internal(h, d); + } + return true; +} + +bool pke_deserialize_ui_box(srlztn_deserialize_helper *h) { + uint64_t prefix_len; + PK_STN_RES res; + char *stn_end; + pke_ui_box bx{}; + pke_ui_box *parent_box = nullptr; + void *type_data = nullptr; + memset(&bx, 0, sizeof(pke_ui_box)); + bx.type_data = nullptr; + while (h->i->getline(h->read_line, h->read_line_len)) { + if (strstr(SRLZTN_OBJ_END, h->read_line)) { + pke_ui_box *box; + if (parent_box == nullptr) { + box = pke_ui_box_new_root(bx.type, bx.uuid); + } else { + box = pke_ui_box_new_child(parent_box, bx.type, bx.uuid); + } + box->flags = bx.flags; + box->pos_top_left_x = bx.pos_top_left_x; + box->pos_top_left_y = bx.pos_top_left_y; + box->min_width = bx.min_width; + box->min_height = bx.min_height; + box->max_width = bx.max_width; + box->max_height = bx.max_height; + box->flex_weight = bx.flex_weight; + box->type = bx.type; + box->flex_direction = bx.flex_direction; + box->layer = bx.layer; + return true; + } + if (strstr(SRLZTN_UI_BOX_UUID, h->read_line)) { + prefix_len = strlen(SRLZTN_UI_BOX_UUID); + (h->read_line + prefix_len) >> bx.uuid; + continue; + } + if (strstr(SRLZTN_UI_BOX_PARENT_UUID, h->read_line)) { + uint32_t target_instance_index = -1; + pk_uuid id; + prefix_len = strlen(SRLZTN_UI_BOX_PARENT_UUID); + (h->read_line + prefix_len) >> id; + target_instance_index = pk_arr_find_first_index(&h->mapping, &id, srlztn_mapping_find_first_handle_by_uuid); + if (target_instance_index != uint32_t(-1)) { + parent_box = static_cast<pke_ui_box*>(h->mapping[target_instance_index].created_entity); + } + continue; + } + if (strstr(SRLZTN_UI_BOX_FLAGS, h->read_line)) { + prefix_len = strlen(SRLZTN_UI_BOX_FLAGS); + PKE_UI_BOX_FLAG_T flags; + res = pk_stn(&flags, h->read_line + prefix_len, &stn_end); + if (res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i", SRLZTN_UI_BOX_FLAGS, res); + continue; + } + bx.flags = PKE_UI_BOX_FLAG(flags); + continue; + } + if (strstr(SRLZTN_UI_BOX_POS_TOP_LEFT_X, h->read_line)) { + prefix_len = strlen(SRLZTN_UI_BOX_POS_TOP_LEFT_X); + res = pk_stn(&bx.pos_top_left_x, h->read_line + prefix_len, &stn_end); + if (res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i", SRLZTN_UI_BOX_POS_TOP_LEFT_X, res); + continue; + } + continue; + } + if (strstr(SRLZTN_UI_BOX_POS_TOP_LEFT_Y, h->read_line)) { + prefix_len = strlen(SRLZTN_UI_BOX_POS_TOP_LEFT_Y); + res = pk_stn(&bx.pos_top_left_y, h->read_line + prefix_len, &stn_end); + if (res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i", SRLZTN_UI_BOX_POS_TOP_LEFT_Y, res); + continue; + } + continue; + } + if (strstr(SRLZTN_UI_BOX_MIN_WIDTH, h->read_line)) { + prefix_len = strlen(SRLZTN_UI_BOX_MIN_WIDTH); + res = pk_stn(&bx.min_width, h->read_line + prefix_len, &stn_end); + if (res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i", SRLZTN_UI_BOX_MIN_WIDTH, res); + continue; + } + continue; + } + if (strstr(SRLZTN_UI_BOX_MIN_HEIGHT, h->read_line)) { + prefix_len = strlen(SRLZTN_UI_BOX_MIN_HEIGHT); + res = pk_stn(&bx.min_width, h->read_line + prefix_len, &stn_end); + if (res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i", SRLZTN_UI_BOX_MIN_HEIGHT, res); + continue; + } + continue; + } + if (strstr(SRLZTN_UI_BOX_MAX_WIDTH, h->read_line)) { + prefix_len = strlen(SRLZTN_UI_BOX_MAX_WIDTH); + res = pk_stn(&bx.max_width, h->read_line + prefix_len, &stn_end); + if (res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i", SRLZTN_UI_BOX_MAX_WIDTH, res); + continue; + } + continue; + } + if (strstr(SRLZTN_UI_BOX_MAX_HEIGHT, h->read_line)) { + prefix_len = strlen(SRLZTN_UI_BOX_MAX_HEIGHT); + res = pk_stn(&bx.max_width, h->read_line + prefix_len, &stn_end); + if (res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i", SRLZTN_UI_BOX_MAX_HEIGHT, res); + continue; + } + continue; + } + if (strstr(SRLZTN_UI_BOX_FLEX_WEIGHT, h->read_line)) { + prefix_len = strlen(SRLZTN_UI_BOX_FLEX_WEIGHT); + res = pk_stn(&bx.flex_weight, h->read_line + prefix_len, &stn_end); + if (res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i", SRLZTN_UI_BOX_FLEX_WEIGHT, res); + continue; + } + continue; + } + if (strstr(SRLZTN_UI_BOX_FLEX_DIRECTION, h->read_line)) { + prefix_len = strlen(SRLZTN_UI_BOX_FLEX_DIRECTION); + res = pk_stn(&bx.flex_direction, h->read_line + prefix_len, &stn_end); + if (res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i", SRLZTN_UI_BOX_FLEX_DIRECTION, res); + continue; + } + continue; + } + if (strstr(SRLZTN_UI_BOX_LAYER, h->read_line)) { + prefix_len = strlen(SRLZTN_UI_BOX_LAYER); + res = pk_stn(&bx.layer, h->read_line + prefix_len, &stn_end); + if (res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i", SRLZTN_UI_BOX_LAYER, res); + continue; + } + continue; + } + if (strstr(SRLZTN_UI_BOX_TYPE, h->read_line)) { + prefix_len = strlen(SRLZTN_UI_BOX_TYPE); + res = pk_stn(&bx.type, h->read_line + prefix_len, &stn_end); + if (res != PK_STN_RES_SUCCESS) { + fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i", SRLZTN_UI_BOX_TYPE, res); + continue; + } + // TODO specific bucket? + switch (bx.type) { + case PKE_UI_BOX_TYPE_TEXT: + type_data = pk_new<pke_ui_box_type_data_text>(); + break; + default: + fprintf(stderr, "[pke_deserialize_ui_box] Parsed unknown ui box data type from: '%s'", h->read_line); + continue; + } + continue; + } + // TODO something isn't right here, too much room for parsing mistakes + if (bx.type != PKE_UI_BOX_TYPE_STANDARD && type_data != nullptr) { + switch (bx.type) { + case PKE_UI_BOX_TYPE_TEXT: + if (pke_deserialize_ui_box_internal(h, reinterpret_cast<pke_ui_box_type_data_text *>(bx.type_data))) { + continue; + } + break; + default: + continue; + } + } + } + return false; +} diff --git a/src/serialization-static-ui.hpp b/src/serialization-static-ui.hpp new file mode 100644 index 0000000..9026c5d --- /dev/null +++ b/src/serialization-static-ui.hpp @@ -0,0 +1,10 @@ +#ifndef PKE_SERIALIZATION_STATIC_UI_HPP +#define PKE_SERIALIZATION_STATIC_UI_HPP + +#include "static-ui.hpp" +#include "serialization.hpp" + +bool pke_serialize_ui_box(srlztn_serialize_helper *h, pke_ui_box *box); +bool pke_deserialize_ui_box(srlztn_deserialize_helper *h); + +#endif /* PKE_SERIALIZATION_STATIC_UI_HPP */ diff --git a/src/serialization.cpp b/src/serialization.cpp index 507a238..b41c70d 100644 --- a/src/serialization.cpp +++ b/src/serialization.cpp @@ -5,6 +5,11 @@ #include "camera.hpp" #include "ecs.hpp" +bool srlztn_mapping_find_first_handle_by_uuid(void *handle, void *mapping) { + srlztn_instance_mapping *inst_mapping = reinterpret_cast<srlztn_instance_mapping *>(mapping); + return inst_mapping->serialized_uuid == *reinterpret_cast<pk_uuid *>(handle); +} + srlztn_serialize_helper *pke_serialize_init(pk_membucket *bkt) { srlztn_serialize_helper *helper = pk_new<srlztn_serialize_helper>(bkt); // TODO custom allocator @@ -51,7 +56,7 @@ void pke_serialize_file_scene(srlztn_serialize_helper *h) { const auto &instance = instances[i]; if (instance.entHandle == EntityHandle_MAX) continue; - if (instance.flags & COMPONENT_INSTANCE_FLAG_DO_NOT_SERIALIZE) { + if (PK_HAS_FLAG(instance.comp_instance_flags, COMPONENT_INSTANCE_FLAG_DO_NOT_SERIALIZE)) { continue; } h->o << SRLZTN_OBJ_INSTANCE << std::endl; diff --git a/src/serialization.hpp b/src/serialization.hpp index 4b0624c..b6d2bfa 100644 --- a/src/serialization.hpp +++ b/src/serialization.hpp @@ -8,10 +8,12 @@ inline const char* const SRLZTN_FILE_BEGIN = ":PKFB:"; inline const char* const SRLZTN_FILE_END = ":PKFE:"; inline const char* const SRLZTN_FILE_VERSION = ":0:"; +inline const char* const SRLZTN_FILE_NUM_SEPARATOR = ";"; inline const char* const SRLZTN_OBJ_END = ""; inline const char* const SRLZTN_OBJ_INSTANCE = "Instance:"; inline const char* const SRLZTN_OBJ_CAMERA = "Camera:"; +inline const char* const SRLZTN_OBJ_UI_BOX = "Camera:"; inline const char* const SRLZTN_POSROT_POS = "Position: "; inline const char* const SRLZTN_POSROT_ROT = "Rotation: "; @@ -32,6 +34,31 @@ inline const char* const SRLZTN_CAMERA_ORIENTATION = "Orientation: "; inline const char* const SRLZTN_CAMERA_TARGET_INSTANCE_UUID = "TargetUUID: "; inline const char* const SRLZTN_CAMERA_IS_PRIMARY = "IsPrimary: "; +inline const char* const SRLZTN_UI_BOX_UUID = "UUID: "; +inline const char* const SRLZTN_UI_BOX_PARENT_UUID = "ParentUUID: "; +inline const char* const SRLZTN_UI_BOX_FLAGS = "Flags: "; +inline const char* const SRLZTN_UI_BOX_POS_TOP_LEFT_X = "PosTopLeftX: "; +inline const char* const SRLZTN_UI_BOX_POS_TOP_LEFT_Y = "PosTopLeftY: "; +inline const char* const SRLZTN_UI_BOX_MIN_WIDTH = "MinWidthX: "; +inline const char* const SRLZTN_UI_BOX_MIN_HEIGHT = "MinWidthY: "; +inline const char* const SRLZTN_UI_BOX_MAX_WIDTH = "MaxWidthX: "; +inline const char* const SRLZTN_UI_BOX_MAX_HEIGHT = "MaxWidthY: "; +inline const char* const SRLZTN_UI_BOX_FLEX_WEIGHT = "FlexWeight: "; +inline const char* const SRLZTN_UI_BOX_TYPE = "Type: "; +inline const char* const SRLZTN_UI_BOX_FLEX_DIRECTION = "FlexDirection: "; +inline const char* const SRLZTN_UI_BOX_LAYER = "Layer: "; +inline const char* const SRLZTN_UI_BOX_DATA_TEXT_FONT_RENDER_UUID = "FontRenderUUID: "; + +inline const char* const SRLZTN_UI_FONT_RENDER_UUID = "UUID: "; +inline const char* const SRLZTN_UI_FONT_RENDER_TEXT_BEGIN = "TextBegin::"; +inline const char* const SRLZTN_UI_FONT_RENDER_TEXT_END = "::TextEnd"; +inline const char* const SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SCALE = "CharScale"; +inline const char* const SRLZTN_UI_FONT_RENDER_SETTINGS_LINE_HEIGHT_SCALE = "LineHeightScale"; +inline const char* const SRLZTN_UI_FONT_RENDER_SETTINGS_CHAR_SPACING_SCALE = "CharSpacingScale"; +inline const char* const SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_SIZE = "SurfaceAreaSize"; +inline const char* const SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_POS = "SurfaceAreaPos"; +inline const char* const SRLZTN_UI_FONT_RENDER_SETTINGS_SURFACE_AREA_FLAGS = "SurfaceAreaFlags"; + struct srlztn_instance_mapping { pk_uuid serialized_uuid = pk_uuid_zed; Entity_Base *created_entity = nullptr; @@ -52,6 +79,8 @@ struct srlztn_deserialize_helper { pk_arr_t<srlztn_instance_mapping> mapping; }; +bool srlztn_mapping_find_first_handle_by_uuid(void *handle, void *mapping); + srlztn_serialize_helper *pke_serialize_init(pk_membucket *bkt); srlztn_deserialize_helper *pke_deserialize_init(pk_membucket *bkt); void pke_serialize_teardown(srlztn_serialize_helper *helper); diff --git a/src/static-ui.cpp b/src/static-ui.cpp index 9df7ffa..823c015 100644 --- a/src/static-ui.cpp +++ b/src/static-ui.cpp @@ -2,6 +2,7 @@ #include "static-ui.hpp" #include "dynamic-array.hpp" +#include "ecs.hpp" #include "game-settings.hpp" #include "pk.h" #include "static-plane.hpp" @@ -458,7 +459,7 @@ void pke_ui_internal_new_typed_box(pke_ui_box *box, const PKE_UI_BOX_TYPE type) } } -pke_ui_box *pke_ui_box_new_root(const PKE_UI_BOX_TYPE type) { +pke_ui_box *pke_ui_box_new_root(const PKE_UI_BOX_TYPE type, pk_uuid uuid) { if (pke_ui_master.h_root_boxes == pke_ui_master.r_root_boxes) { pke_ui_box_count_T prev_r_root_boxes = pke_ui_master.r_root_boxes; pke_ui_master.r_root_boxes *= 1.5; @@ -470,16 +471,18 @@ pke_ui_box *pke_ui_box_new_root(const PKE_UI_BOX_TYPE type) { pke_ui_master.root_boxes = boxes; } pke_ui_box *box = pk_new<pke_ui_box>(pke_ui_master.bkt); - memset(box, 0, sizeof(pke_ui_box)); + *box = {}; pke_ui_master.root_boxes[pke_ui_master.h_root_boxes] = box; pke_ui_master.h_root_boxes += 1; pke_ui_master.should_recalc_ui = true; box->type = type; pke_ui_internal_new_typed_box(box, type); + box->uuid = uuid; + ECS_CreateEntity(box, nullptr); return box; } -pke_ui_box *pke_ui_box_new_child(pke_ui_box *parent, const PKE_UI_BOX_TYPE type) { +pke_ui_box *pke_ui_box_new_child(pke_ui_box *parent, const PKE_UI_BOX_TYPE type, pk_uuid uuid) { assert(parent != nullptr); // validation @@ -502,13 +505,15 @@ pke_ui_box *pke_ui_box_new_child(pke_ui_box *parent, const PKE_UI_BOX_TYPE type) parent->internal.children = boxes; } pke_ui_box *box = pk_new<pke_ui_box>(pke_ui_master.bkt); - memset(box, 0, sizeof(pke_ui_box)); + *box = {}; parent->internal.children[parent->internal.h_children] = box; parent->internal.h_children += 1; box->type = type; box->internal.parent = parent; pke_ui_master.should_recalc_ui = true; pke_ui_internal_new_typed_box(box, type); + box->uuid = uuid; + ECS_CreateEntity(box, parent); return box; } diff --git a/src/static-ui.hpp b/src/static-ui.hpp index 95506d7..149d588 100644 --- a/src/static-ui.hpp +++ b/src/static-ui.hpp @@ -65,7 +65,7 @@ typedef uint16_t pke_ui_box_count_T; struct pke_ui_box; -struct pke_ui_box { +struct pke_ui_box : public Entity_Base { PKE_UI_BOX_FLAG flags; float pos_top_left_x, pos_top_left_y; float min_width, min_height; @@ -91,6 +91,7 @@ struct pke_ui_box { }; struct pke_ui_box_type_data_text { + pk_uuid font_render_uuid = pk_uuid_zed; FontRenderHandle font_render_handle; FontRenderSettings font_render_settings; }; @@ -112,8 +113,8 @@ void pke_ui_init_bindings(); void pke_ui_tick(double delta); void pke_ui_teardown(); -pke_ui_box *pke_ui_box_new_root(const PKE_UI_BOX_TYPE type = PKE_UI_BOX_TYPE_STANDARD); -pke_ui_box *pke_ui_box_new_child(pke_ui_box *parent, const PKE_UI_BOX_TYPE type = PKE_UI_BOX_TYPE_STANDARD); +pke_ui_box *pke_ui_box_new_root(const PKE_UI_BOX_TYPE type = PKE_UI_BOX_TYPE_STANDARD, pk_uuid uuid = pk_uuid_zed); +pke_ui_box *pke_ui_box_new_child(pke_ui_box *parent, const PKE_UI_BOX_TYPE type = PKE_UI_BOX_TYPE_STANDARD, pk_uuid uuid = pk_uuid_zed); #ifdef PKE_TEST_EXPOSE void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_flex_params *flex_params, pke_ui_box *box); |
