egui_treeize/
lib.rs

1//!
2//! # egui-treeize
3//!
4//! Provides a tree-like graph visualization for egui.
5//!
6
7#![deny(missing_docs, non_ascii_idents, unsafe_code)]
8#![deny(clippy::correctness, clippy::complexity, clippy::perf, clippy::style, clippy::suspicious)]
9#![warn(clippy::pedantic, clippy::dbg_macro, clippy::must_use_candidate)]
10#![allow(clippy::range_plus_one, clippy::inline_always, clippy::use_self)]
11
12pub mod layout;
13pub mod ui;
14
15use std::ops::{Index, IndexMut};
16
17use egui::{Pos2, ahash::HashSet};
18use slab::Slab;
19
20impl<T> Default for Treeize<T> {
21  fn default() -> Self {
22    Treeize::new()
23  }
24}
25
26/// Node identifier.
27///
28/// This is newtype wrapper around [`usize`] that implements
29/// necessary traits, but omits arithmetic operations.
30#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
31#[repr(transparent)]
32#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(transparent))]
33pub struct NodeId(pub usize);
34
35/// Node of the graph.
36#[derive(Clone, Debug)]
37#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
38#[non_exhaustive]
39pub struct Node<T> {
40  /// Node generic value.
41  pub value: T,
42
43  /// Position of the top-left corner of the node.
44  /// This does not include frame margin.
45  pub pos: egui::Pos2,
46
47  /// Flag indicating that the node is open - not collapsed.
48  pub open: bool,
49}
50
51/// Output pin identifier.
52/// Cosists of node id and pin index.
53#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
54#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
55pub struct OutPinId {
56  /// Node id.
57  pub node: NodeId,
58
59  /// Output pin index.
60  pub output: usize,
61}
62
63/// Input pin identifier. Cosists of node id and pin index.
64#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
65#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
66pub struct InPinId {
67  /// Node id.
68  pub node: NodeId,
69
70  /// Input pin index.
71  pub input: usize,
72}
73
74/// Connection between two nodes.
75///
76/// Nodes may support multiple connections to the same input or output.
77/// But duplicate connections between same input and the same output are not allowed.
78/// Attempt to insert existing connection will be ignored.
79#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
80#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
81struct Wire {
82  out_pin: OutPinId,
83  in_pin: InPinId,
84}
85
86#[derive(Clone, Debug)]
87struct Wires {
88  wires: HashSet<Wire>,
89}
90
91#[cfg(feature = "serde")]
92impl serde::Serialize for Wires {
93  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
94  where
95    S: serde::Serializer,
96  {
97    use serde::ser::SerializeSeq;
98
99    let mut seq = serializer.serialize_seq(Some(self.wires.len()))?;
100    for wire in &self.wires {
101      seq.serialize_element(&wire)?;
102    }
103    seq.end()
104  }
105}
106
107#[cfg(feature = "serde")]
108impl<'de> serde::Deserialize<'de> for Wires {
109  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
110  where
111    D: serde::Deserializer<'de>,
112  {
113    struct Visitor;
114
115    impl<'de> serde::de::Visitor<'de> for Visitor {
116      type Value = HashSet<Wire>;
117
118      fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
119        formatter.write_str("a sequence of wires")
120      }
121
122      fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
123      where
124        A: serde::de::SeqAccess<'de>,
125      {
126        let mut wires = HashSet::with_hasher(egui::ahash::RandomState::new());
127        while let Some(wire) = seq.next_element()? {
128          wires.insert(wire);
129        }
130        Ok(wires)
131      }
132    }
133
134    let wires = deserializer.deserialize_seq(Visitor)?;
135    Ok(Wires { wires })
136  }
137}
138
139impl Wires {
140  fn new() -> Self {
141    Wires { wires: HashSet::with_hasher(egui::ahash::RandomState::new()) }
142  }
143
144  fn insert(&mut self, wire: Wire) -> bool {
145    self.wires.insert(wire)
146  }
147
148  fn remove(&mut self, wire: &Wire) -> bool {
149    self.wires.remove(wire)
150  }
151
152  fn drop_node(&mut self, node: NodeId) -> usize {
153    let count = self.wires.len();
154    self.wires.retain(|wire| wire.out_pin.node != node && wire.in_pin.node != node);
155    count - self.wires.len()
156  }
157
158  fn drop_all_nodes(&mut self) -> usize {
159    let count = self.wires.len();
160    self.wires.clear();
161    count
162  }
163
164  fn drop_inputs(&mut self, pin: InPinId) -> usize {
165    let count = self.wires.len();
166    self.wires.retain(|wire| wire.in_pin != pin);
167    count - self.wires.len()
168  }
169
170  fn drop_outputs(&mut self, pin: OutPinId) -> usize {
171    let count = self.wires.len();
172    self.wires.retain(|wire| wire.out_pin != pin);
173    count - self.wires.len()
174  }
175
176  fn wired_inputs(&self, out_pin: OutPinId) -> impl Iterator<Item = InPinId> + '_ {
177    self.wires.iter().filter(move |wire| wire.out_pin == out_pin).map(|wire| wire.in_pin)
178  }
179
180  fn wired_outputs(&self, in_pin: InPinId) -> impl Iterator<Item = OutPinId> + '_ {
181    self.wires.iter().filter(move |wire| wire.in_pin == in_pin).map(|wire| wire.out_pin)
182  }
183
184  fn iter(&self) -> impl Iterator<Item = Wire> + '_ {
185    self.wires.iter().copied()
186  }
187}
188
189/// Treeize is generic node-graph container.
190///
191/// It holds graph state - positioned nodes and wires between their pins.
192/// It can be rendered using [`Treeize::show`].
193#[derive(Clone, Debug)]
194#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
195pub struct Treeize<T> {
196  // #[cfg_attr(feature = "serde", serde(with = "serde_nodes"))]
197  nodes: Slab<Node<T>>,
198  wires: Wires,
199}
200
201impl<T> Treeize<T> {
202  /// Create a new empty Treeize.
203  ///
204  /// # Examples
205  ///
206  /// ```
207  /// # use egui_treeize::Treeize;
208  /// let treeize = Treeize::<()>::new();
209  /// ```
210  #[must_use]
211  pub fn new() -> Self {
212    Treeize { nodes: Slab::new(), wires: Wires::new() }
213  }
214
215  /// Adds a node to the Treeize.
216  /// Returns the index of the node.
217  ///
218  /// # Examples
219  ///
220  /// ```
221  /// # use egui_treeize::Treeize;
222  /// let mut treeize = Treeize::<()>::new();
223  /// treeize.insert_node(egui::pos2(0.0, 0.0), ());
224  /// ```
225  pub fn insert_node(&mut self, pos: egui::Pos2, node: T) -> NodeId {
226    let idx = self.nodes.insert(Node { value: node, pos, open: true });
227
228    NodeId(idx)
229  }
230
231  /// Adds a node to the Treeize in collapsed state.
232  /// Returns the index of the node.
233  ///
234  /// # Examples
235  ///
236  /// ```
237  /// # use egui_treeize::Treeize;
238  /// let mut treeize = Treeize::<()>::new();
239  /// treeize.insert_node_collapsed(egui::pos2(0.0, 0.0), ());
240  /// ```
241  pub fn insert_node_collapsed(&mut self, pos: egui::Pos2, node: T) -> NodeId {
242    let idx = self.nodes.insert(Node { value: node, pos, open: false });
243
244    NodeId(idx)
245  }
246
247  /// Opens or collapses a node.
248  ///
249  /// # Panics
250  ///
251  /// Panics if the node does not exist.
252  #[track_caller]
253  pub fn open_node(&mut self, node: NodeId, open: bool) {
254    self.nodes[node.0].open = open;
255  }
256
257  /// Removes a node from the Treeize.
258  /// Returns the node if it was removed.
259  ///
260  /// # Panics
261  ///
262  /// Panics if the node does not exist.
263  ///
264  /// # Examples
265  ///
266  /// ```
267  /// # use egui_treeize::Treeize;
268  /// let mut treeize = Treeize::<()>::new();
269  /// let node = treeize.insert_node(egui::pos2(0.0, 0.0), ());
270  /// treeize.remove_node(node);
271  /// ```
272  #[track_caller]
273  pub fn remove_node(&mut self, idx: NodeId) -> T {
274    let value = self.nodes.remove(idx.0).value;
275    self.wires.drop_node(idx);
276    value
277  }
278
279  /// Removes all nodes from the Treeize.
280  /// Returns number of removed nodes.
281  ///
282  /// # Examples
283  ///
284  /// ```
285  /// # use egui_treeize::Treeize;
286  /// let mut treeize = Treeize::<()>::new();
287  /// treeize.clear();
288  /// ```
289  #[track_caller]
290  pub fn clear(&mut self) -> usize {
291    let count = self.nodes.len();
292    self.nodes.drain();
293    self.wires.drop_all_nodes();
294    count
295  }
296
297  /// Connects two nodes.
298  /// Returns true if the connection was successful.
299  /// Returns false if the connection already exists.
300  ///
301  /// # Panics
302  ///
303  /// Panics if either node does not exist.
304  #[track_caller]
305  pub fn connect(&mut self, from: OutPinId, to: InPinId) -> bool {
306    assert!(self.nodes.contains(from.node.0));
307    assert!(self.nodes.contains(to.node.0));
308
309    let wire = Wire { out_pin: from, in_pin: to };
310    self.wires.insert(wire)
311  }
312
313  /// Disconnects two nodes.
314  /// Returns true if the connection was removed.
315  ///
316  /// # Panics
317  ///
318  /// Panics if either node does not exist.
319  #[track_caller]
320  pub fn disconnect(&mut self, from: OutPinId, to: InPinId) -> bool {
321    assert!(self.nodes.contains(from.node.0));
322    assert!(self.nodes.contains(to.node.0));
323
324    let wire = Wire { out_pin: from, in_pin: to };
325
326    self.wires.remove(&wire)
327  }
328
329  /// Removes all connections to the node's pin.
330  ///
331  /// Returns number of removed connections.
332  ///
333  /// # Panics
334  ///
335  /// Panics if the node does not exist.
336  #[track_caller]
337  pub fn drop_inputs(&mut self, pin: InPinId) -> usize {
338    assert!(self.nodes.contains(pin.node.0));
339    self.wires.drop_inputs(pin)
340  }
341
342  /// Removes all connections from the node's pin.
343  /// Returns number of removed connections.
344  ///
345  /// # Panics
346  ///
347  /// Panics if the node does not exist.
348  #[track_caller]
349  pub fn drop_outputs(&mut self, pin: OutPinId) -> usize {
350    assert!(self.nodes.contains(pin.node.0));
351    self.wires.drop_outputs(pin)
352  }
353
354  /// Returns reference to the node.
355  #[must_use]
356  pub fn get_node(&self, idx: NodeId) -> Option<&T> {
357    self.nodes.get(idx.0).map(|node| &node.value)
358  }
359
360  /// Returns mutable reference to the node.
361  pub fn get_node_mut(&mut self, idx: NodeId) -> Option<&mut T> {
362    match self.nodes.get_mut(idx.0) {
363      Some(node) => Some(&mut node.value),
364      None => None,
365    }
366  }
367
368  /// Returns reference to the node data.
369  #[must_use]
370  pub fn get_node_info(&self, idx: NodeId) -> Option<&Node<T>> {
371    self.nodes.get(idx.0)
372  }
373
374  /// Returns mutable reference to the node data.
375  pub fn get_node_info_mut(&mut self, idx: NodeId) -> Option<&mut Node<T>> {
376    self.nodes.get_mut(idx.0)
377  }
378
379  /// Iterates over shared references to each node.
380  pub fn nodes(&self) -> NodesIter<'_, T> {
381    NodesIter { nodes: self.nodes.iter() }
382  }
383
384  /// Iterates over mutable references to each node.
385  pub fn nodes_mut(&mut self) -> NodesIterMut<'_, T> {
386    NodesIterMut { nodes: self.nodes.iter_mut() }
387  }
388
389  /// Iterates over shared references to each node and its position.
390  pub fn nodes_pos(&self) -> NodesPosIter<'_, T> {
391    NodesPosIter { nodes: self.nodes.iter() }
392  }
393
394  /// Iterates over mutable references to each node and its position.
395  pub fn nodes_pos_mut(&mut self) -> NodesPosIterMut<'_, T> {
396    NodesPosIterMut { nodes: self.nodes.iter_mut() }
397  }
398
399  /// Iterates over shared references to each node and its identifier.
400  pub fn node_ids(&self) -> NodesIdsIter<'_, T> {
401    NodesIdsIter { nodes: self.nodes.iter() }
402  }
403
404  /// Iterates over mutable references to each node and its identifier.
405  pub fn nodes_ids_mut(&mut self) -> NodesIdsIterMut<'_, T> {
406    NodesIdsIterMut { nodes: self.nodes.iter_mut() }
407  }
408
409  /// Iterates over shared references to each node, its position and its identifier.
410  pub fn nodes_pos_ids(&self) -> NodesPosIdsIter<'_, T> {
411    NodesPosIdsIter { nodes: self.nodes.iter() }
412  }
413
414  /// Iterates over mutable references to each node, its position and its identifier.
415  pub fn nodes_pos_ids_mut(&mut self) -> NodesPosIdsIterMut<'_, T> {
416    NodesPosIdsIterMut { nodes: self.nodes.iter_mut() }
417  }
418
419  /// Iterates over shared references to each node data.
420  pub fn nodes_info(&self) -> NodeInfoIter<'_, T> {
421    NodeInfoIter { nodes: self.nodes.iter() }
422  }
423
424  /// Iterates over mutable references to each node data.
425  pub fn nodes_info_mut(&mut self) -> NodeInfoIterMut<'_, T> {
426    NodeInfoIterMut { nodes: self.nodes.iter_mut() }
427  }
428
429  /// Iterates over shared references to each node id and data.
430  pub fn nodes_ids_data(&self) -> NodeIdsDataIter<'_, T> {
431    NodeIdsDataIter { nodes: self.nodes.iter() }
432  }
433
434  /// Iterates over mutable references to each node id and data.
435  pub fn nodes_ids_data_mut(&mut self) -> NodeIdsDataIterMut<'_, T> {
436    NodeIdsDataIterMut { nodes: self.nodes.iter_mut() }
437  }
438
439  /// Iterates over wires.
440  pub fn wires(&self) -> impl Iterator<Item = (OutPinId, InPinId)> + '_ {
441    self.wires.iter().map(|wire| (wire.out_pin, wire.in_pin))
442  }
443
444  /// Returns input pin of the node.
445  #[must_use]
446  pub fn in_pin(&self, pin: InPinId) -> InPin {
447    InPin::new(self, pin)
448  }
449
450  /// Returns output pin of the node.
451  #[must_use]
452  pub fn out_pin(&self, pin: OutPinId) -> OutPin {
453    OutPin::new(self, pin)
454  }
455}
456
457impl<T> Index<NodeId> for Treeize<T> {
458  type Output = T;
459
460  #[inline]
461  #[track_caller]
462  fn index(&self, idx: NodeId) -> &Self::Output {
463    &self.nodes[idx.0].value
464  }
465}
466
467impl<T> IndexMut<NodeId> for Treeize<T> {
468  #[inline]
469  #[track_caller]
470  fn index_mut(&mut self, idx: NodeId) -> &mut Self::Output {
471    &mut self.nodes[idx.0].value
472  }
473}
474
475/// Iterator over shared references to nodes.
476#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
477pub struct NodesIter<'a, T> {
478  nodes: slab::Iter<'a, Node<T>>,
479}
480
481impl<'a, T> Iterator for NodesIter<'a, T> {
482  type Item = &'a T;
483
484  fn size_hint(&self) -> (usize, Option<usize>) {
485    self.nodes.size_hint()
486  }
487
488  fn next(&mut self) -> Option<&'a T> {
489    let (_, node) = self.nodes.next()?;
490    Some(&node.value)
491  }
492
493  fn nth(&mut self, n: usize) -> Option<&'a T> {
494    let (_, node) = self.nodes.nth(n)?;
495    Some(&node.value)
496  }
497}
498
499/// Iterator over mutable references to nodes.
500#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
501pub struct NodesIterMut<'a, T> {
502  nodes: slab::IterMut<'a, Node<T>>,
503}
504
505impl<'a, T> Iterator for NodesIterMut<'a, T> {
506  type Item = &'a mut T;
507
508  fn size_hint(&self) -> (usize, Option<usize>) {
509    self.nodes.size_hint()
510  }
511
512  fn next(&mut self) -> Option<&'a mut T> {
513    let (_, node) = self.nodes.next()?;
514    Some(&mut node.value)
515  }
516
517  fn nth(&mut self, n: usize) -> Option<&'a mut T> {
518    let (_, node) = self.nodes.nth(n)?;
519    Some(&mut node.value)
520  }
521}
522
523/// Iterator over shared references to nodes and their positions.
524#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
525pub struct NodesPosIter<'a, T> {
526  nodes: slab::Iter<'a, Node<T>>,
527}
528
529impl<'a, T> Iterator for NodesPosIter<'a, T> {
530  type Item = (Pos2, &'a T);
531
532  fn size_hint(&self) -> (usize, Option<usize>) {
533    self.nodes.size_hint()
534  }
535
536  fn next(&mut self) -> Option<(Pos2, &'a T)> {
537    let (_, node) = self.nodes.next()?;
538    Some((node.pos, &node.value))
539  }
540
541  fn nth(&mut self, n: usize) -> Option<(Pos2, &'a T)> {
542    let (_, node) = self.nodes.nth(n)?;
543    Some((node.pos, &node.value))
544  }
545}
546
547/// Iterator over mutable references to nodes and their positions.
548#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
549pub struct NodesPosIterMut<'a, T> {
550  nodes: slab::IterMut<'a, Node<T>>,
551}
552
553impl<'a, T> Iterator for NodesPosIterMut<'a, T> {
554  type Item = (Pos2, &'a mut T);
555
556  fn size_hint(&self) -> (usize, Option<usize>) {
557    self.nodes.size_hint()
558  }
559
560  fn next(&mut self) -> Option<(Pos2, &'a mut T)> {
561    let (_, node) = self.nodes.next()?;
562    Some((node.pos, &mut node.value))
563  }
564
565  fn nth(&mut self, n: usize) -> Option<(Pos2, &'a mut T)> {
566    let (_, node) = self.nodes.nth(n)?;
567    Some((node.pos, &mut node.value))
568  }
569}
570
571/// Iterator over shared references to nodes and their identifiers.
572#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
573pub struct NodesIdsIter<'a, T> {
574  nodes: slab::Iter<'a, Node<T>>,
575}
576
577impl<'a, T> Iterator for NodesIdsIter<'a, T> {
578  type Item = (NodeId, &'a T);
579
580  fn size_hint(&self) -> (usize, Option<usize>) {
581    self.nodes.size_hint()
582  }
583
584  fn next(&mut self) -> Option<(NodeId, &'a T)> {
585    let (idx, node) = self.nodes.next()?;
586    Some((NodeId(idx), &node.value))
587  }
588
589  fn nth(&mut self, n: usize) -> Option<(NodeId, &'a T)> {
590    let (idx, node) = self.nodes.nth(n)?;
591    Some((NodeId(idx), &node.value))
592  }
593}
594
595/// Iterator over mutable references to nodes and their identifiers.
596#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
597pub struct NodesIdsIterMut<'a, T> {
598  nodes: slab::IterMut<'a, Node<T>>,
599}
600
601impl<'a, T> Iterator for NodesIdsIterMut<'a, T> {
602  type Item = (NodeId, &'a mut T);
603
604  fn size_hint(&self) -> (usize, Option<usize>) {
605    self.nodes.size_hint()
606  }
607
608  fn next(&mut self) -> Option<(NodeId, &'a mut T)> {
609    let (idx, node) = self.nodes.next()?;
610    Some((NodeId(idx), &mut node.value))
611  }
612
613  fn nth(&mut self, n: usize) -> Option<(NodeId, &'a mut T)> {
614    let (idx, node) = self.nodes.nth(n)?;
615    Some((NodeId(idx), &mut node.value))
616  }
617}
618
619/// Iterator over shared references to nodes, their positions and their identifiers.
620#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
621pub struct NodesPosIdsIter<'a, T> {
622  nodes: slab::Iter<'a, Node<T>>,
623}
624
625impl<'a, T> Iterator for NodesPosIdsIter<'a, T> {
626  type Item = (NodeId, Pos2, &'a T);
627
628  fn size_hint(&self) -> (usize, Option<usize>) {
629    self.nodes.size_hint()
630  }
631
632  fn next(&mut self) -> Option<(NodeId, Pos2, &'a T)> {
633    let (idx, node) = self.nodes.next()?;
634    Some((NodeId(idx), node.pos, &node.value))
635  }
636
637  fn nth(&mut self, n: usize) -> Option<(NodeId, Pos2, &'a T)> {
638    let (idx, node) = self.nodes.nth(n)?;
639    Some((NodeId(idx), node.pos, &node.value))
640  }
641}
642
643/// Iterator over mutable references to nodes, their positions and their identifiers.
644#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
645pub struct NodesPosIdsIterMut<'a, T> {
646  nodes: slab::IterMut<'a, Node<T>>,
647}
648
649impl<'a, T> Iterator for NodesPosIdsIterMut<'a, T> {
650  type Item = (NodeId, Pos2, &'a mut T);
651
652  fn size_hint(&self) -> (usize, Option<usize>) {
653    self.nodes.size_hint()
654  }
655
656  fn next(&mut self) -> Option<(NodeId, Pos2, &'a mut T)> {
657    let (idx, node) = self.nodes.next()?;
658    Some((NodeId(idx), node.pos, &mut node.value))
659  }
660
661  fn nth(&mut self, n: usize) -> Option<(NodeId, Pos2, &'a mut T)> {
662    let (idx, node) = self.nodes.nth(n)?;
663    Some((NodeId(idx), node.pos, &mut node.value))
664  }
665}
666
667/// Iterator over shared references to nodes.
668#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
669pub struct NodeInfoIter<'a, T> {
670  nodes: slab::Iter<'a, Node<T>>,
671}
672
673impl<'a, T> Iterator for NodeInfoIter<'a, T> {
674  type Item = &'a Node<T>;
675
676  fn size_hint(&self) -> (usize, Option<usize>) {
677    self.nodes.size_hint()
678  }
679
680  fn next(&mut self) -> Option<&'a Node<T>> {
681    let (_, node) = self.nodes.next()?;
682    Some(node)
683  }
684
685  fn nth(&mut self, n: usize) -> Option<&'a Node<T>> {
686    let (_, node) = self.nodes.nth(n)?;
687    Some(node)
688  }
689}
690
691/// Iterator over mutable references to nodes.
692#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
693pub struct NodeInfoIterMut<'a, T> {
694  nodes: slab::IterMut<'a, Node<T>>,
695}
696
697impl<'a, T> Iterator for NodeInfoIterMut<'a, T> {
698  type Item = &'a mut Node<T>;
699
700  fn size_hint(&self) -> (usize, Option<usize>) {
701    self.nodes.size_hint()
702  }
703
704  fn next(&mut self) -> Option<&'a mut Node<T>> {
705    let (_, node) = self.nodes.next()?;
706    Some(node)
707  }
708
709  fn nth(&mut self, n: usize) -> Option<&'a mut Node<T>> {
710    let (_, node) = self.nodes.nth(n)?;
711    Some(node)
712  }
713}
714
715/// Iterator over shared references to nodes.
716#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
717pub struct NodeIdsDataIter<'a, T> {
718  nodes: slab::Iter<'a, Node<T>>,
719}
720
721impl<'a, T> Iterator for NodeIdsDataIter<'a, T> {
722  type Item = (NodeId, &'a Node<T>);
723
724  fn size_hint(&self) -> (usize, Option<usize>) {
725    self.nodes.size_hint()
726  }
727
728  fn next(&mut self) -> Option<(NodeId, &'a Node<T>)> {
729    let (id, node) = self.nodes.next()?;
730    Some((NodeId(id), node))
731  }
732
733  fn nth(&mut self, n: usize) -> Option<(NodeId, &'a Node<T>)> {
734    let (id, node) = self.nodes.nth(n)?;
735    Some((NodeId(id), node))
736  }
737}
738
739/// Iterator over mutable references to nodes.
740#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
741pub struct NodeIdsDataIterMut<'a, T> {
742  nodes: slab::IterMut<'a, Node<T>>,
743}
744
745impl<'a, T> Iterator for NodeIdsDataIterMut<'a, T> {
746  type Item = (NodeId, &'a mut Node<T>);
747
748  fn size_hint(&self) -> (usize, Option<usize>) {
749    self.nodes.size_hint()
750  }
751
752  fn next(&mut self) -> Option<(NodeId, &'a mut Node<T>)> {
753    let (id, node) = self.nodes.next()?;
754    Some((NodeId(id), node))
755  }
756
757  fn nth(&mut self, n: usize) -> Option<(NodeId, &'a mut Node<T>)> {
758    let (id, node) = self.nodes.nth(n)?;
759    Some((NodeId(id), node))
760  }
761}
762
763/// Node and its output pin.
764#[derive(Clone, Debug)]
765pub struct OutPin {
766  /// Output pin identifier.
767  pub id: OutPinId,
768
769  /// List of input pins connected to this output pin.
770  pub remotes: Vec<InPinId>,
771}
772
773/// Node and its output pin.
774#[derive(Clone, Debug)]
775pub struct InPin {
776  /// Input pin identifier.
777  pub id: InPinId,
778
779  /// List of output pins connected to this input pin.
780  pub remotes: Vec<OutPinId>,
781}
782
783impl OutPin {
784  fn new<T>(treeize: &Treeize<T>, pin: OutPinId) -> Self {
785    OutPin { id: pin, remotes: treeize.wires.wired_inputs(pin).collect() }
786  }
787}
788
789impl InPin {
790  fn new<T>(treeize: &Treeize<T>, pin: InPinId) -> Self {
791    InPin { id: pin, remotes: treeize.wires.wired_outputs(pin).collect() }
792  }
793}