workflow_egui/module/
manager.rs1use crate::imports::*;
2
3struct Inner<T> {
4 deactivation: Option<Module<T>>,
5 module: Module<T>,
6 modules: AHashMap<TypeId, Module<T>>,
7 stack: VecDeque<Module<T>>,
8}
9
10impl<T> Inner<T>
11where
12 T: App,
13{
14 pub fn new(module: Module<T>, modules: AHashMap<TypeId, Module<T>>) -> Self {
15 Self {
16 deactivation: None,
17 module,
18 modules,
19 stack: VecDeque::new(),
20 }
21 }
22}
23
24pub struct ModuleManager<T> {
25 inner: Rc<RefCell<Inner<T>>>,
26}
27
28impl<T> Clone for ModuleManager<T> {
29 fn clone(&self) -> Self {
30 Self {
31 inner: Rc::clone(&self.inner),
32 }
33 }
34}
35
36impl<T> ModuleManager<T>
37where
38 T: App,
39{
40 pub fn new(default_module: TypeId, modules: AHashMap<TypeId, Module<T>>) -> Self {
41 let default_module = modules
42 .get(&default_module)
43 .expect("Unknown module")
44 .clone();
45 Self {
46 inner: Rc::new(RefCell::new(Inner::new(default_module, modules))),
47 }
48 }
49
50 fn inner(&self) -> Ref<Inner<T>> {
51 self.inner.borrow()
52 }
53
54 fn inner_mut(&self) -> RefMut<Inner<T>> {
55 self.inner.borrow_mut()
56 }
57
58 pub fn module(&self) -> Module<T> {
59 self.inner().module.clone()
60 }
61
62 pub fn select<M>(&mut self, core: &mut T)
63 where
64 M: 'static,
65 {
66 self.select_with_type_id(TypeId::of::<M>(), core);
67 }
68
69 pub fn select_with_type_id(&self, type_id: TypeId, core: &mut T) {
70 let (current, next) = {
71 let inner = self.inner();
72 (
73 inner.module.clone(),
74 inner.modules.get(&type_id).expect("Unknown module").clone(),
75 )
76 };
77
78 if let Some(next) = (current.type_id() != next.type_id()).then(|| {
79 let mut inner = self.inner_mut();
80 inner.stack.push_back(current.clone());
81 inner.deactivation = Some(current);
82 inner.module = next.clone();
83 next
84 }) {
85 next.activate(core);
86 }
87 }
88
89 pub fn has_stack(&self) -> bool {
90 !self.inner().stack.is_empty()
91 }
92
93 pub fn render(
94 &self,
95 app: &mut T,
96 ctx: &egui::Context,
97 frame: &mut eframe::Frame,
98 ui: &mut egui::Ui,
99 ) {
100 self.module().render(app, ctx, frame, ui);
101 if let Some(previous) = self.inner_mut().deactivation.take() {
102 previous.deactivate(app);
103 }
104 }
105
106 pub fn back(&mut self) {
107 let mut inner = self.inner_mut();
108 while let Some(module) = inner.stack.pop_back() {
109 if !module.secure() {
110 inner.module = module;
111 return;
112 }
113 }
114 }
115
116 pub fn purge_secure_stack(&mut self) {
117 self.inner_mut().stack.retain(|module| !module.secure());
118 }
119
120 pub fn get<M>(&self) -> ModuleReference<T, M>
121 where
122 M: ModuleT<Context = T> + 'static,
123 {
124 let inner = self.inner();
125 let cell = inner.modules.get(&TypeId::of::<M>()).unwrap();
126 ModuleReference::new(&cell.inner.module)
127 }
128}
129
130pub struct ModuleReference<T, M>
131where
132 T: App,
133{
134 module: Rc<RefCell<dyn ModuleT<Context = T>>>,
135 _phantom: PhantomData<M>,
136}
137
138impl<T, M> ModuleReference<T, M>
139where
140 T: App,
141{
142 fn new(module: &Rc<RefCell<dyn ModuleT<Context = T>>>) -> Self {
143 Self {
144 module: module.clone(),
145 _phantom: PhantomData,
146 }
147 }
148
149 pub fn as_ref(&self) -> Ref<'_, M>
150 where
151 M: ModuleT<Context = T> + 'static,
152 {
153 Ref::map(self.module.borrow(), |r| {
154 (r).as_any()
155 .downcast_ref::<M>()
156 .expect("unable to downcast section")
157 })
158 }
159
160 pub fn as_mut(&self) -> RefMut<'_, M>
161 where
162 M: ModuleT<Context = T> + 'static,
163 {
164 RefMut::map(self.module.borrow_mut(), |r| {
165 (r).as_any_mut()
166 .downcast_mut::<M>()
167 .expect("unable to downcast section")
168 })
169 }
170}