From: Olaf Wintermann Date: Sat, 1 Aug 2026 10:31:03 +0000 (+0200) Subject: change onshot event callbacks to FnOnce X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=9780526f92679fa2c7b81830b8eb60da8adbb78f;p=note.git change onshot event callbacks to FnOnce --- diff --git a/ui-rs/src/ui/button.rs b/ui-rs/src/ui/button.rs index 62c1daf..7a90549 100644 --- a/ui-rs/src/ui/button.rs +++ b/ui-rs/src/ui/button.rs @@ -383,7 +383,7 @@ impl<'a, T> ButtonBuilder<'a, T> { pub fn onclick(&mut self, f: F) -> &mut Self where F: FnMut(&mut event::Event) + 'static { - let wrapper = Box::new(EventWrapper { callback: Box::new(f) }); + let wrapper = Box::new(EventWrapper::new(f) ); let ptr = self.obj.ctx.reg_box(wrapper); unsafe { ui_button_args_set_onclick(self.args, Some(event::event_wrapper::)); @@ -575,7 +575,7 @@ impl<'a, T> ToggleBuilder<'a, T> { pub fn onchange(&mut self, f: F) -> &mut Self where F: FnMut(&mut event::Event) + 'static { - let wrapper = Box::new(EventWrapper { callback: Box::new(f) }); + let wrapper = Box::new(EventWrapper::new(f) ); let ptr = self.obj.ctx.reg_box(wrapper); unsafe { ui_toggle_args_set_onchange(self.args, Some(event::event_wrapper::)); @@ -760,7 +760,7 @@ impl<'a, T> LinkButtonBuilder<'a, T> { pub fn onclick(&mut self, f: F) -> &mut Self where F: FnMut(&mut event::Event) + 'static { - let wrapper = Box::new(EventWrapper { callback: Box::new(f) }); + let wrapper = Box::new(EventWrapper::new(f) ); let ptr = self.obj.ctx.reg_box(wrapper); unsafe { ui_linkbutton_args_set_onclick(self.args, Some(event::event_wrapper::)); diff --git a/ui-rs/src/ui/event.rs b/ui-rs/src/ui/event.rs index 506f496..139e7f5 100644 --- a/ui-rs/src/ui/event.rs +++ b/ui-rs/src/ui/event.rs @@ -226,14 +226,24 @@ fn get_event_type<'a>(data: &'a mut EventTypeData) -> EventType<'a> { } } +pub enum EventWrapperCallback { + Once(Option)>>), + Mut(Box)>) +} + pub struct EventWrapper { - pub callback: Box)> + pub callback: EventWrapperCallback } impl EventWrapper { pub fn new(f: F) -> EventWrapper where F: FnMut(&mut event::Event) + 'static { - EventWrapper { callback: Box::new(f) } + EventWrapper { callback: EventWrapperCallback::Mut(Box::new(f)) } + } + + pub fn new_once(f: F) -> EventWrapper + where F: FnOnce(&mut event::Event) + 'static { + EventWrapper { callback: EventWrapperCallback::Once(Some(Box::new(f))) } } } @@ -261,8 +271,18 @@ pub extern "C" fn event_wrapper(e: *const ffi::UiEvent, data: *mut c_void) { intval: ev_int, set: ev_set }; - - (wrapper.callback)(&mut event); + + + match wrapper.callback { + EventWrapperCallback::Once(ref mut cb) => { + if let Some(cb) = cb.take() { + cb(&mut event); + } + }, + EventWrapperCallback::Mut(ref mut cb) => { + cb(&mut event); + } + } } } diff --git a/ui-rs/src/ui/window.rs b/ui-rs/src/ui/window.rs index aba6bc7..5ad52d9 100644 --- a/ui-rs/src/ui/window.rs +++ b/ui-rs/src/ui/window.rs @@ -75,7 +75,7 @@ impl toolkit::UiObject { pub fn onclose(&self, f: F) where F: FnMut(&mut event::Event) + 'static { - let wrapper = Box::new(EventWrapper { callback: Box::new(f) }); + let wrapper = Box::new(EventWrapper::new(f)); let ptr = self.ctx.reg_box(wrapper); unsafe { ui_object_set_onclose(self.ptr, Some(event::event_wrapper::), ptr.cast()); @@ -294,8 +294,8 @@ impl DialogBuilder { } pub fn result(&mut self, f: F) -> &mut Self - where F: FnMut(&mut event::Event) + 'static { - let wrapper = Box::new(EventWrapper { callback: Box::new(f) }); + where F: FnOnce(&mut event::Event) + 'static { + let wrapper = Box::new(EventWrapper::new_once(f) ); let ptr = Box::into_raw(wrapper); unsafe { ui_dialog_args_set_result(self.args, Some(event::event_wrapper::)); @@ -428,7 +428,7 @@ impl DialogWindowBuilder { pub fn onclick(&mut self, f: F) -> &mut Self where F: FnMut(&mut event::Event) + 'static { - self.onclick = Some(Box::new(EventWrapper { callback: Box::new(f) })); + self.onclick = Some(Box::new(EventWrapper::new(f) )); self } } @@ -479,8 +479,8 @@ pub fn dialog() -> DialogBuilder { } fn openfile_dialog(obj: &toolkit::UiObject, mode: c_uint, f: F) -where F: FnMut(&mut event::Event) + 'static { - let b: Box> = Box::new(EventWrapper { callback: Box::new(f) }); +where F: FnOnce(&mut event::Event) + 'static { + let b: Box> = Box::new(EventWrapper::new_once(f)); let ptr = Box::into_raw(b); unsafe { ui_openfiledialog(obj.ptr, mode, Some(event_wrapper_oneshot::), ptr as *mut c_void); @@ -488,9 +488,9 @@ where F: FnMut(&mut event::Event) + 'static { } fn savefile_dialog(obj: &toolkit::UiObject, name: &str, f: F) -where F: FnMut(&mut event::Event) + 'static { +where F: FnOnce(&mut event::Event) + 'static { let cstr = CString::new(name).unwrap(); - let b: Box> = Box::new(EventWrapper { callback: Box::new(f) }); + let b: Box> = Box::new(EventWrapper::new_once(f)); let ptr = Box::into_raw(b); unsafe { ui_savefiledialog(obj.ptr, cstr.as_ptr(), Some(event_wrapper_oneshot::), ptr as *mut c_void);