compose_rt/
state.rs

1use std::fmt::{self, Debug, Formatter};
2use std::marker::PhantomData;
3use std::ops::DerefMut;
4
5use generational_box::GenerationalBox;
6
7use crate::{ComposeNode, Composer, Loc, NodeKey};
8
9pub struct State<T, N>
10where
11    N: ComposeNode,
12{
13    pub id: StateId,
14    composer: GenerationalBox<Composer<N>>,
15    ty: PhantomData<T>,
16}
17
18impl<T, N> State<T, N>
19where
20    T: 'static,
21    N: ComposeNode,
22{
23    #[inline(always)]
24    pub(crate) fn new(id: StateId, composer: GenerationalBox<Composer<N>>) -> Self {
25        Self {
26            id,
27            composer,
28            ty: PhantomData,
29        }
30    }
31
32    pub fn with<F, U>(&self, func: F) -> U
33    where
34        F: Fn(&T) -> U,
35    {
36        let mut c = self.composer.write();
37        let c = c.deref_mut();
38        let current_node_key = c.current_node_key;
39        let used_by = c.used_by.entry(self.id).or_default();
40        used_by.insert(current_node_key);
41        let uses = c.uses.entry(current_node_key).or_default();
42        uses.insert(self.id);
43        let scope_states = c.states.get(&self.id.node_key).unwrap();
44        let any_state = scope_states.get(&self.id).unwrap();
45        let state = any_state.downcast_ref::<T>().unwrap();
46        func(state)
47    }
48
49    pub fn with_untracked<F, U>(&self, func: F) -> U
50    where
51        F: Fn(&T) -> U,
52    {
53        let mut c = self.composer.write();
54        let c = c.deref_mut();
55        let scope_states = c.states.get(&self.id.node_key).unwrap();
56        let any_state = scope_states.get(&self.id).unwrap();
57        let state = any_state.downcast_ref::<T>().unwrap();
58        func(state)
59    }
60
61    pub fn with_mut<F, U>(&self, func: F) -> U
62    where
63        F: Fn(&mut T) -> U,
64    {
65        let mut c = self.composer.write();
66        let c = c.deref_mut();
67        let current_node_key = c.current_node_key;
68        let used_by = c.used_by.entry(self.id).or_default();
69        used_by.insert(current_node_key);
70        let uses = c.uses.entry(current_node_key).or_default();
71        uses.insert(self.id);
72        let scope_states = c.states.get_mut(&self.id.node_key).unwrap();
73        let any_state = scope_states.get_mut(&self.id).unwrap();
74        let state = any_state.downcast_mut::<T>().unwrap();
75        c.dirty_states.insert(self.id);
76        func(state)
77    }
78
79    pub fn with_mut_untracked<F, U>(&self, func: F) -> U
80    where
81        F: Fn(&mut T) -> U,
82    {
83        let mut c = self.composer.write();
84        let c = c.deref_mut();
85        let scope_states = c.states.get_mut(&self.id.node_key).unwrap();
86        let any_state = scope_states.get_mut(&self.id).unwrap();
87        let state = any_state.downcast_mut::<T>().unwrap();
88        c.dirty_states.insert(self.id);
89        func(state)
90    }
91
92    pub fn get(&self) -> T
93    where
94        T: Clone,
95    {
96        let mut c = self.composer.write();
97        let c = c.deref_mut();
98        let current_node_key = c.current_node_key;
99        let used_by = c.used_by.entry(self.id).or_default();
100        used_by.insert(current_node_key);
101        let uses = c.uses.entry(current_node_key).or_default();
102        uses.insert(self.id);
103        let scope_states = c.states.get(&self.id.node_key).unwrap();
104        let any_state = scope_states.get(&self.id).unwrap();
105        let state = any_state.downcast_ref::<T>().unwrap();
106        state.clone()
107    }
108
109    pub fn get_untracked(&self) -> T
110    where
111        T: Clone,
112    {
113        let mut c = self.composer.write();
114        let c = c.deref_mut();
115        let scope_states = c.states.get(&self.id.node_key).unwrap();
116        let any_state = scope_states.get(&self.id).unwrap();
117        let state = any_state.downcast_ref::<T>().unwrap();
118        state.clone()
119    }
120
121    pub fn set(&self, value: T) {
122        let mut c = self.composer.write();
123        let c = c.deref_mut();
124        c.dirty_states.insert(self.id);
125        let scope_states = c.states.entry(self.id.node_key).or_default();
126        let val = scope_states.get_mut(&self.id).unwrap();
127        *val = Box::new(value);
128    }
129}
130
131impl<T, N> Debug for State<T, N>
132where
133    N: ComposeNode,
134{
135    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
136        f.debug_struct("State")
137            .field("id", &self.id)
138            .field("ty", &self.ty)
139            .finish()
140    }
141}
142
143impl<T, N> Clone for State<T, N>
144where
145    N: ComposeNode,
146{
147    fn clone(&self) -> Self {
148        *self
149    }
150}
151
152impl<T, N> Copy for State<T, N> where N: ComposeNode {}
153
154#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
155pub struct StateId {
156    pub(crate) node_key: NodeKey,
157    loc: Loc,
158}
159
160impl StateId {
161    #[track_caller]
162    #[inline(always)]
163    pub fn new(node_key: NodeKey) -> Self {
164        Self {
165            node_key,
166            loc: Loc::new(),
167        }
168    }
169}
170
171impl Debug for StateId {
172    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
173        write!(f, "StateId({:?},{:?})", self.node_key, self.loc)
174    }
175}