1use std::any::{Any, TypeId};
2use std::cell::RefCell;
3use std::collections::{HashMap, HashSet};
4use std::rc::Rc;
5
6use crate::actor::shape::Declared;
7
8mod actors;
9mod features;
10mod lifetime;
11mod state;
12mod tree;
13
14#[cfg(test)]
15mod tests;
16
17pub use features::{Installed, Listener};
18pub use lifetime::{Awake, DropGuard, Teardown};
19pub use state::{DescribedState, Reducer, Slot, StateHandle, Subscription};
20pub use tree::{ScopeGuard, ScopeTree};
21
22use actors::HeldActor;
23use state::{Cell, Kind};
24use tree::{Tree, tree};
25
26#[derive(Clone, Copy, PartialEq, Eq, Hash)]
40pub struct Scope {
41 tree: u32,
42 index: u32,
43 serial: u64,
44}
45
46impl std::fmt::Debug for Scope {
47 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 write!(f, "Scope({})", self.serial)
49 }
50}
51
52pub type Outlet = &'static str;
55
56pub const MAIN: Outlet = "main";
58
59#[derive(Default)]
60struct ScopeData {
61 cells: RefCell<HashMap<TypeId, Cell>>,
62 kinds: RefCell<HashMap<TypeId, Kind>>,
65 teardowns: RefCell<Vec<Box<dyn FnOnce()>>>,
66 installed_features: RefCell<HashSet<TypeId>>,
74 exports: RefCell<HashSet<TypeId>>,
80 sections: RefCell<Vec<HashMap<TypeId, Rc<dyn Any>>>>,
87 section_names: RefCell<Vec<Option<&'static str>>>,
89 section_declarations: RefCell<Vec<Option<Declared>>>,
91 declarations: RefCell<HashMap<TypeId, Declared>>,
93 listeners: RefCell<Vec<Listener>>,
95 owners: RefCell<HashMap<TypeId, usize>>,
98 installing: RefCell<Vec<usize>>,
101 leave_guards: RefCell<Vec<Rc<dyn Fn() -> crate::guard::Verdict>>>,
103 asleep: Rc<std::cell::Cell<bool>>,
106 wake_hooks: RefCell<Vec<Rc<dyn Fn()>>>,
108 window: std::cell::Cell<Option<u64>>,
110 actors: RefCell<Vec<HeldActor>>,
112}
113
114impl Scope {
115 pub fn child(&self) -> Scope {
117 self.child_in(MAIN)
118 }
119
120 pub fn child_in(&self, outlet: Outlet) -> Scope {
122 let tree =
123 tree(self.tree).unwrap_or_else(|| panic!("a child for {self:?}, whose tree is gone"));
124 let mut nodes = tree.borrow_mut();
125 assert!(
126 nodes.node(self.index, self.serial).is_some(),
127 "a child for {self:?}, which was removed"
128 );
129 let (index, serial) = nodes.insert(Some(self.index), outlet);
130
131 Scope {
132 tree: self.tree,
133 index,
134 serial,
135 }
136 }
137
138 pub fn remove(&self) {
144 let Some(tree) = tree(self.tree) else {
145 return;
146 };
147 let detached = tree.borrow_mut().detach(self.index, self.serial);
148 drop(tree);
149
150 for data in detached {
151 data.tear_down();
152 }
153 }
154
155 pub fn is_alive(&self) -> bool {
157 self.read(|tree| tree.node(self.index, self.serial).is_some())
158 .unwrap_or(false)
159 }
160
161 pub fn parent(&self) -> Option<Scope> {
163 self.read(|tree| {
164 let parent = tree.node(self.index, self.serial)?.parent?;
165 Some(self.named(tree, parent))
166 })
167 .flatten()
168 }
169
170 pub fn outlet(&self) -> Option<Outlet> {
172 self.read(|tree| tree.node(self.index, self.serial).map(|node| node.outlet))
173 .flatten()
174 }
175
176 pub fn ancestors(&self) -> Vec<Scope> {
178 std::iter::successors(self.parent(), Scope::parent).collect()
179 }
180
181 pub fn children_in(&self, outlet: Outlet) -> Vec<Scope> {
183 self.read(|tree| {
184 let Some(node) = tree.node(self.index, self.serial) else {
185 return Vec::new();
186 };
187 node.children
188 .iter()
189 .filter(|&&child| tree.nodes[child as usize].outlet == outlet)
190 .map(|&child| self.named(tree, child))
191 .collect()
192 })
193 .unwrap_or_default()
194 }
195
196 pub fn beside(&self) -> Vec<Scope> {
199 self.read(|tree| {
200 let Some(node) = tree.node(self.index, self.serial) else {
201 return Vec::new();
202 };
203 node.children
204 .iter()
205 .filter(|&&child| tree.nodes[child as usize].outlet != MAIN)
206 .map(|&child| self.named(tree, child))
207 .collect()
208 })
209 .unwrap_or_default()
210 }
211
212 fn read<T>(&self, read: impl FnOnce(&Tree) -> T) -> Option<T> {
213 let tree = tree(self.tree)?;
214 let nodes = tree.borrow();
215 Some(read(&nodes))
216 }
217
218 fn named(&self, tree: &Tree, index: u32) -> Scope {
219 Scope {
220 tree: self.tree,
221 index,
222 serial: tree.nodes[index as usize].serial,
223 }
224 }
225
226 pub fn owner_of<R: 'static>(&self) -> Option<Scope> {
233 if self.claims::<R>() {
234 return Some(*self);
235 }
236
237 std::iter::successors(self.parent(), Scope::parent).find(|scope| scope.exports::<R>())
238 }
239
240 pub fn subtree(&self) -> Vec<Scope> {
242 self.read(|tree| {
243 if tree.node(self.index, self.serial).is_none() {
244 return Vec::new();
245 }
246
247 let mut order = Vec::new();
248 tree.collect(self.index, &mut order);
249 order
250 .into_iter()
251 .map(|index| self.named(tree, index))
252 .collect()
253 })
254 .unwrap_or_default()
255 }
256
257 pub fn guard(&self) -> ScopeGuard {
259 ScopeGuard(*self)
260 }
261
262 pub fn key(&self) -> usize {
264 self.serial as usize
265 }
266
267 fn data(&self) -> Option<Rc<ScopeData>> {
268 self.read(|tree| {
269 tree.node(self.index, self.serial)
270 .and_then(|node| node.data.clone())
271 })
272 .flatten()
273 }
274
275 fn installing(&self, doing: &str) -> Rc<ScopeData> {
276 self.data()
277 .unwrap_or_else(|| panic!("{doing} in {self:?}, which was removed"))
278 }
279}
280
281impl ScopeData {
282 fn section_name(&self, section: usize) -> Option<&'static str> {
283 self.section_names.borrow().get(section).copied().flatten()
284 }
285
286 fn current_section(&self) -> usize {
287 self.installing.borrow().last().copied().unwrap_or(0)
288 }
289}