From cbc0b2930cd0652fbedf145e01be410317cf9331 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Mon, 11 May 2026 21:38:40 +0200 Subject: [PATCH] add reference counting to UiObject --- ui-rs/src/ui/toolkit.rs | 23 +++++++++++++++++++++++ ui-rs/src/ui/window.rs | 9 +++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/ui-rs/src/ui/toolkit.rs b/ui-rs/src/ui/toolkit.rs index 38ff894..48e26f3 100644 --- a/ui-rs/src/ui/toolkit.rs +++ b/ui-rs/src/ui/toolkit.rs @@ -191,6 +191,26 @@ pub struct UiObject { pub _data: PhantomData } +impl Clone for UiObject { + fn clone(&self) -> Self { + unsafe { + ui_object_ref(self.ptr); + } + UiObject { + ptr: self.ptr, + ctx: UiContext { ptr: self.ctx.ptr }, + _data: PhantomData + } + } +} + +impl Drop for UiObject { + fn drop(&mut self) { + unsafe { + ui_object_unref(self.ptr); + } + } +} pub struct UiText { pub ptr: *mut ffi::UiText @@ -765,6 +785,9 @@ type UiListGetFunc = extern "C" fn(*const ffi::UiList, c_int) -> *mut c_void; type UiListCountFunc = extern "C" fn(*const ffi::UiList) -> c_int; extern "C" { + pub fn ui_object_ref(obj: *mut ffi::UiObject); + pub fn ui_object_unref(obj: *mut ffi::UiObject); + fn ui_list_new(ctx: *mut ffi::UiContext, name: *const c_char) -> *mut ffi::UiList; fn ui_list_new2(ctx: *mut ffi::UiContext, name: *const c_char, init: UiListInitFunc, userdata: *mut c_void) -> *mut ffi::UiList; fn ui_list_class_set_first(list: *mut ffi::UiList, func: UiListFirstFunc); diff --git a/ui-rs/src/ui/window.rs b/ui-rs/src/ui/window.rs index 47b42a2..408e9c1 100644 --- a/ui-rs/src/ui/window.rs +++ b/ui-rs/src/ui/window.rs @@ -32,7 +32,7 @@ use std::ffi::{c_char, c_int, c_void}; use std::ffi::CString; use std::marker::PhantomData; -use crate::ui::{event, ffi, toolkit, AppContext, EventWrapper, NoAppData, UiActions, UiModel}; +use crate::ui::{event, ffi, toolkit, ui_object_ref, AppContext, EventWrapper, NoAppData, UiActions, UiModel}; use crate::ui::ffi::{UiButtonArgs, UiCallback, UiContext, UiDestructor, UiDialogArgs, UiObject}; use crate::ui::widget::widget_fn; @@ -65,6 +65,11 @@ where F: FnOnce(&mut toolkit::UiObject, &mut T) { WindowType::Simple => ui_simple_window(str.as_ptr()) } }; + // because we use additional reference counting in the Rust UiObject wrapper, + // we always increase the reference counter here + unsafe { + ui_object_ref(objptr); + } let ctxptr = unsafe { ui_object_get_context(objptr) @@ -92,7 +97,7 @@ where F: FnOnce(&mut toolkit::UiObject, &mut T) { // call ui building closure create_ui(&mut obj, wdata); - + obj } -- 2.47.3