decoupled/
decoupled.rs

1use fltk::{app, button::Button, prelude::*, window::Window};
2use fltk_observe::{Runner, WidgetObserver};
3use std::sync::{Arc, Mutex};
4
5struct Counter {
6    value: i32,
7}
8
9impl Counter {
10    fn new() -> Self {
11        Self { value: 0 }
12    }
13}
14
15fn increment(c: &mut Arc<Mutex<Counter>>, _b: &Button) {
16    c.lock().unwrap().value += 1;
17}
18
19fn update_label(c: &Arc<Mutex<Counter>>, b: &mut Button) {
20    b.set_label(&c.lock().unwrap().value.to_string());
21}
22
23fn main() {
24    let counter = Arc::new(Mutex::new(Counter::new()));
25    let c = counter.clone();
26    let a = app::App::default().use_state(move || c).unwrap();
27
28    let mut window = Window::default().with_size(200, 200).with_label("Add data");
29    let mut inc = Button::default_fill();
30    inc.set_action(increment);
31    inc.set_view(update_label);
32    window.end();
33    window.show();
34
35    std::thread::spawn(move || {
36        let counter = counter.clone();
37        loop {
38            // doesn't update the gui
39            counter.clone().lock().unwrap().value += 1;
40            // updates the gui
41            fltk_observe::with_state_mut(|c: &mut Arc<Mutex<Counter>>| {
42                c.lock().unwrap().value += 1;
43                app::awake();
44            });
45            std::thread::sleep(std::time::Duration::from_secs(1));
46        }
47    });
48
49    a.run().unwrap();
50}