diff options
Diffstat (limited to 'src/static-ui.cpp')
| -rw-r--r-- | src/static-ui.cpp | 106 |
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); } |
