diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-12-03 14:47:53 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-12-03 14:47:53 -0500 |
| commit | 119e1e91af301a00c1e58aa787bb8b3c0132a1f0 (patch) | |
| tree | 1df248616c495ce6913d9e30b151e017664bcff3 | |
| parent | 06fe41bf9a2f7442893a8f03281c2ad0abb7882f (diff) | |
pke: font stop rendering immediately on remove
| -rw-r--r-- | src/font.cpp | 21 | ||||
| -rw-r--r-- | src/static-ui.cpp | 20 |
2 files changed, 28 insertions, 13 deletions
diff --git a/src/font.cpp b/src/font.cpp index 004e9f8..de7814a 100644 --- a/src/font.cpp +++ b/src/font.cpp @@ -508,6 +508,11 @@ void FontType_Tick(double delta) { ft->gr.should_update_instance_buffer = true; return; } + // skip text if not valid. + // reminder: happens intentionally in FontType_RemoveStringRender. + if (fr->text.val == nullptr) { + return; + } index += fr->n_glyphs; }; pk_bkt_arr_iterate(&ft->renders, iter_fn.invoke, &iter_fn); @@ -538,6 +543,11 @@ void FontType_Tick(double delta) { if (fr->isMarkedForRemoval == true) { return; } + // skip text if not valid. + // reminder: happens intentionally in FontType_RemoveStringRender. + if (fr->text.val == nullptr) { + return; + } FontType_Inner_CalcTransforms(ft, fr, &fibis[index], &index); }; pk_bkt_arr_iterate(&ft->renders, iter_fn.invoke, &iter_fn); @@ -1156,9 +1166,16 @@ void FontType_RemoveStringRender(FontTypeRender ftr) { assert(pk_bkt_arr_handle_validate(&ftd.fonts, ftr.font_type_handle) == PK_BKT_ARR_HANDLE_VALIDATION_VALID); FontType *ft = &ftd.fonts[ftr.font_type_handle]; assert(pk_bkt_arr_handle_validate(&ft->renders, ftr.font_render_handle) == PK_BKT_ARR_HANDLE_VALIDATION_VALID); - // hack, but works - ft->gr.should_update_instance_buffer = true; fr = &ft->renders[ftr.font_render_handle]; + + // 2025-12-03 JCB + // This prevents text from being seen THIS tick. + ft->gr.should_update_instance_buffer = true; + if (fr->text.reserved > 0 && fr->text.val != NULL) pk_delete_arr<char>(fr->text.val, fr->text.reserved); + fr->text.val = nullptr; + fr->text.length = 0; + fr->text.reserved = 0; + ECS_MarkForRemoval(fr); } diff --git a/src/static-ui.cpp b/src/static-ui.cpp index 6858905..882a3dc 100644 --- a/src/static-ui.cpp +++ b/src/static-ui.cpp @@ -760,7 +760,7 @@ void pke_ui_tick(double delta) { } void pke_ui_teardown_box_recursive(pke_ui_box *box, uint8_t depth) { - FontRender *fr; + FontRender *fr = nullptr; 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], depth + 1); @@ -771,20 +771,10 @@ void pke_ui_teardown_box_recursive(pke_ui_box *box, uint8_t depth) { if (box->type_data != 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_type_render); - if (fr != nullptr && fr->parentHandle != box->handle) { - FontType_RemoveStringRender(box->type_data->text.font_type_render); - } break; case PKE_UI_BOX_TYPE_BUTTON_TEXT: fr = FontType_GetFontRender(box->type_data->button_text.font_type_render); - if (fr != nullptr && fr->parentHandle != box->handle) { - FontType_RemoveStringRender(box->type_data->button_text.font_type_render); - } break; case PKE_UI_BOX_TYPE_BUTTON_IMAGE: if (box->type_data->button_image.gr_binds_bkt_arr_handle != pk_bkt_arr_handle_MAX) { @@ -824,11 +814,19 @@ void pke_ui_teardown_box_recursive(pke_ui_box *box, uint8_t depth) { box->type_data = nullptr; } pk_arr_append_t<pke_ui_box*>(&pke_ui_master.boxes_to_delete, box); + // 2025-09-16 JCB + // If correctly parented, this is unnecessary, but de/serialization does + // not construct text boxes in this way. + // Handle explicitly to avoid memory leaks. + if (fr != nullptr && fr->parentHandle != box->handle) { + FontType_RemoveStringRender(FontTypeRender{fr->font_type_handle, fr->font_render_handle}); + } /* 2025-09-25 JCB HACK * I'd like this to be more elegant, this seems hacky. * We need to skip the first (the one we marked for removal). * If we are manually managing child boxes (like deleting in the editor), * then this can get called when depth > 0 but the box is already marked. + * The box at depth==0 is already marked, so only mark children. */ if (depth != 0 && box->isMarkedForRemoval == false) { ECS_MarkForRemoval(box); |
