mach_core/dag/
graph.rs

1use serde::{Serialize, Deserialize};
2use crate::dag::Visitor;
3use super::{MachNode, Handle};
4
5
6///
7/// MachGraph.
8/// This is where nodes are organized.
9/// 
10#[derive(Debug, Serialize, Deserialize)]
11pub struct MachGraph {
12    /// Name of this graph.
13    pub name: String,
14
15    /// Optionally used index of this graph.
16    pub index: u32,
17
18    /// Root index of this graph.
19    pub root: Handle,
20
21    /// Nodes in this graph.
22    pub nodes: Vec<MachNode>,
23}
24
25
26///
27/// Default implementation for MachGraph.
28/// 
29impl Default for MachGraph {
30    fn default() -> Self {
31        let root = MachNode::default();
32        Self {
33            name: String::from("default"),
34            index: 0,
35            root: Handle::from((root.name.clone(), 0)),
36            nodes: vec![root],
37        }
38    }
39}
40
41
42///
43/// Implementation for MachGraph.
44/// 
45impl MachGraph {
46    /// New graph with a name.
47    pub fn new(name: &str) -> Self {
48        Self {
49            name: String::from(name),
50            ..Default::default()
51        }
52    }
53
54
55    /**********************************************************
56     * Getters
57     **********************************************************/
58
59    /// Get root node reference.
60    pub fn get_root(&self) -> Option<&MachNode> {
61        self.get_node(&self.root)
62    }
63
64
65    /// Get root node mutable reference.
66    pub fn get_root_mut(&mut self) -> Option<&mut MachNode> {
67        self.get_node_mut(&self.root.clone())
68    }
69
70
71    /// Get node reference.
72    pub fn get_node(&self, handle: &Handle) -> Option<&MachNode> {
73        let index: u32;
74        if handle.has_index() { index = handle.index.unwrap(); }
75        else { 
76            if let Some(idx) = Handle::index(self, &handle.path) {
77                index = idx;
78            } else {
79                return None;
80            }
81        }
82        let u = index as usize;
83        if u < self.nodes.len() {
84            return Some(&self.nodes[u]);
85        }
86        None
87    }
88
89
90    /// Get node mutable reference.
91    pub fn get_node_mut(&mut self, handle: &Handle) -> Option<&mut MachNode> {
92        let index: u32;
93        if handle.has_index() { index = handle.index.unwrap(); }
94        else { 
95            if let Some(idx) = Handle::index(self, &handle.path) {
96                index = idx;
97            } else {
98                return None;
99            }
100        }
101        let u = index as usize;
102        if u < self.nodes.len() {
103            return Some(&mut self.nodes[u]);
104        }
105        None
106    }
107
108
109    /// Get parent.
110    pub fn get_parent(&self, handle: &Handle) -> Option<&MachNode> {
111        if let Some(node) = self.get_node(handle) {
112            if !node.has_parent() { return None; }
113            return self.get_node(&Handle::from(node.parent));
114        }
115        None
116    }
117
118
119    /**********************************************************
120     * Components
121     **********************************************************/
122
123    /// Push a component to a node.
124    pub fn push_component(&mut self, node: &Handle, component: u32) {
125        if let Some(node) = self.get_node_mut(node) {
126            node.components.push(component);
127        }
128    }
129
130
131    /**********************************************************
132     * Children
133     **********************************************************/
134
135    /// Push a child node of root with a name.
136    pub fn push_child(&mut self, name: &str) -> Handle {
137        self.push_child_of(name, &self.root.clone())
138    }
139
140
141    /// Push a new child node with a name and a parent.
142    pub fn push_child_of(&mut self, name: &str, parent: &Handle) -> Handle {
143        if let Some(parent_index) = parent.get_index(self) {
144            let mut node = MachNode::from((name.into(), parent_index));
145            let index = self.nodes.len() as u32;
146            node.index = index;
147            if let Some(parent) = self.get_node_mut(parent) {
148                parent.children.push(node.index);
149            }
150            self.nodes.push(node);
151            let mut handle = Handle::from(index);
152            handle.set_path(self);
153            return handle;
154        }
155        Handle::from("root")
156    }
157
158
159    /// Push a node to this graph. Sets index and returns it. Not used often...
160    pub fn push(&mut self, mut node: MachNode) -> u32 {
161        let index = self.nodes.len() as u32;
162        node.index = index;
163        self.nodes.push(node);
164        index
165    }
166
167
168    /**********************************************************
169     * Visitors
170     **********************************************************/
171
172    /// Visit all nodes (not in graph order).
173    pub fn visit_all(&self, visitor: &impl Visitor) {
174        for node in &self.nodes { node.accept(visitor); }
175    }
176
177
178    /// Visit all nodes mutable (not in graph order).
179    pub fn visit_all_mut(&mut self, visitor: &mut impl Visitor) {
180        for node in &mut self.nodes { node.accept_mut(visitor); }
181    }
182
183
184    /// Pre-visit.
185    pub fn pre_visit(&self, visitor: &impl Visitor) {
186        let mut handle = self.root.clone();
187        self.pre_visit_internal(visitor, &mut handle);
188    }
189    fn pre_visit_internal(&self, visitor: &impl Visitor, handle: &mut Handle) {
190        if let Some(node) = self.get_node(&handle) {
191            node.accept(visitor);
192            for child in &node.children {
193                let mut handle = Handle::from(*child);
194                self.pre_visit_internal(visitor, &mut handle);
195            }
196        }
197    }
198
199
200    /// Pre-visit mutable.
201    pub fn pre_visit_mut(&mut self, visitor: &mut impl Visitor) {
202        let mut handle = self.root.clone();
203        self.pre_visit_internal_mut(visitor, &mut handle);
204    }
205    fn pre_visit_internal_mut(&mut self, visitor: &mut impl Visitor, handle: &mut Handle) {
206        let mut children: Vec<u32> = Vec::new();
207        if let Some(node) = self.get_node_mut(&handle) {
208            node.accept_mut(visitor);
209            children = node.children.clone();
210        }
211        for child in &children {
212            let mut handle = Handle::from(*child);
213            self.pre_visit_internal_mut(visitor, &mut handle);
214        }
215    }
216
217
218    /// Post-visit.
219    pub fn post_visit(&self, visitor: &impl Visitor) {
220        let mut handle = self.root.clone();
221        self.post_visit_internal(visitor, &mut handle);
222    }
223    fn post_visit_internal(&self, visitor: &impl Visitor, handle: &mut Handle) {
224        if let Some(node) = self.get_node(&handle) {
225            for child in &node.children {
226                let mut handle = Handle::from(*child);
227                self.post_visit_internal(visitor, &mut handle);
228            }
229            node.accept(visitor);
230        }
231    }
232
233
234    /// Post-visit mutable.
235    pub fn post_visit_mut(&mut self, visitor: &mut impl Visitor) {
236        let mut handle = self.root.clone();
237        self.post_visit_internal_mut(visitor, &mut handle);
238    }
239    fn post_visit_internal_mut(&mut self, visitor: &mut impl Visitor, handle: &mut Handle) {
240        let mut children: Vec<u32> = Vec::new();
241        if let Some(node) = self.get_node_mut(&handle) {
242            children = node.children.clone();
243        }
244        for child in &children {
245            let mut handle = Handle::from(*child);
246            self.post_visit_internal_mut(visitor, &mut handle);
247        }
248        if let Some(node) = self.get_node_mut(&handle) {
249            node.accept_mut(visitor);
250        }
251    }
252}