#include "serialization-static-ui.hpp" #include "ecs.hpp" #include "pk.h" #include "serialization-font.hpp" #include "static-ui.hpp" pk_handle pke_serialize_ui_box_internal(srlztn_serialize_helper *h, pke_ui_box_type_data_text *data) { char *s; pk_handle font_render_handle; pke_kve kve{}; pke_kve_container kvec{}; font_render_handle = pke_serialize_font_render_settings(h, &data->font_render_settings); kvec.srlztn_handle = h->handle_head; kvec.type_code = cstring_to_pk_cstr(SRLZTN_OBJ_UI_BOX); kvec.bkt = h->bkt; kvec.arr.bkt = h->bkt; kvec.children.bkt = h->bkt; kvec.child_handles.bkt = h->bkt; h->handle_head.itemIndex++; if (font_render_handle != PK_HANDLE_MAX) { pk_arr_append_t(&kvec.child_handles, font_render_handle); } if (data->font_render_uuid != pk_uuid_zed) { kve.key = SRLZTN_UI_BOX_DATA_TEXT_FONT_RENDER_UUID; s = pk_new(37, h->bkt); sprintf(s, pk_uuid_printf_format, pk_uuid_printf_var(data->font_render_uuid)); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } pk_arr_append_t(&h->kvp_containers, kvec); return kvec.srlztn_handle; } void pke_deserialize_ui_box_internal(srlztn_deserialize_helper *h, pke_kve_container *kvec, pke_ui_box_type_data_text *data) { assert(kvec->children.next == 1); pke_deserialize_font_render_settings(h, kvec, &data->font_render_settings); if (strstr(SRLZTN_UI_BOX_DATA_TEXT_FONT_RENDER_UUID, kvec->arr[0].key)) { kvec->arr[0].val >> data->font_render_uuid; } } pk_handle pke_serialize_ui_box(srlztn_serialize_helper *h, pke_ui_box *box) { char *s; int len; pk_handle internal_type_handle = PK_HANDLE_MAX; pke_kve kve{}; pke_kve_container kvec{}; if (box->type == PKE_UI_BOX_TYPE_TEXT) { pke_ui_box_type_data_text *d = reinterpret_cast(box->type_data); internal_type_handle = pke_serialize_ui_box_internal(h, d); } kvec.srlztn_handle = h->handle_head; kvec.type_code = cstring_to_pk_cstr(SRLZTN_OBJ_UI_BOX); kvec.bkt = h->bkt; kvec.arr.bkt = h->bkt; kvec.children.bkt = h->bkt; kvec.child_handles.bkt = h->bkt; h->handle_head.itemIndex++; if (internal_type_handle != PK_HANDLE_MAX) { pk_arr_append_t(&kvec.child_handles, internal_type_handle); } if (box->uuid != pk_uuid_zed && box->uuid != pk_uuid_max) { kve.key = SRLZTN_UI_BOX_UUID; s = pk_new(37, h->bkt); sprintf(s, pk_uuid_printf_format, pk_uuid_printf_var(box->uuid)); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } if (box->parentHandle != EntityHandle_MAX) { Entity_Base *e = ECS_GetEntity(box->parentHandle); kve.key = SRLZTN_UI_BOX_PARENT_UUID; s = pk_new(37, h->bkt); sprintf(s, pk_uuid_printf_format, pk_uuid_printf_var(e->uuid)); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } if (box->flags != PKE_UI_BOX_FLAG_NONE) { kve.key = SRLZTN_UI_BOX_FLAGS; s = pk_new(19, h->bkt); sprintf(s, "0x%.2lX", static_cast(box->flags)); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } if (box->pos_top_left_x != 0.0) { kve.key = SRLZTN_UI_BOX_POS_TOP_LEFT_X; len = snprintf(NULL, 0, "%f", box->pos_top_left_x); s = pk_new(len+1, h->bkt); sprintf(s, "%f", box->pos_top_left_x); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } if (box->pos_top_left_y != 0.0) { kve.key = SRLZTN_UI_BOX_POS_TOP_LEFT_Y; len = snprintf(NULL, 0, "%f", box->pos_top_left_y); s = pk_new(len+1, h->bkt); sprintf(s, "%f", box->pos_top_left_y); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } if (box->min_width != 0.0) { kve.key = SRLZTN_UI_BOX_MIN_WIDTH; len = snprintf(NULL, 0, "%f", box->min_width); s = pk_new(len+1, h->bkt); sprintf(s, "%f", box->min_width); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } if (box->min_height != 0.0) { kve.key = SRLZTN_UI_BOX_MIN_HEIGHT; len = snprintf(NULL, 0, "%f", box->min_height); s = pk_new(len+1, h->bkt); sprintf(s, "%f", box->min_height); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } if (box->max_width != 0.0) { kve.key = SRLZTN_UI_BOX_MAX_WIDTH; len = snprintf(NULL, 0, "%f", box->max_width); s = pk_new(len+1, h->bkt); sprintf(s, "%f", box->max_width); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } if (box->max_height != 0.0) { kve.key = SRLZTN_UI_BOX_MAX_HEIGHT; len = snprintf(NULL, 0, "%f", box->max_height); s = pk_new(len+1, h->bkt); sprintf(s, "%f", box->max_height); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } if (box->flex_weight != 0.0) { kve.key = SRLZTN_UI_BOX_FLEX_WEIGHT; len = snprintf(NULL, 0, "%f", box->flex_weight); s = pk_new(len+1, h->bkt); sprintf(s, "%f", box->flex_weight); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } if (box->type != PKE_UI_BOX_TYPE_STANDARD) { kve.key = SRLZTN_UI_BOX_FLAGS; s = pk_new(5, h->bkt); sprintf(s, "0x%.2X", static_cast(box->type)); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } if (box->flex_direction != 0) { kve.key = SRLZTN_UI_BOX_FLEX_DIRECTION; s = pk_new(5, h->bkt); sprintf(s, "%u", box->flex_direction); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } if (box->layer != 0) { kve.key = SRLZTN_UI_BOX_LAYER; s = pk_new(5, h->bkt); sprintf(s, "%u", box->layer); kve.val = s; kve.end = SRLZTN_KVE_END; pk_arr_append_t(&kvec.arr, kve); } pk_arr_append_t(&h->kvp_containers, kvec); return kvec.srlztn_handle; } void pke_deserialize_ui_box(srlztn_deserialize_helper *h, pke_kve_container *kvec) { /* How this works, a concrete example * * wrapper box > type_text box > { type_text data + FRSettings } * * 1. wrapper box parse & create * 2. box_type text starts parse * a. parse type_data (one child only) (by reference) * 1. parse font-render settings (by reference) * */ uint32_t i; uint64_t prefix_len; PK_STN_RES res; char *stn_end; pke_ui_box bx{}; pke_ui_box *parent_box = nullptr; bx.type_data = nullptr; for (i = 0; i < kvec->arr.next; ++i) { if (strstr(SRLZTN_UI_BOX_UUID, kvec->arr[i].key)) { prefix_len = strlen(SRLZTN_UI_BOX_UUID); (kvec->arr[i].val + prefix_len) >> bx.uuid; continue; } if (strstr(SRLZTN_UI_BOX_PARENT_UUID, kvec->arr[i].key)) { uint32_t target_instance_index = -1; pk_uuid id; prefix_len = strlen(SRLZTN_UI_BOX_PARENT_UUID); (kvec->arr[i].val + 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(h->mapping[target_instance_index].created_entity); } continue; } if (strstr(SRLZTN_UI_BOX_FLAGS, kvec->arr[i].key)) { prefix_len = strlen(SRLZTN_UI_BOX_FLAGS); PKE_UI_BOX_FLAG_T flags; res = pk_stn(&flags, kvec->arr[i].val + 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, kvec->arr[i].key)) { prefix_len = strlen(SRLZTN_UI_BOX_POS_TOP_LEFT_X); res = pk_stn(&bx.pos_top_left_x, kvec->arr[i].val + 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, kvec->arr[i].key)) { prefix_len = strlen(SRLZTN_UI_BOX_POS_TOP_LEFT_Y); res = pk_stn(&bx.pos_top_left_y, kvec->arr[i].val + 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, kvec->arr[i].key)) { prefix_len = strlen(SRLZTN_UI_BOX_MIN_WIDTH); res = pk_stn(&bx.min_width, kvec->arr[i].val + 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, kvec->arr[i].key)) { prefix_len = strlen(SRLZTN_UI_BOX_MIN_HEIGHT); res = pk_stn(&bx.min_width, kvec->arr[i].val + 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, kvec->arr[i].key)) { prefix_len = strlen(SRLZTN_UI_BOX_MAX_WIDTH); res = pk_stn(&bx.max_width, kvec->arr[i].val + 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, kvec->arr[i].key)) { prefix_len = strlen(SRLZTN_UI_BOX_MAX_HEIGHT); res = pk_stn(&bx.max_width, kvec->arr[i].val + 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, kvec->arr[i].key)) { prefix_len = strlen(SRLZTN_UI_BOX_FLEX_WEIGHT); res = pk_stn(&bx.flex_weight, kvec->arr[i].val + 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, kvec->arr[i].key)) { prefix_len = strlen(SRLZTN_UI_BOX_FLEX_DIRECTION); res = pk_stn(&bx.flex_direction, kvec->arr[i].val + 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, kvec->arr[i].key)) { prefix_len = strlen(SRLZTN_UI_BOX_LAYER); res = pk_stn(&bx.layer, kvec->arr[i].val + 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, kvec->arr[i].key)) { prefix_len = strlen(SRLZTN_UI_BOX_TYPE); res = pk_stn(&bx.type, kvec->arr[i].val + 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: break; default: fprintf(stderr, "[pke_deserialize_ui_box] Parsed unknown ui box data type from: '%s'", kvec->arr[i].val); continue; } continue; } } // get ready to deserialize children if (bx.type != PKE_UI_BOX_TYPE_STANDARD) { switch (bx.type) { case PKE_UI_BOX_TYPE_TEXT: bx.type_data = pk_new(); break; default: break; } } // deserialize children for (i = 0; i < kvec->children.next; ++i) { pke_kve_container *child_kvec = kvec->children[i]; if (strcmp(child_kvec->type_code.val, SRLZTN_OBJ_UI_BOX_TYPE_DATA) == 0) { pke_deserialize_ui_box_internal(h, child_kvec, static_cast(bx.type_data)); } } 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; // TODO clone functions? // might not be necessary if we refactor deserialization into their own ctors if (bx.type != PKE_UI_BOX_TYPE_STANDARD) { switch (bx.type) { case PKE_UI_BOX_TYPE_TEXT: reinterpret_cast(box->type_data )->font_render_uuid = reinterpret_cast(bx.type_data)->font_render_uuid; reinterpret_cast(box->type_data )->font_render_handle = reinterpret_cast(bx.type_data)->font_render_handle; reinterpret_cast(box->type_data )->font_render_settings = reinterpret_cast(bx.type_data)->font_render_settings; break; default: break; } } return; }