Rs-gtk vs. mutable data?


#1

I’m working on adding a GUI to a working CLI application with rs-gtk & siblings. I’d like to mutate the application data on at least some events. This doesn’t seem to be possible with the current rs-gtk API, as trying to compile the invocation gets the rather obfuscated error message:

gtk.rs:47:73: 47:77 error: cannot borrow captured outer variable in an `Fn` closure as mutable
gtk.rs:47     board.connect_button_press_event(move |_, e| make_user_play(e, &mut game));
                                                                                  ^~~~
gtk.rs:47:38: 47:78 help: consider changing this closure to take self by mutable reference
gtk.rs:47     board.connect_button_press_event(move |_, e| make_user_play(e, &mut game));
                                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I eventually figured out that that error message means I need to change connect_button_press_event to take an FnMut instead of an FnOnce. But this isn’t in my sources, so that’s not a good long-term solution. This also prevents

Is this just a problem in the rs-gtk API, or is it something I’m missing? A more appropriate architecture for gtk or rs-gtk apps? Something else I’ve missed?


#2

The majority of signal handlers can be called recursively thus they need to be Fn. You can push this static check to run-time by wrapping the value in a RefCell and dealing with possible recursion yourself

let game = RefCell::new(game);
board.connect_button_press_event(move |_, e| {
    // borrow_mut will panic if the signal happens to be emitted recursively
    make_user_play(e, &mut game.borrow_mut())
});