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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
use super::batch; use super::context::{in_node, push_effect}; use super::node::{HasNode, Node}; use std::cell::RefCell; use std::rc::{Rc, Weak}; pub struct Effect { data: Rc<Node>, } impl Clone for Effect { fn clone(&self) -> Self { Effect { data: self.data.clone(), } } } impl Effect { pub fn new<K: FnMut() + 'static>(mut k: K) -> Effect { batch(|| { let this = Rc::new(RefCell::new(None)); let node = Rc::new(Node::new(this.clone())); let this2 = Rc::downgrade(&node); *this.borrow_mut() = Some(this2.clone()); let this3 = this2.clone(); let k2 = Rc::new(RefCell::new(Box::new(move || { let node = this2.upgrade().unwrap(); let weak_node = Rc::downgrade(&node) as Weak<dyn HasNode>; for dependency in &*node.dependencies.borrow() { dependency.node().dependents.borrow_mut().retain(|x| !x.ptr_eq(&weak_node)); } node.dependencies.borrow_mut().clear(); in_node( node, || { k(); } ); }) as Box<dyn FnMut()>)); { let node = node.clone(); let k2 = k2.clone(); let k3 = Rc::new(RefCell::new(Box::new(move || { let _ = &node; k2.borrow_mut()(); }) as Box<dyn FnMut()>)); push_effect(k3); } *node.update_op.borrow_mut() = Some(Box::new(move || { let node = this3.upgrade().unwrap(); let k2 = k2.clone(); let k3 = Rc::new(RefCell::new(Box::new(move || { let _ = &node; k2.borrow_mut()(); }) as Box<dyn FnMut()>)); push_effect(k3); false })); Effect { data: node, } }) } pub fn merge(effects: Vec<Effect>) -> Effect { Effect::new(move || { let _ = &effects; }) } }