1use super::context::{batch, clear_dirty_flag_at_end, mark_nodes_to_be_updated, outer_node};
2use std::cell::{Cell, RefCell, Ref, RefMut};
3use std::ops::{Deref, DerefMut};
4use std::rc::{Rc, Weak};
5
6pub struct Node {
7 pub this: Rc<RefCell<Option<Weak<dyn HasNode>>>>,
8 pub update_op: RefCell<Option<Box<dyn FnMut()->bool>>>,
9 pub visited: Cell<bool>,
10 pub dirty: Cell<bool>,
11 pub dependencies: RefCell<Vec<Rc<dyn HasNode>>>,
12 pub dependents: RefCell<Vec<Weak<dyn HasNode>>>,
13}
14
15pub trait HasNode {
16 fn node(&self) -> &Node;
17}
18
19impl HasNode for Node {
20 fn node(&self) -> &Node {
21 self
22 }
23}
24
25impl Node {
26 pub fn new(this: Rc<RefCell<Option<Weak<dyn HasNode>>>>) -> Node {
27 Node {
28 this,
29 update_op: RefCell::new(None),
30 visited: Cell::new(false),
31 dirty: Cell::new(false),
32 dependencies: RefCell::new(Vec::new()),
33 dependents: RefCell::new(Vec::new()),
34 }
35 }
36}
37
38impl Drop for Node {
39 fn drop(&mut self) {
40 let this = self.this.borrow();
41 let this = this.as_ref().unwrap();
42 for dependency in &*self.dependencies.borrow() {
43 dependency.node().dependents.borrow_mut().retain(|x| !x.ptr_eq(this));
44 }
45 }
46}
47
48pub struct NodeWithValue<A> {
49 pub value: RefCell<Option<A>>,
50 pub node: Node,
51}
52
53impl<A> NodeWithValue<A> {
54 pub fn new(this: Rc<RefCell<Option<Weak<dyn HasNode>>>>, value: A) -> NodeWithValue<A> {
55 NodeWithValue {
56 value: RefCell::new(Some(value)),
57 node: Node::new(this),
58 }
59 }
60
61 pub fn new2(node: Node) -> NodeWithValue<A> {
62 NodeWithValue {
63 value: RefCell::new(None),
64 node,
65 }
66 }
67}
68
69impl<A> HasNode for NodeWithValue<A> {
70 fn node(&self) -> &Node {
71 &self.node
72 }
73}
74
75pub struct NodeValRef<'a,A> {
76 x: Ref<'a,Option<A>>,
77 read: Cell<bool>,
78 node: Rc<dyn HasNode>,
79}
80
81impl<'a,A> NodeValRef<'a,A> {
82 pub fn new(node_with_value: &'a NodeWithValue<A>, node: Rc<dyn HasNode>) -> NodeValRef<'a,A> {
83 NodeValRef {
84 x: node_with_value.value.borrow(),
85 read: Cell::new(false),
86 node
87 }
88 }
89}
90
91impl<'a,A> Deref for NodeValRef<'a,A> {
92 type Target = A;
93
94 fn deref(&self) -> &Self::Target {
95 self.read.set(true);
96 self.x.deref().as_ref().unwrap()
97 }
98}
99
100impl<'a,A> Drop for NodeValRef<'a,A> {
101 fn drop(&mut self) {
102 if self.read.get() {
103 if let Some(outer_node) = outer_node() {
104 outer_node.node().dependencies.borrow_mut().push(self.node.clone());
105 self.node.node().dependents.borrow_mut().push(Rc::downgrade(&outer_node));
106 }
107 }
108 }
109}
110
111pub struct NodeValRefMut<'a,A> {
112 x: Option<RefMut<'a,Option<A>>>,
113 written: Cell<bool>,
114 node: Rc<dyn HasNode>,
115}
116
117impl<'a,A> NodeValRefMut<'a,A> {
118 pub fn new(node_with_value: &'a NodeWithValue<A>, node: Rc<dyn HasNode>) -> NodeValRefMut<'a,A> {
119 NodeValRefMut {
120 x: Some(node_with_value.value.borrow_mut()),
121 written: Cell::new(false),
122 node
123 }
124 }
125}
126
127impl<'a,A> Deref for NodeValRefMut<'a,A> {
128 type Target = A;
129
130 fn deref(&self) -> &Self::Target {
131 self.x.as_ref().unwrap().deref().as_ref().unwrap()
132 }
133}
134
135impl<'a,A> DerefMut for NodeValRefMut<'a,A> {
136 fn deref_mut(&mut self) -> &mut Self::Target {
137 self.written.set(true);
138 self.x.as_mut().unwrap().deref_mut().as_mut().unwrap()
139 }
140}
141
142impl<'a,A> Drop for NodeValRefMut<'a,A> {
143 fn drop(&mut self) {
144 self.x = None;
145 if self.written.get() {
146 batch(|| {
147 self.node.node().dirty.set(true);
148 clear_dirty_flag_at_end(Rc::downgrade(&self.node));
149 mark_nodes_to_be_updated([Rc::downgrade(&self.node)].iter().cloned());
150 });
151 }
152 }
153}