fgr/reactivity/
signal.rs

1use super::node::{HasNode, NodeWithValue, NodeValRef, NodeValRefMut};
2use std::cell::RefCell;
3use std::ops::Deref;
4use std::ops::DerefMut;
5use std::rc::{Rc, Weak};
6
7pub struct Signal<A> {
8    data: Rc<NodeWithValue<A>>,
9}
10
11impl<A> Clone for Signal<A> {
12    fn clone(&self) -> Self {
13        Signal {
14            data: self.data.clone(),
15        }
16    }
17}
18
19pub fn signal_data<A>(signal: &Signal<A>) -> &Rc<NodeWithValue<A>> {
20    &signal.data
21}
22
23impl<A:'static> Signal<A> {
24    pub fn new(init_value: A) -> Signal<A> {
25        let this: Rc<RefCell<Option<Weak<dyn HasNode>>>> = Rc::new(RefCell::new(None));
26        let r = Signal {
27            data: Rc::new(NodeWithValue::new(this.clone(), init_value))
28        };
29        *(*this).borrow_mut() = Some(Rc::downgrade(&r.data) as Weak<dyn HasNode>);
30        r
31    }
32
33    pub fn read<'a>(&'a self) -> impl Deref<Target=A> + 'a {
34        NodeValRef::new(&*self.data, self.data.clone())
35    }
36
37    pub fn write<'a>(&'a self) -> impl DerefMut<Target=A> + 'a {
38        NodeValRefMut::new(&*self.data, self.data.clone())
39    }
40}