use std::sync::Arc;
use xilem::core::{frozen, memoize};
use xilem::view::{flex_col, text_button};
use xilem::{AnyWidgetView, EventLoop, WidgetView, WindowOptions, Xilem};
struct AppState {
count: i32,
increase_button: MemoizedArcView<i32>,
}
#[derive(Default)]
struct MemoizedArcView<D> {
data: D,
view: Option<Arc<AnyWidgetView<AppState>>>,
}
fn increase_button(state: &mut AppState) -> Arc<AnyWidgetView<AppState>> {
if state.count != state.increase_button.data || state.increase_button.view.is_none() {
let view = Arc::new(text_button(
format!("current count is {}", state.count),
|state: &mut AppState| {
state.count += 1;
},
));
state.increase_button.data = state.count;
state.increase_button.view = Some(view.clone());
view
} else {
state.increase_button.view.as_ref().unwrap().clone()
}
}
fn decrease_button(state: &AppState) -> impl WidgetView<AppState> + use<> {
memoize(state.count, |count| {
text_button(
format!("decrease the count: {count}"),
|data: &mut AppState| data.count -= 1,
)
})
}
fn reset_button() -> impl WidgetView<AppState> {
frozen(|| text_button("reset", |data: &mut AppState| data.count = 0))
}
fn app_logic(state: &mut AppState) -> impl WidgetView<AppState> + use<> {
flex_col((
increase_button(state),
decrease_button(state),
reset_button(),
))
}
fn main() {
let data = AppState {
count: 0,
increase_button: MemoizedArcView::default(),
};
let app = Xilem::new_simple(data, app_logic, WindowOptions::new("Memoization"));
app.run_in(EventLoop::with_user_event()).unwrap();
}