1use std::sync::atomic::AtomicU64;
2
3use crate::{effect::observer_clean_up, runtime::RUNTIME, signal::Signal};
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Hash)]
7pub struct Id(u64);
8
9impl Id {
10 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 pub(crate) fn signal(&self) -> Option<Signal> {
18 RUNTIME.with(|runtime| runtime.signals.borrow().get(self).cloned())
19 }
20
21 pub(crate) fn add_signal(&self, signal: Signal) {
23 RUNTIME.with(|runtime| runtime.signals.borrow_mut().insert(*self, signal));
24 }
25
26 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 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}