1use std::{
2 any::{
3 Any,
4 TypeId,
5 },
6 rc::Rc,
7};
8
9use generational_box::{
10 AnyStorage,
11 GenerationalBox,
12 Owner,
13 UnsyncStorage,
14};
15use pathgraph::PathGraph;
16use rustc_hash::FxHashMap;
17
18use crate::{
19 diff_key::DiffKey,
20 element::{
21 ComponentProps,
22 Element,
23 },
24 node_id::NodeId,
25 path_element::PathElement,
26 reactive_context::ReactiveContext,
27 scope_id::ScopeId,
28};
29
30pub struct Scope {
31 pub id: ScopeId,
32 pub parent_id: Option<ScopeId>,
33 pub height: usize,
34
35 pub parent_node_id_in_parent: NodeId,
36 pub path_in_parent: Box<[u32]>, pub nodes: PathGraph<PathNode>,
39
40 pub key: DiffKey,
41
42 pub comp: Rc<dyn Fn(Rc<dyn ComponentProps>) -> Element>,
43
44 pub props: Rc<dyn ComponentProps>,
45
46 pub element: Option<PathElement>,
47}
48
49impl Scope {
50 pub fn with_element<D>(&self, target_path: &[u32], with: D)
51 where
52 D: FnOnce(&PathElement),
53 {
54 if let Some(element) = &self.element {
55 element.with_element(target_path, with);
56 }
57 }
58}
59
60#[derive(Clone)]
61pub struct ScopeStorage {
62 pub parent_id: Option<ScopeId>,
63 pub current_run: usize,
64 pub current_value: usize,
65 pub values: Vec<Rc<dyn Any>>,
66
67 pub contexts: FxHashMap<TypeId, Rc<dyn Any>>,
68
69 pub reactive_context: ReactiveContext,
70
71 pub owner: Owner,
72}
73
74impl ScopeStorage {
75 pub(crate) fn new<T: 'static>(
76 parent_id: Option<ScopeId>,
77 reactive_context: impl FnOnce(&dyn Fn(T) -> GenerationalBox<T>) -> ReactiveContext,
78 ) -> Self {
79 let owner = UnsyncStorage::owner();
80 let reactive_context = (reactive_context)(&|d: T| owner.insert(d));
81 Self {
82 parent_id,
83 current_run: Default::default(),
84 current_value: Default::default(),
85 values: Default::default(),
86 contexts: Default::default(),
87 reactive_context,
88 owner,
89 }
90 }
91
92 pub(crate) fn reset(&mut self) {
93 self.current_run = 0;
94 self.current_value = 0;
95 self.values.clear();
96 self.contexts.clear();
97 }
98}
99
100#[derive(Clone, Debug, PartialEq)]
101pub struct PathNode {
102 pub node_id: NodeId,
103 pub scope_id: Option<ScopeId>,
104}