trellis_core/
scope_lifecycle.rs1use crate::{Graph, GraphResult, ResourceKey, ScopeId};
2
3impl<C, O> Graph<C, O> {
4 pub(crate) fn close_scope_direct(&mut self, scope: ScopeId) -> GraphResult<Vec<ScopeId>> {
5 self.require_scope(scope)?;
6 let scopes = self.scope_close_order(scope);
7 for closing in &scopes {
8 if let Some(scope_meta) = self.scopes.get_mut(closing) {
9 scope_meta.close();
10 }
11 self.resource_planners
12 .retain(|planner| planner.scope != *closing);
13 for node in self.nodes.values_mut() {
14 node.detach_scope(*closing);
15 }
16 }
17 Ok(scopes)
18 }
19
20 pub fn child_scopes(&self, scope: ScopeId) -> GraphResult<Vec<ScopeId>> {
22 self.require_scope(scope)?;
23 Ok(self.child_scopes_unchecked(scope))
24 }
25
26 pub fn orphan_resources(&self) -> Vec<ResourceKey> {
28 self.resource_owners
29 .iter()
30 .filter_map(|(key, owners)| {
31 let has_live_owner = owners
32 .iter()
33 .any(|scope| self.scopes.get(scope).is_some_and(|meta| !meta.is_closed()));
34 (!has_live_owner).then(|| key.clone())
35 })
36 .collect()
37 }
38
39 fn scope_close_order(&self, scope: ScopeId) -> Vec<ScopeId> {
40 let mut scopes = Vec::new();
41 self.collect_scope_close_order(scope, &mut scopes);
42 scopes
43 }
44
45 fn collect_scope_close_order(&self, scope: ScopeId, scopes: &mut Vec<ScopeId>) {
46 for child in self.child_scopes_unchecked(scope) {
47 self.collect_scope_close_order(child, scopes);
48 }
49 if self
50 .scopes
51 .get(&scope)
52 .is_some_and(|scope_meta| !scope_meta.is_closed())
53 {
54 scopes.push(scope);
55 }
56 }
57
58 fn child_scopes_unchecked(&self, scope: ScopeId) -> Vec<ScopeId> {
59 self.scopes
60 .values()
61 .filter_map(|scope_meta| {
62 (scope_meta.parent() == Some(scope)).then_some(scope_meta.id())
63 })
64 .collect()
65 }
66}