summaryrefslogtreecommitdiff
path: root/src/static-ui.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/static-ui.cpp')
-rw-r--r--src/static-ui.cpp106
1 files changed, 71 insertions, 35 deletions
diff --git a/src/static-ui.cpp b/src/static-ui.cpp
index b4bdc5c..c8200b0 100644
--- a/src/static-ui.cpp
+++ b/src/static-ui.cpp
@@ -52,9 +52,10 @@ struct pke_ui_master {
const pke_input_event *mouse_middle = nullptr;
pke_ui_box *deepest_pressed = nullptr;
} state;
+ pk_arr_t<pke_ui_box*> boxes_to_delete{};
} pke_ui_master;
-void pke_ui_teardown_box_recursive(pke_ui_box *box);
+void pke_ui_teardown_box_recursive(pke_ui_box *box, uint8_t depth);
// typedef void(*pke_box_search)(pke_ui_box &box);
typedef std::function<void(pke_ui_box &box)> pke_box_iterate ;
@@ -554,6 +555,12 @@ void pke_ui_tick(double delta) {
(void)delta;
pke_ui_box_count_T i, ii;
uint32_t u;
+
+ for (u = 0; u < pke_ui_master.boxes_to_delete.next; ++u) {
+ pk_delete<pke_ui_box>(pke_ui_master.boxes_to_delete[u], pke_ui_master.bkt);
+ }
+ pk_arr_clear(&pke_ui_master.boxes_to_delete);
+
if (pke_ui_master.h_root_boxes == 0) return;
pke_ui_master.state.mouse_left = pke_input_query_by_action_name(ui_ux_mouse_left);
@@ -576,19 +583,17 @@ void pke_ui_tick(double delta) {
// Leaving this as-is for the time being because you can control the
// visibility of child boxes with flags and don't need to completely remove them.
if (box->isMarkedForRemoval == true) {
- pke_ui_teardown_box_recursive(box);
+ pke_ui_teardown_box_recursive(box, 0);
for (ii = 0; i + ii + 1 < pke_ui_master.r_root_boxes; ++ii) {
pke_ui_master.root_boxes[i + ii] = pke_ui_master.root_boxes[i + ii + 1];
}
pke_ui_master.h_root_boxes -= 1;
i -= 1;
pke_ui_master.should_update_buffer = true;
- goto skip_calc;
+ continue;
}
pke_ui_calc_px(arr, tmp_txtr_arr, nullptr, box);
pke_ui_recalc_sizes_recursive(arr, tmp_txtr_arr, box);
-skip_calc:
- continue;
}
for (i = 0; i < tmp_txtr_arr.next; ++i) {
@@ -629,50 +634,80 @@ skip_calc:
}
}
-void pke_ui_teardown_box_recursive(pke_ui_box *box) {
+void pke_ui_teardown_box_recursive(pke_ui_box *box, uint8_t depth) {
+ FontRender *fr;
+ pke_ui_graphics_bindings_texture *bindings = nullptr;
for (pke_ui_box_count_T i = 0; i < box->internal.h_children; ++i) {
- pke_ui_teardown_box_recursive(box->internal.children[i]);
+ pke_ui_teardown_box_recursive(box->internal.children[i], depth + 1);
}
if (box->internal.children != nullptr) {
pk_delete_arr<pke_ui_box *>(box->internal.children, box->internal.r_children, pke_ui_master.bkt);
}
if (box->type_data != nullptr) {
- if (box->type == PKE_UI_BOX_TYPE_BUTTON_IMAGE && box->type_data->button_image.gr_binds_bkt_arr_handle != pk_bkt_arr_handle_MAX) {
-
- pke_ui_graphics_bindings_texture *bindings = &pke_ui_master.bindings_texture[box->type_data->button_image.gr_binds_bkt_arr_handle];
-
- // reminder that we are not passing the flag on the pool to manually manage descriptor sets, so all we need to do is destroy the pool
- if (bindings->descriptor_pool != VK_NULL_HANDLE) {
- pkvk_queue_vk_descriptor_pool_destroy(bindings->descriptor_pool);
- }
- if (bindings->descriptor_sets != nullptr) {
- pk_delete_arr(bindings->descriptor_sets, prevSwapchainLength, MemBkt_Vulkan);
- }
-
- if (bindings->image_view!= VK_NULL_HANDLE) {
- pkvk_queue_vk_image_view_destroy(bindings->image_view);
- }
- if (bindings->image!= VK_NULL_HANDLE) {
- pkvk_queue_vk_image_destroy(bindings->image);
- }
- if (bindings->image_memory != VK_NULL_HANDLE) {
- pkvk_queue_vk_memory_free(bindings->image_memory);
- }
-
- bindings->descriptor_sets = nullptr;
- bindings->descriptor_pool = VK_NULL_HANDLE;
- pk_bkt_arr_free_handle(&pke_ui_master.bindings_texture, box->type_data->button_image.gr_binds_bkt_arr_handle);
- bindings = nullptr;
+ switch (box->type) {
+ case PKE_UI_BOX_TYPE_TEXT:
+ // 2025-09-16 JCB
+ // If correctly parented, this is unnecessary, but serialization does
+ // not construct text boxes in this way.
+ // Handle to avoid memory leaks.
+ fr = FontType_GetFontRender(box->type_data->text.font_render_handle);
+ if (fr != nullptr && fr->parentHandle != box->handle) {
+ FontType_RemoveStringRender(box->type_data->text.font_render_handle);
+ }
+ break;
+ case PKE_UI_BOX_TYPE_BUTTON_TEXT:
+ fr = FontType_GetFontRender(box->type_data->button_text.font_render_handle);
+ if (fr != nullptr && fr->parentHandle != box->handle) {
+ FontType_RemoveStringRender(box->type_data->button_text.font_render_handle);
+ }
+ break;
+ case PKE_UI_BOX_TYPE_BUTTON_IMAGE:
+ if (box->type_data->button_image.gr_binds_bkt_arr_handle != pk_bkt_arr_handle_MAX) {
+ bindings = &pke_ui_master.bindings_texture[box->type_data->button_image.gr_binds_bkt_arr_handle];
+ // reminder that we are not passing the flag on the pool to manually manage descriptor sets, so all we need to do is destroy the pool
+ if (bindings->descriptor_pool != VK_NULL_HANDLE) {
+ pkvk_queue_vk_descriptor_pool_destroy(bindings->descriptor_pool);
+ }
+ if (bindings->descriptor_sets != nullptr) {
+ pk_delete_arr(bindings->descriptor_sets, prevSwapchainLength, MemBkt_Vulkan);
+ }
+ if (bindings->image_view!= VK_NULL_HANDLE) {
+ pkvk_queue_vk_image_view_destroy(bindings->image_view);
+ }
+ if (bindings->image!= VK_NULL_HANDLE) {
+ pkvk_queue_vk_image_destroy(bindings->image);
+ }
+ if (bindings->image_memory != VK_NULL_HANDLE) {
+ pkvk_queue_vk_memory_free(bindings->image_memory);
+ }
+ bindings->descriptor_sets = nullptr;
+ bindings->descriptor_pool = VK_NULL_HANDLE;
+ pk_bkt_arr_free_handle(&pke_ui_master.bindings_texture, box->type_data->button_image.gr_binds_bkt_arr_handle);
+ bindings = nullptr;
+ }
+ break;
+ case PKE_UI_BOX_TYPE_INPUT_TEXT:
+ // TODO
+ break;
+ case PKE_UI_BOX_TYPE_INPUT_MULTILINE_TEXT:
+ // TODO
+ break;
+ default:
+ fprintf(stderr, "[%s][pke_ui_teardown_box_recursive] unknown box type: %hhu", __FILE__, static_cast<PKE_UI_BOX_TYPE_T>(box->type));
}
pk_delete<pke_ui_box_type_data>(box->type_data, pke_ui_master.bkt);
+ box->type_data = nullptr;
+ }
+ pk_arr_append_t<pke_ui_box*>(&pke_ui_master.boxes_to_delete, box);
+ if (depth != 0) {
+ ECS_MarkForRemoval(box);
}
- pk_delete<pke_ui_box>(box, pke_ui_master.bkt);
pke_ui_master.should_update_buffer = true;
}
void pke_ui_teardown() {
for (pke_ui_box_count_T i = 0; i < pke_ui_master.h_root_boxes; ++i) {
- pke_ui_teardown_box_recursive(pke_ui_master.root_boxes[i]);
+ pke_ui_teardown_box_recursive(pke_ui_master.root_boxes[i], 0);
}
pk_delete_arr<pke_ui_box *>(pke_ui_master.root_boxes, pke_ui_master.r_root_boxes, pke_ui_master.bkt);
pke_ui_master.bindings_texture.~texture_binding_bkt_arr();
@@ -720,6 +755,7 @@ void pke_ui_teardown() {
vkFreeMemory(vkDevice, pke_ui_master.bindings.deviceMemoryVert, vkAllocator);
pke_ui_master.bindings.deviceMemoryVert = VK_NULL_HANDLE;
+ pk_arr_reset(&pke_ui_master.boxes_to_delete);
pke_input_unregister_set(pke_ui_master.input_action_set_handle);
}