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> {
27 inner: Rc<RefCell<Inner<T>>>,
28}
29
30impl<T> Clone for ModuleManager<T> {
31 fn clone(&self) -> Self {
32 Self {
33 inner: Rc::clone(&self.inner),
34 }
35 }
36}
37
38impl<T> ModuleManager<T>
39where
40 T: App,
41{
42 pub fn new(default_module: TypeId, modules: AHashMap<TypeId, Module<T>>) -> Self {
45 let default_module = modules
46 .get(&default_module)
47 .expect("Unknown module")
48 .clone();
49 Self {
50 inner: Rc::new(RefCell::new(Inner::new(default_module, modules))),
51 }
52 }
53
54 fn inner(&self) -> Ref<'_, Inner<T>> {
55 self.inner.borrow()
56 }
57
58 fn inner_mut(&self) -> RefMut<'_, Inner<T>> {
59 self.inner.borrow_mut()
60 }
61
62 pub fn module(&self) -> Module<T> {
64 self.inner().module.clone()
65 }
66
67 pub fn select<M>(&mut self, core: &mut T)
69 where
70 M: 'static,
71 {
72 self.select_with_type_id(TypeId::of::<M>(), core);
73 }
74
75 pub fn select_with_type_id(&self, type_id: TypeId, core: &mut T) {
78 let (current, next) = {
79 let inner = self.inner();
80 (
81 inner.module.clone(),
82 inner.modules.get(&type_id).expect("Unknown module").clone(),
83 )
84 };
85
86 if let Some(next) = (current.type_id() != next.type_id()).then(|| {
87 let mut inner = self.inner_mut();
88 inner.stack.push_back(current.clone());
89 inner.deactivation = Some(current);
90 inner.module = next.clone();
91 next
92 }) {
93 next.activate(core);
94 }
95 }
96
97 pub fn has_stack(&self) -> bool {
99 !self.inner().stack.is_empty()
100 }
101
102 pub fn render(
105 &self,
106 app: &mut T,
107 ctx: &egui::Context,
108 frame: &mut eframe::Frame,
109 ui: &mut egui::Ui,
110 ) {
111 self.module().render(app, ctx, frame, ui);
112 if let Some(previous) = self.inner_mut().deactivation.take() {
113 previous.deactivate(app);
114 }
115 }
116
117 pub fn back(&mut self) {
120 let mut inner = self.inner_mut();
121 while let Some(module) = inner.stack.pop_back() {
122 if !module.secure() {
123 inner.module = module;
124 return;
125 }
126 }
127 }
128
129 pub fn purge_secure_stack(&mut self) {
131 self.inner_mut().stack.retain(|module| !module.secure());
132 }
133
134 pub fn get<M>(&self) -> ModuleReference<T, M>
136 where
137 M: ModuleT<Context = T> + 'static,
138 {
139 let inner = self.inner();
140 let cell = inner.modules.get(&TypeId::of::<M>()).unwrap();
141 ModuleReference::new(&cell.inner.module)
142 }
143}
144
145pub struct ModuleReference<T, M>
148where
149 T: App,
150{
151 module: Rc<RefCell<dyn ModuleT<Context = T>>>,
152 _phantom: PhantomData<M>,
153}
154
155impl<T, M> ModuleReference<T, M>
156where
157 T: App,
158{
159 fn new(module: &Rc<RefCell<dyn ModuleT<Context = T>>>) -> Self {
160 Self {
161 module: module.clone(),
162 _phantom: PhantomData,
163 }
164 }
165
166 pub fn as_ref(&self) -> Ref<'_, M>
168 where
169 M: ModuleT<Context = T> + 'static,
170 {
171 Ref::map(self.module.borrow(), |r| {
172 (r).as_any()
173 .downcast_ref::<M>()
174 .expect("unable to downcast section")
175 })
176 }
177
178 pub fn as_mut(&self) -> RefMut<'_, M>
180 where
181 M: ModuleT<Context = T> + 'static,
182 {
183 RefMut::map(self.module.borrow_mut(), |r| {
184 (r).as_any_mut()
185 .downcast_mut::<M>()
186 .expect("unable to downcast section")
187 })
188 }
189}