firespine/
node.rs

1//! Nodes
2
3use crate::*;
4
5/// All user-logic and -state for a node is owned by it's associated handler.
6pub trait NodeHandler: Downcast + std::fmt::Debug {
7    /// Called when a new child-node is to be created.
8    /// 
9    /// **Note:**
10    /// > The name of the child-node is *not* a full path, just a name.  
11    /// > 
12    /// > Use [`NodeContext::get_child_name`] to get the full path.
13    fn handle_node_request<'e>(
14        &'e mut self,
15        _name: Arc<str>,
16        _context: &'e mut NodeContext,
17    ) -> NodeHandlerRequestRes {
18        Err("Node has no children".into())
19    }
20    
21    /// Called when the node receives an [`Event`] (wrapped in a [`EventWrapper`]).
22    /// 
23    /// i.e: Given a struct `MyEvent` that impls [`Event`] ...
24    /// ```rust
25    /// fn handle_event<'e>(
26    ///     &'e mut self,
27    ///     event: &'e mut EventWrapper,
28    ///     context: &'e mut NodeContext,
29    /// ) {
30    ///     if let Some(my_event) = event.downcast_ref::<MyEvent>() {
31    ///         // Handle the event! :D
32    ///     }
33    /// }
34    /// ```
35    fn handle_event<'e>(
36        &'e mut self,
37        event: &'e mut EventWrapper,
38        context: &'e mut NodeContext,
39    ) -> SubEvent {
40        if !event.is_silent() {
41            crate::debug!(
42                "EVENT {} AT {}: {:?}",
43                event.get_phase(),
44                context.name,
45                event.get_event()
46            );
47        }
48        None
49    }
50    
51    /// Called by [`NodeContext`] to fetch a component for a descendant node (or the backbone).
52    fn get_comp(
53        &self,
54        _ctype: TypeId
55    ) -> Option<&dyn NodeComponent> {None}
56    
57    /// Called by [`NodeContext`] to fetch a mutable component for a descendant node (or the backbone).
58    fn get_comp_mut(
59        &self,
60        _ctype: TypeId
61    ) -> Option<&RefCell<dyn NodeComponent>> {None}
62    
63    /// Called by [`NodeContext`] to fetch a async component for a descendant node (or the backbone).
64    fn get_comp_arc(
65        &self,
66        _ctype: TypeId
67    ) -> Option<Arc<dyn NodeComponentSync>> {None}
68}
69
70use downcast_rs::impl_downcast;
71impl_downcast!(NodeHandler);
72
73/// TODO: Implement.
74pub trait NodeHandlerSync: NodeHandler + Send + Sync {
75    
76}
77
78/// A potential pending request for the creation of a node-handler.
79pub type NodeHandlerRequestRes = Result<NodeHandlerRequest, Box<dyn std::error::Error>>;
80
81/// A pending request for the creation of a node-handler.
82pub type NodeHandlerRequest = futures::channel::oneshot::Receiver<NodeHandlerCreated>;
83
84/// The result of a completed [`NodeHandlerRequest`].
85pub type NodeHandlerCreated = Result<NamedNodeHandlerBox, Box<dyn std::error::Error>>;
86
87/// A box holding a [`NodeHandler`] instance.
88pub type NodeHandlerBox = Box<dyn NodeHandler>;
89
90/// A optional box holding an [`Event`].
91pub type SubEvent = Option<Box<dyn Event>>;
92
93/// A named [`NodeHandlerBox`].
94#[derive(Debug)]
95pub struct NamedNodeHandlerBox {
96    /// The name(?) of the node.
97    pub name: Arc<str>,
98    /// The node.
99    pub node: NodeHandlerBox
100}
101
102/// Node handler storage.
103pub type Nodes = Vec<NamedNodeHandlerBox>;
104
105/// A handler that does nothing.
106pub mod empty {
107    use super::*;
108    
109    /// An event-handler that does precisely nothing.
110    #[derive(Debug)]
111    pub struct EmptyEventHandler;
112    impl NodeHandler for EmptyEventHandler {}
113}
114
115/// A handler that simply stores components.
116pub mod cstore {
117    use super::*;
118    
119    /// An event-handler that does precisely nothing.
120    pub struct CStoreEventHandler {
121        stored: std::collections::HashMap<std::any::TypeId, Box<dyn NodeComponent>>,
122        celled: std::collections::HashMap<std::any::TypeId, Box<RefCell<dyn NodeComponent>>>,
123        shared: std::collections::HashMap<std::any::TypeId, Arc<dyn NodeComponentSync>>,
124    }
125    
126    impl CStoreEventHandler {
127        /// Adds a new [`NodeComponent`] to this store.
128        pub fn insert_box(&mut self, comp: Box<dyn NodeComponent>) -> bool {
129            let type_id = comp.type_id();
130            self.stored.insert(type_id, comp).is_none()
131        }
132        
133        /// Adds a new [`NodeComponent`] to this store.
134        pub fn insert_cell(&mut self, comp: Box<dyn NodeComponent>) -> bool {
135            let type_id = comp.type_id();
136            self.celled.insert(type_id, Box::new(RefCell::new(comp))).is_none()
137        }
138        
139        /// Adds a new [`NodeComponent`] to this store.
140        pub fn insert_arc(&mut self, comp: Arc<dyn NodeComponentSync>) -> bool {
141            let type_id = comp.type_id();
142            self.shared.insert(type_id, comp).is_none()
143        }
144    }
145    
146    impl CStoreEventHandler {
147        /// Merges the given [`Self`] into this `self`.
148        pub fn with(&mut self, other: CStoreEventHandler) {
149            let Self {
150                stored,
151                celled,
152                shared
153            } = other;
154            self.stored.extend(stored);
155            self.celled.extend(celled);
156            self.shared.extend(shared);
157        }
158        
159    }
160    
161    impl Default for CStoreEventHandler {
162        fn default() -> Self {
163            Self {
164                stored: Default::default(),
165                celled: Default::default(),
166                shared: Default::default(),
167            }
168        }
169    }
170    
171    impl std::fmt::Debug for CStoreEventHandler {
172        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
173            f.debug_struct("CStoreEventHandler")
174                .field("box", &self.stored.keys())
175                .field("cel", &self.celled.keys())
176                .field("arc", &self.shared.keys())
177                .finish()
178        }
179    }
180    
181    impl NodeHandler for CStoreEventHandler {
182        fn get_comp(
183            &self,
184            ctype: TypeId
185        ) -> Option<&dyn NodeComponent> {
186            self.stored.get(&ctype).map(|comp| comp.as_ref())
187        }
188
189        fn get_comp_mut(
190            &self,
191            ctype: TypeId
192        ) -> Option<&RefCell<dyn NodeComponent>> {
193            self.celled.get(&ctype).map(|comp| comp.as_ref())
194        }
195
196        fn get_comp_arc(
197            &self,
198            ctype: TypeId
199        ) -> Option<Arc<dyn NodeComponentSync>> {
200            self.shared.get(&ctype).map(|comp| comp.clone())
201        }
202    }
203    
204    /// Make sure that components are stored with their type_id as key.
205    #[test]
206    fn test_cstore() {
207        let mut cstore = CStoreEventHandler::default();
208        
209        assert!(cstore.insert_box(Box::new("stringy box".to_string())) == true);
210        assert!(cstore.insert_box(Box::new(Vec::<String>::default())) == true);
211        
212        assert!(cstore.insert_cell(Box::new("stringy box".to_string())) == true);
213        assert!(cstore.insert_cell(Box::new(Vec::<String>::default())) == true);
214        
215        assert!(cstore.insert_arc(Arc::new("stringy box".to_string())) == true);
216        assert!(cstore.insert_arc(Arc::new(Vec::<String>::default())) == true);
217    }
218}
219
220/// A handler that combines two other handlers.
221pub mod cascade {
222    use super::*;
223    
224    /// An event-handler that does precisely nothing.
225    #[derive(Debug)]
226    pub struct CascadingEventHandler {
227        /// The outer node.
228        pub(crate) outer: NamedNodeHandlerBox,
229        /// The inner node.
230        pub(crate) inner: NamedNodeHandlerBox,
231    }
232    
233    impl NodeHandler for CascadingEventHandler {
234        fn handle_node_request<'e>(
235            &'e mut self,
236            name: Arc<str>,
237            context: &'e mut NodeContext,
238        ) -> NodeHandlerRequestRes {
239            let inner_req = self.inner.node.handle_node_request(name.clone(), context);
240            
241            if let Err(_err) = inner_req {
242                return self.outer.node.handle_node_request(name, context);
243            }
244            
245            inner_req
246        }
247        
248        fn handle_event<'e>(
249            &'e mut self,
250            event: &'e mut EventWrapper,
251            context: &'e mut NodeContext,
252        ) -> SubEvent {
253            match event.get_phase() {
254                EventPhase::Creation => unreachable!("This should never ever occur"),
255                EventPhase::Falling => {
256                    // TODO: Handle sub-event returned by the outer node.
257                    self.outer.node.handle_event(event, context);
258                    if !event.can_fall() {return None}
259                    self.inner.node.handle_event(event, context)
260                },
261                EventPhase::Acting => {
262                    self.inner.node.handle_event(event, context)
263                },
264                EventPhase::Rising => {
265                    // TODO: Handle sub-event returned by the inner node.
266                    self.inner.node.handle_event(event, context);
267                    if !event.can_rise() {return None}
268                    self.outer.node.handle_event(event, context)
269                },
270            }
271        }
272        
273        fn get_comp(
274            &self,
275            ctype: TypeId
276        ) -> Option<&dyn NodeComponent> {
277            self.inner.node.get_comp(ctype).or_else(||self.outer.node.get_comp(ctype))
278        }
279        
280        fn get_comp_mut(
281            &self,
282            ctype: TypeId
283        ) -> Option<&RefCell<dyn NodeComponent>> {
284            self.inner.node.get_comp_mut(ctype).or_else(||self.outer.node.get_comp_mut(ctype))
285        }
286        
287        fn get_comp_arc(
288            &self,
289            ctype: TypeId
290        ) -> Option<Arc<dyn NodeComponentSync>> {
291            self.inner.node.get_comp_arc(ctype).or_else(||self.outer.node.get_comp_arc(ctype))
292        }
293    }
294
295}