]> uap-core.de Git - note.git/commitdiff
change Drop implementation for UiList to actually free the list
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 19 Apr 2026 18:08:47 +0000 (20:08 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 19 Apr 2026 18:08:47 +0000 (20:08 +0200)
ui-rs/src/ui/toolkit.rs
ui/common/context.c
ui/common/context.h
ui/common/object.c
ui/ui/toolkit.h

index fecf197680c245b5b19449347b88b7907c4b5016..024bbbb5227ae731f5c8fb4769257791cdf96245 100644 (file)
@@ -182,6 +182,7 @@ pub struct UiDouble {
 
 pub struct UiList<T> {
     pub ptr: *mut ffi::UiList,
+    ctx: *mut ffi::UiContext,
     data: Box<Vec<T>>
 }
 
@@ -206,6 +207,7 @@ impl<T> Default for UiList<T> {
     fn default() -> Self {
         Self {
             ptr: std::ptr::null_mut(),
+            ctx: std::ptr::null_mut(),
             data: Box::new(Vec::new())
         }
     }
@@ -310,6 +312,7 @@ impl<T> UiList<T> {
         unsafe {
             let data: *mut Vec<T> = &mut *self.data;
             self.ptr = ui_list_new2(ctx.ptr, c_str, list_init::<T>, data as *mut c_void);
+            self.ctx = ctx.ptr;
         }
     }
 
@@ -352,10 +355,8 @@ impl<T> UiList<T> {
 impl<T> Drop for UiList<T> {
     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<T>(_ctx: *mut ffi::UiContext, list: *mut ffi::UiList, da
         ui_list_class_set_next(list, list_next::<T>);
         ui_list_class_set_get(list, list_get::<T>);
         ui_list_class_set_count(list, list_count::<T>);
+        ui_list_class_set_destructor(list, list_destroy::<T>);
     }
 }
 
@@ -441,6 +443,10 @@ extern "C" fn list_count<T>(list: *mut ffi::UiList) -> c_int {
     }
 }
 
+extern "C" fn list_destroy<T>(_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);
 }
index 581469e60f90bcd2ae6437e8b737a55419c2f84e..12130d0fa6c6c7555cab2764f7bd81807841b855 100644 (file)
@@ -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) {
index c2bba8b9b2e7f6de6041d943d8b0852dc780f091..c846ba5cfdc7432d22d261719dda399bb4837bc8 100644 (file)
@@ -62,7 +62,7 @@ typedef enum UiVarType {
 struct UiContext {
     UiContext     *parent;
     UiObject      *obj;
-    CxMempool *mp;
+    CxMempool     *mp;
     const CxAllocator *allocator;
     CxList *destroy_handler;
     
index 9b197d7edb235905c4579f07721859bed49c8dfc..150cd43cd1008792cf4cd39246b0e7bcbad63cce 100644 (file)
@@ -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) {
index af1036ef2590ad0e16cb5eb741a5601d14d005db..77234b92881864f9cf8b63ba53a69fc043b14fce 100644 (file)
@@ -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);