floem_reactive/
id.rs

1use std::sync::atomic::AtomicU64;
2
3use crate::{effect::observer_clean_up, runtime::RUNTIME, signal::Signal};
4
5/// An internal id which can reference a Signal/Effect/Scope.
6#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Hash)]
7pub struct Id(u64);
8
9impl Id {
10    /// Create a new Id that's next in order
11    pub(crate) fn next() -> Id {
12        static COUNTER: AtomicU64 = AtomicU64::new(0);
13        Id(COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed))
14    }
15
16    /// Try to get the Signal that links with this Id
17    pub(crate) fn signal(&self) -> Option<Signal> {
18        RUNTIME.with(|runtime| runtime.signals.borrow().get(self).cloned())
19    }
20
21    /// Try to set the Signal to be linking with this Id
22    pub(crate) fn add_signal(&self, signal: Signal) {
23        RUNTIME.with(|runtime| runtime.signals.borrow_mut().insert(*self, signal));
24    }
25
26    /// Make this Id a child of the current Scope
27    pub(crate) fn set_scope(&self) {
28        RUNTIME.with(|runtime| {
29            let scope = runtime.current_scope.borrow();
30            let mut children = runtime.children.borrow_mut();
31            let children = children.entry(*scope).or_default();
32            children.insert(*self);
33        });
34    }
35
36    /// Dispose the relevant resources that's linking to this Id, and the all the children
37    /// and grandchildren.
38    pub(crate) fn dispose(&self) {
39        if let Ok((children, signal)) = RUNTIME.try_with(|runtime| {
40            (
41                runtime.children.borrow_mut().remove(self),
42                runtime.signals.borrow_mut().remove(self),
43            )
44        }) {
45            if let Some(children) = children {
46                for child in children {
47                    child.dispose();
48                }
49            }
50
51            if let Some(signal) = signal {
52                for (_, effect) in signal.subscribers() {
53                    observer_clean_up(&effect);
54                }
55            }
56        }
57    }
58}