use std::cell::Cell as Counter;
use std::rc::Rc;
use std::time::Duration;
use adaptite::{effect, memo, signal};
use runite::time::sleep;
#[derive(Clone, Copy, Debug, PartialEq)]
enum Mode {
Sum,
Product,
}
#[runite::main]
async fn main() {
let a1 = signal(10i64);
let a2 = signal(20i64);
let b1 = signal(7i64);
let mode = signal(Mode::Sum);
let computes = Rc::new(Counter::new(0usize));
let result = memo({
let a1 = a1.clone();
let a2 = a2.clone();
let b1 = b1.clone();
let mode = mode.clone();
let computes = Rc::clone(&computes);
move || {
computes.set(computes.get() + 1);
let (value, formula) = match mode.get() {
Mode::Sum => (a1.get() + a2.get(), "A1 + A2"),
Mode::Product => (a1.get() * b1.get(), "A1 * B1"),
};
println!(" [compute] RESULT = {formula} = {value}");
value
}
});
effect({
let result = result.clone();
move || println!(" [render] RESULT is {}", result.get())
})
.leak();
let turn = |label: &'static str| async move {
sleep(Duration::from_millis(10)).await;
println!("{label}");
};
println!("initial render (mode = Sum)");
turn("edit A2 = 32 (a dependency of the Sum formula)").await;
a2.set(32);
turn("edit B1 = 9 (NOT a dependency while mode = Sum -- expect silence)").await;
b1.set(9);
turn("edit A1 = 10 to the same value (equal write is suppressed -- expect silence)").await;
a1.set(10);
turn("switch mode = Product (formula now reads A1 and B1)").await;
mode.set(Mode::Product);
turn("edit A2 = 1000 (no longer a dependency -- expect silence)").await;
a2.set(1000);
turn("edit B1 = 10 (a dependency again)").await;
b1.set(10);
sleep(Duration::from_millis(10)).await;
println!(
"done: 6 edits, but the formula computed only {} times",
computes.get()
);
}