compose_rt/
recomposer.rs

1use std::fmt::{Debug, Formatter};
2use std::ops::{Deref, DerefMut};
3
4use generational_box::{GenerationalBox, Owner};
5
6use crate::{utils, ComposeNode, Composer, NodeKey, State};
7
8pub struct Recomposer<S, N>
9where
10    N: ComposeNode,
11{
12    #[allow(dead_code)]
13    pub(crate) owner: Owner,
14    pub(crate) composer: GenerationalBox<Composer<N>>,
15    pub(crate) root_state: State<S, N>,
16}
17
18impl<S, N> Recomposer<S, N>
19where
20    S: 'static,
21    N: ComposeNode,
22{
23    pub fn recompose(&mut self) {
24        let mut c = self.composer.write();
25        c.dirty_nodes.clear();
26        for state_id in c.dirty_states.drain().collect::<Vec<_>>() {
27            if let Some(nodes) = c.used_by.get(&state_id).cloned() {
28                c.dirty_nodes.extend(nodes);
29            }
30        }
31        let mut composables = Vec::with_capacity(c.dirty_nodes.len());
32        for node_key in &c.dirty_nodes {
33            if let Some(composable) = c.composables.get(node_key).cloned() {
34                composables.push((*node_key, composable));
35            }
36        }
37        drop(c);
38        for (node_key, composable) in composables {
39            {
40                let mut c = self.composer.write();
41                c.current_node_key = node_key;
42            }
43            composable.compose();
44        }
45        let mut c = self.composer.write();
46        let c = c.deref_mut();
47        let unmount_nodes = c
48            .unmount_nodes
49            .difference(&c.mount_nodes)
50            .cloned()
51            .collect::<Vec<_>>();
52        for n in unmount_nodes {
53            c.composables.remove(&n);
54            c.nodes.remove(n);
55            if let Some(node_states) = c.states.remove(&n) {
56                for state in node_states.keys() {
57                    c.used_by.remove(state);
58                }
59            }
60            let use_states = c.uses.remove(&n);
61            if let Some(use_states) = use_states {
62                for state in use_states {
63                    if let Some(used_by) = c.used_by.get_mut(&state) {
64                        used_by.remove(&n);
65                    }
66                }
67            }
68        }
69        c.mount_nodes.clear();
70        c.unmount_nodes.clear();
71    }
72
73    #[inline(always)]
74    pub fn recompose_with(&mut self, new_state: S) {
75        self.root_state.set(new_state);
76        self.recompose();
77    }
78
79    #[inline(always)]
80    pub fn root_node_key(&self) -> NodeKey {
81        self.composer.read().root_node_key
82    }
83
84    #[inline(always)]
85    pub fn with_context<F, T>(&self, func: F) -> T
86    where
87        F: FnOnce(&N::Context) -> T,
88    {
89        let c = self.composer.read();
90        func(&c.context)
91    }
92
93    #[inline(always)]
94    pub fn with_context_mut<F, T>(&mut self, func: F) -> T
95    where
96        F: FnOnce(&mut N::Context) -> T,
97    {
98        let mut c = self.composer.write();
99        func(&mut c.context)
100    }
101
102    #[inline(always)]
103    pub fn with_composer<F, T>(&self, func: F) -> T
104    where
105        F: FnOnce(&Composer<N>) -> T,
106    {
107        let c = self.composer.read();
108        func(c.deref())
109    }
110
111    #[inline(always)]
112    pub fn with_composer_mut<F, T>(&mut self, func: F) -> T
113    where
114        F: FnOnce(&mut Composer<N>) -> T,
115    {
116        let mut c = self.composer.write();
117        func(c.deref_mut())
118    }
119
120    #[inline(always)]
121    pub fn get_root_state(&self) -> S
122    where
123        S: Clone,
124    {
125        self.root_state.get_untracked()
126    }
127
128    #[inline(always)]
129    pub fn set_root_state(&mut self, val: S) {
130        self.root_state.set(val);
131    }
132
133    #[inline(always)]
134    pub fn with_root_state<F, T>(&self, func: F) -> T
135    where
136        F: Fn(&S) -> T,
137    {
138        self.root_state.with_untracked(func)
139    }
140
141    #[inline(always)]
142    pub fn with_root_state_mut<F, T>(&mut self, func: F) -> T
143    where
144        F: Fn(&mut S) -> T,
145    {
146        self.root_state.with_mut_untracked(func)
147    }
148
149    #[inline(always)]
150    pub fn print_tree(&self)
151    where
152        N: Debug,
153    {
154        self.print_tree_with(self.root_node_key(), |n| format!("{:?}", n));
155    }
156
157    #[inline(always)]
158    pub fn print_tree_with<D>(&self, node_key: NodeKey, display_fn: D)
159    where
160        D: Fn(Option<&N>) -> String,
161    {
162        let c = self.composer.read();
163        utils::print_tree(&c, node_key, display_fn);
164    }
165}
166
167impl<S, N> Debug for Recomposer<S, N>
168where
169    N: ComposeNode + Debug,
170{
171    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
172        let c = self.composer.read();
173        f.debug_struct("Recomposer")
174            .field("nodes", &c.nodes)
175            .field("states", &c.states)
176            .field("dirty_states", &c.dirty_states)
177            .field("used_by", &c.used_by)
178            .field("composables", &c.composables.keys())
179            .finish()
180    }
181}