aboutsummaryrefslogtreecommitdiff
path: root/incria/examples/spreadsheet.rs
blob: 135ca80a76fcee1d69b5e3f0ab49922c78daad16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use std::{future::Future, pin::Pin};

use incria::{
    deps,
    thunk::{Thunk, ThunkMapper},
    Mapper,
};
use once_cell::sync::OnceCell;

type Key = (usize, usize);
type Value = usize;

#[derive(Debug, Default)]
struct CellThunk;

impl Thunk<Key, Value> for CellThunk {
    fn compute(&self, key: Key) -> Pin<Box<dyn Future<Output = Value> + Send + '_>> {
        Box::pin(async move {
            if key.0 > 0 {
                let prev1 = *cell_mapping().get(&(key.0 - 1, key.1 - 1)).await;
                let prev2 = *cell_mapping().get(&(key.0 - 1, key.1)).await;
                let prev3 = *cell_mapping().get(&(key.0 - 1, key.1 + 1)).await;
                prev1 + prev2 + prev3
            } else {
                1
            }
        })
    }
}

type CellMapping = ThunkMapper<Key, Value, CellThunk>;
static CELL_MAPPING: OnceCell<CellMapping> = OnceCell::new();
fn cell_mapping() -> &'static CellMapping {
    CELL_MAPPING.get_or_init(CellMapping::default)
}

const N: usize = 20;

#[tokio::main]
async fn main() {
    deps::with_node_id(deps::next_node_id(), async {
        let val = *dbg!(cell_mapping().get(&(N, N)).await);
        // println!("{}", dep_graphviz());

        deps::mark_dirty(21);
        // println!("{}", dep_graphviz());

        assert_eq!(val, *cell_mapping().get(&(N, N)).await);
        println!("{}", deps::dep_graphviz());
    })
    .await;
}