From ac269aa0f319b8942b7dec7fe2b2dda81e62f5ef Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Sun, 19 Apr 2026 20:08:47 +0200 Subject: [PATCH] change Drop implementation for UiList to actually free the list --- ui-rs/src/ui/toolkit.rs | 15 ++++++++++++--- ui/common/context.c | 22 +++++++++++----------- ui/common/context.h | 2 +- ui/common/object.c | 12 +----------- ui/ui/toolkit.h | 2 -- 5 files changed, 25 insertions(+), 28 deletions(-) diff --git a/ui-rs/src/ui/toolkit.rs b/ui-rs/src/ui/toolkit.rs index fecf197..024bbbb 100644 --- a/ui-rs/src/ui/toolkit.rs +++ b/ui-rs/src/ui/toolkit.rs @@ -182,6 +182,7 @@ pub struct UiDouble { pub struct UiList { pub ptr: *mut ffi::UiList, + ctx: *mut ffi::UiContext, data: Box> } @@ -206,6 +207,7 @@ impl Default for UiList { fn default() -> Self { Self { ptr: std::ptr::null_mut(), + ctx: std::ptr::null_mut(), data: Box::new(Vec::new()) } } @@ -310,6 +312,7 @@ impl UiList { unsafe { let data: *mut Vec = &mut *self.data; self.ptr = ui_list_new2(ctx.ptr, c_str, list_init::, data as *mut c_void); + self.ctx = ctx.ptr; } } @@ -352,10 +355,8 @@ impl UiList { impl Drop for UiList { fn drop(&mut self) { unsafe { - // This does not free the UiList pointer, because it could still be in use by - // UI elements, but it will have no reference to any object managed by Rust if !self.ptr.is_null() { - ui_list_class_set_data(self.ptr, std::ptr::null_mut()); + ui_list_free(self.ctx, self.ptr); } } } @@ -374,6 +375,7 @@ extern "C" fn list_init(_ctx: *mut ffi::UiContext, list: *mut ffi::UiList, da ui_list_class_set_next(list, list_next::); ui_list_class_set_get(list, list_get::); ui_list_class_set_count(list, list_count::); + ui_list_class_set_destructor(list, list_destroy::); } } @@ -441,6 +443,10 @@ extern "C" fn list_count(list: *mut ffi::UiList) -> c_int { } } +extern "C" fn list_destroy(_ctx: *mut ffi::UiContext, _list: *mut ffi::UiList, _data: *mut c_void) { + // noop +} + /* -------------------------------- C functions -------------------------------- */ extern "C" { @@ -484,6 +490,7 @@ extern "C" { fn ui_list_class_set_next(list: *mut ffi::UiList, func: UiListNextFunc); fn ui_list_class_set_get(list: *mut ffi::UiList, func: UiListGetFunc); fn ui_list_class_set_count(list: *mut ffi::UiList, func: UiListCountFunc); + fn ui_list_class_set_destructor(list: *mut ffi::UiList, destructor: UiListDestroyFunc); fn ui_list_class_set_data(list: *mut ffi::UiList, data: *mut c_void); fn ui_list_class_set_iter(list: *mut ffi::UiList, iter: *mut c_void); @@ -498,4 +505,6 @@ extern "C" { fn ui_list_selection_get_count(list: *mut ffi::UiListSelection) -> c_int; fn ui_list_selection_get_rows(list: *mut ffi::UiListSelection) -> *const c_int; fn ui_list_selection_free(list: *mut ffi::UiListSelection); + + fn ui_list_free(ctx: *mut ffi::UiContext, list: *mut ffi::UiList); } diff --git a/ui/common/context.c b/ui/common/context.c index 581469e..12130d0 100644 --- a/ui/common/context.c +++ b/ui/common/context.c @@ -108,16 +108,23 @@ void uic_context_destroy(UiContext *ctx, void *document) { } UiEvent ev; - ev.window = NULL; + ev.obj = ctx->obj; + ev.window = ev.obj ? ev.obj->window : NULL; ev.document = document; - ev.obj = NULL; ev.eventdata = NULL; ev.eventdatatype = 0; ev.intval = 0; + ev.set = 0; if(ctx->close_callback) { ctx->close_callback(&ev, ctx->close_data); } + + CxIterator i = cxListIterator(ctx->destroy_handler); + cx_foreach(UiDestroyHandler *, h, i) { + h->destructor(h->data); + } + cxMempoolFree(ctx->mp); } @@ -552,14 +559,6 @@ void ui_context_closefunc(UiContext *ctx, ui_callback fnc, void *udata) { ctx->close_data = udata; } -void ui_context_destroy(UiContext *ctx) { - CxIterator i = cxListIterator(ctx->destroy_handler); - cx_foreach(UiDestroyHandler *, h, i) { - h->destructor(h->data); - } - cxMempoolFree(ctx->mp); -} - UiContext* ui_context_parent(UiContext *ctx) { return ctx->parent; } @@ -730,7 +729,8 @@ char* ui_strdup(UiContext *ctx, const char *str) { } void ui_reg_destructor(UiContext *ctx, void *data, ui_destructor_func destr) { - cxMempoolRegister(ctx->mp, data, (cx_destructor_func)destr); + //cxMempoolRegister(ctx->mp, data, (cx_destructor_func)destr); + uic_context_add_destructor(ctx, destr, data); } void ui_set_destructor(void *mem, ui_destructor_func destr) { diff --git a/ui/common/context.h b/ui/common/context.h index c2bba8b..c846ba5 100644 --- a/ui/common/context.h +++ b/ui/common/context.h @@ -62,7 +62,7 @@ typedef enum UiVarType { struct UiContext { UiContext *parent; UiObject *obj; - CxMempool *mp; + CxMempool *mp; const CxAllocator *allocator; CxList *destroy_handler; diff --git a/ui/common/object.c b/ui/common/object.c index 9b197d7..150cd43 100644 --- a/ui/common/object.c +++ b/ui/common/object.c @@ -98,18 +98,8 @@ int ui_object_unref(UiObject *obj) { } void uic_object_destroy(UiObject *obj) { - if(obj->ctx->close_callback) { - UiEvent ev; - ev.window = obj->window; - ev.document = obj->ctx->document; - ev.obj = obj; - ev.eventdata = NULL; - ev.eventdatatype = 0; - ev.intval = 0; - obj->ctx->close_callback(&ev, obj->ctx->close_data); - } uic_object_destroyed(obj); - cxMempoolFree(obj->ctx->mp); + uic_context_destroy(obj->ctx, obj->ctx->document); } UiObject* uic_object_new_toplevel(void) { diff --git a/ui/ui/toolkit.h b/ui/ui/toolkit.h index af1036e..77234b9 100644 --- a/ui/ui/toolkit.h +++ b/ui/ui/toolkit.h @@ -539,8 +539,6 @@ UIEXPORT UiContext* ui_global_context(void); UIEXPORT void ui_context_closefunc(UiContext *ctx, ui_callback fnc, void *udata); -UIEXPORT void ui_context_destroy(UiContext *ctx); - UIEXPORT UiContext* ui_context_parent(UiContext *ctx); UIEXPORT void ui_object_ref(UiObject *obj); -- 2.47.3