1use super::*;
2
3impl Table {
4 pub fn calc(
6 x: usize,
7 y: usize,
8 tree_table: &mut Vec<Vec<Box<ThreadSafeNode>>>,
9 ref_src_table: &mut Vec<Vec<Vec<(usize, usize)>>>,
10 dependents_table: &mut Vec<Vec<HashMap<(usize, usize), u32>>>,
11 calculated_table: &mut Vec<Vec<Value>>,
12 walked_position: &mut Vec<(usize, usize)>,
13 ) {
14 walked_position.push((x, y));
15
16 calculated_table[y][x] =
17 if ref_src_table[y][x]
18 .iter()
19 .fold(false, |b, (x_of_target, y_of_target)| {
20 b || walked_position.contains(&(*x_of_target, *y_of_target))
21 })
22 {
23 Value::Error
24 } else {
25 let (calculated_value, old_dependents, new_dependents) =
27 tree_table[y][x].calc(&calculated_table);
28
29 for (dependent_x, dependent_y) in new_dependents {
31 if dependent_y < dependents_table.len()
32 && dependent_x < dependents_table[dependent_y].len()
33 {
34 let entry = dependents_table[y][x]
35 .entry((dependent_x, dependent_y))
36 .or_insert(0);
37
38 if *entry == 0 {
39 ref_src_table[dependent_y][dependent_x].push((x, y));
40 }
41
42 *entry += 1;
43 }
44 }
45
46 for (dependent_x, dependent_y) in old_dependents {
48 if let (true, true, Some(n)) = (
49 dependent_y < dependents_table.len(),
50 dependent_x < dependents_table[dependent_y].len(),
51 dependents_table[y][x].get_mut(&(dependent_x, dependent_y)),
52 ) {
53 *n -= 1;
54
55 if *n == 0 {
56 ref_src_table[dependent_y][dependent_x]
57 .retain(|&(x_src, y_src)| x_src == x && y_src == y);
58 }
59 }
60 }
61
62 dependents_table[y][x].retain(|_, v| *v != 0);
64
65 calculated_value
66 };
67
68 for i in 0..ref_src_table[y][x].len() {
69 let (x_of_target, y_of_target) = ref_src_table[y][x][i];
70 let n_walks = walked_position.iter().fold(0, |b, walked_pos| {
71 if walked_pos == &(x_of_target, y_of_target) {
72 b + 1
73 } else {
74 b
75 }
76 });
77
78 if n_walks < 2 {
79 Self::calc(
80 x_of_target,
81 y_of_target,
82 tree_table,
83 ref_src_table,
84 dependents_table,
85 calculated_table,
86 walked_position,
87 );
88 }
89 }
90 }
91}