slint icon indicating copy to clipboard operation
slint copied to clipboard

Native callback handler simplification (how to access data without too many Rc/Weak jungling)

Open ogoffart opened this issue 1 year ago • 6 comments

Currently, one need to move a weak pointer of the component handle to the callback, then upgrade it in the callback.

Given a callback foo(int, int) -> int

Currently we have to do

let state2 = state.clone(); // where state is a Rc with the application state
let weak = my_ui.as_weak();    
my_ui.on_foo(move |bar, boo| {
        let my_ui = weak.unwrap();
        // do something with my_ui, state2, foo and bar 
    });

This gymnastic is a bit cumbersome. We need to improve that.

Some ideas include passing the handle directly in the callback:

let state2 = state.clone(); // where state is a Rc with the application state
my_ui.on_foo(|my_ui, bar, boo| {
            // do something with my_ui, state2, foo and bar 
   });

This already saves the creation of the weak for the component handle, This adds an extra argument to the callback. (Should it be |my_ui, bar, boo| {...} or |my_ui, (bar, boo)| {...} ?)

For the extra applicaiton state we could add another Rc in the Component handle

// We add a Data template parameter create a MyUi<MyState>
let my_ui = MyUi::new_with_data(state.clone()); 
// ...
my_ui.on_foo(|my_ui, bar, boo| {
            // do something with my_ui, my_ui.data(), foo and bar 
 });

The problem is that it is a breaking change. Should we enable that only for the new component syntax? or shoud we have pragma or something? Or should we just go for it in a new semver major version?

ogoffart avatar Oct 07 '22 07:10 ogoffart