1#![deny(missing_docs, non_ascii_idents, unsafe_code)]
9#![deny(
10 clippy::correctness,
11 clippy::complexity,
12 clippy::perf,
13 clippy::style,
14 clippy::suspicious
15)]
16#![warn(clippy::pedantic, clippy::dbg_macro, clippy::must_use_candidate)]
17#![allow(clippy::range_plus_one, clippy::inline_always, clippy::use_self)]
18
19pub mod ui;
20
21use std::ops::{Index, IndexMut};
22
23use ahash::HashSet;
24use egui::Pos2;
25use slab::Slab;
26
27impl<T> Default for Snarl<T> {
28 fn default() -> Self {
29 Snarl::new()
30 }
31}
32
33#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
38#[repr(transparent)]
39#[cfg_attr(
40 feature = "serde",
41 derive(serde::Serialize, serde::Deserialize),
42 serde(transparent)
43)]
44pub struct NodeId(pub usize);
45
46#[derive(Clone, Debug)]
48#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
49#[non_exhaustive]
50pub struct Node<T> {
51 pub value: T,
53
54 pub pos: egui::Pos2,
57
58 pub open: bool,
60}
61
62#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
65#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
66pub struct OutPinId {
67 pub node: NodeId,
69
70 pub output: usize,
72}
73
74#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
76#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
77pub struct InPinId {
78 pub node: NodeId,
80
81 pub input: usize,
83}
84
85#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
91#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
92struct Wire {
93 out_pin: OutPinId,
94 in_pin: InPinId,
95}
96
97#[derive(Clone, Debug)]
98struct Wires {
99 wires: HashSet<Wire>,
100}
101
102#[cfg(feature = "serde")]
103impl serde::Serialize for Wires {
104 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
105 where
106 S: serde::Serializer,
107 {
108 use serde::ser::SerializeSeq;
109
110 let mut seq = serializer.serialize_seq(Some(self.wires.len()))?;
111 for wire in &self.wires {
112 seq.serialize_element(&wire)?;
113 }
114 seq.end()
115 }
116}
117
118#[cfg(feature = "serde")]
119impl<'de> serde::Deserialize<'de> for Wires {
120 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
121 where
122 D: serde::Deserializer<'de>,
123 {
124 struct Visitor;
125
126 impl<'de> serde::de::Visitor<'de> for Visitor {
127 type Value = HashSet<Wire>;
128
129 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
130 formatter.write_str("a sequence of wires")
131 }
132
133 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
134 where
135 A: serde::de::SeqAccess<'de>,
136 {
137 let mut wires = HashSet::with_hasher(ahash::RandomState::new());
138 while let Some(wire) = seq.next_element()? {
139 wires.insert(wire);
140 }
141 Ok(wires)
142 }
143 }
144
145 let wires = deserializer.deserialize_seq(Visitor)?;
146 Ok(Wires { wires })
147 }
148}
149
150impl Wires {
151 fn new() -> Self {
152 Wires {
153 wires: HashSet::with_hasher(ahash::RandomState::new()),
154 }
155 }
156
157 fn insert(&mut self, wire: Wire) -> bool {
158 self.wires.insert(wire)
159 }
160
161 fn remove(&mut self, wire: &Wire) -> bool {
162 self.wires.remove(wire)
163 }
164
165 fn drop_node(&mut self, node: NodeId) -> usize {
166 let count = self.wires.len();
167 self.wires
168 .retain(|wire| wire.out_pin.node != node && wire.in_pin.node != node);
169 count - self.wires.len()
170 }
171
172 fn drop_inputs(&mut self, pin: InPinId) -> usize {
173 let count = self.wires.len();
174 self.wires.retain(|wire| wire.in_pin != pin);
175 count - self.wires.len()
176 }
177
178 fn drop_outputs(&mut self, pin: OutPinId) -> usize {
179 let count = self.wires.len();
180 self.wires.retain(|wire| wire.out_pin != pin);
181 count - self.wires.len()
182 }
183
184 fn wired_inputs(&self, out_pin: OutPinId) -> impl Iterator<Item = InPinId> + '_ {
185 self.wires
186 .iter()
187 .filter(move |wire| wire.out_pin == out_pin)
188 .map(|wire| wire.in_pin)
189 }
190
191 fn wired_outputs(&self, in_pin: InPinId) -> impl Iterator<Item = OutPinId> + '_ {
192 self.wires
193 .iter()
194 .filter(move |wire| wire.in_pin == in_pin)
195 .map(|wire| wire.out_pin)
196 }
197
198 fn iter(&self) -> impl Iterator<Item = Wire> + '_ {
199 self.wires.iter().copied()
200 }
201}
202
203#[derive(Clone, Debug)]
208#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
209pub struct Snarl<T> {
210 nodes: Slab<Node<T>>,
212 wires: Wires,
213}
214
215impl<T> Snarl<T> {
216 #[must_use]
225 pub fn new() -> Self {
226 Snarl {
227 nodes: Slab::new(),
228 wires: Wires::new(),
229 }
230 }
231
232 pub fn insert_node(&mut self, pos: egui::Pos2, node: T) -> NodeId {
243 let idx = self.nodes.insert(Node {
244 value: node,
245 pos,
246 open: true,
247 });
248
249 NodeId(idx)
250 }
251
252 pub fn insert_node_collapsed(&mut self, pos: egui::Pos2, node: T) -> NodeId {
263 let idx = self.nodes.insert(Node {
264 value: node,
265 pos,
266 open: false,
267 });
268
269 NodeId(idx)
270 }
271
272 #[track_caller]
278 pub fn open_node(&mut self, node: NodeId, open: bool) {
279 self.nodes[node.0].open = open;
280 }
281
282 #[track_caller]
298 pub fn remove_node(&mut self, idx: NodeId) -> T {
299 let value = self.nodes.remove(idx.0).value;
300 self.wires.drop_node(idx);
301 value
302 }
303
304 #[track_caller]
312 pub fn connect(&mut self, from: OutPinId, to: InPinId) -> bool {
313 assert!(self.nodes.contains(from.node.0));
314 assert!(self.nodes.contains(to.node.0));
315
316 let wire = Wire {
317 out_pin: from,
318 in_pin: to,
319 };
320 self.wires.insert(wire)
321 }
322
323 #[track_caller]
330 pub fn disconnect(&mut self, from: OutPinId, to: InPinId) -> bool {
331 assert!(self.nodes.contains(from.node.0));
332 assert!(self.nodes.contains(to.node.0));
333
334 let wire = Wire {
335 out_pin: from,
336 in_pin: to,
337 };
338
339 self.wires.remove(&wire)
340 }
341
342 #[track_caller]
350 pub fn drop_inputs(&mut self, pin: InPinId) -> usize {
351 assert!(self.nodes.contains(pin.node.0));
352 self.wires.drop_inputs(pin)
353 }
354
355 #[track_caller]
362 pub fn drop_outputs(&mut self, pin: OutPinId) -> usize {
363 assert!(self.nodes.contains(pin.node.0));
364 self.wires.drop_outputs(pin)
365 }
366
367 #[must_use]
369 pub fn get_node(&self, idx: NodeId) -> Option<&T> {
370 self.nodes.get(idx.0).map(|node| &node.value)
371 }
372
373 pub fn get_node_mut(&mut self, idx: NodeId) -> Option<&mut T> {
375 match self.nodes.get_mut(idx.0) {
376 Some(node) => Some(&mut node.value),
377 None => None,
378 }
379 }
380
381 #[must_use]
383 pub fn get_node_info(&self, idx: NodeId) -> Option<&Node<T>> {
384 self.nodes.get(idx.0)
385 }
386
387 pub fn get_node_info_mut(&mut self, idx: NodeId) -> Option<&mut Node<T>> {
389 self.nodes.get_mut(idx.0)
390 }
391
392 pub fn nodes(&self) -> NodesIter<'_, T> {
394 NodesIter {
395 nodes: self.nodes.iter(),
396 }
397 }
398
399 pub fn nodes_mut(&mut self) -> NodesIterMut<'_, T> {
401 NodesIterMut {
402 nodes: self.nodes.iter_mut(),
403 }
404 }
405
406 pub fn nodes_pos(&self) -> NodesPosIter<'_, T> {
408 NodesPosIter {
409 nodes: self.nodes.iter(),
410 }
411 }
412
413 pub fn nodes_pos_mut(&mut self) -> NodesPosIterMut<'_, T> {
415 NodesPosIterMut {
416 nodes: self.nodes.iter_mut(),
417 }
418 }
419
420 pub fn node_ids(&self) -> NodesIdsIter<'_, T> {
422 NodesIdsIter {
423 nodes: self.nodes.iter(),
424 }
425 }
426
427 pub fn nodes_ids_mut(&mut self) -> NodesIdsIterMut<'_, T> {
429 NodesIdsIterMut {
430 nodes: self.nodes.iter_mut(),
431 }
432 }
433
434 pub fn nodes_pos_ids(&self) -> NodesPosIdsIter<'_, T> {
436 NodesPosIdsIter {
437 nodes: self.nodes.iter(),
438 }
439 }
440
441 pub fn nodes_pos_ids_mut(&mut self) -> NodesPosIdsIterMut<'_, T> {
443 NodesPosIdsIterMut {
444 nodes: self.nodes.iter_mut(),
445 }
446 }
447
448 pub fn nodes_info(&self) -> NodeInfoIter<'_, T> {
450 NodeInfoIter {
451 nodes: self.nodes.iter(),
452 }
453 }
454
455 pub fn nodes_info_mut(&mut self) -> NodeInfoIterMut<'_, T> {
457 NodeInfoIterMut {
458 nodes: self.nodes.iter_mut(),
459 }
460 }
461
462 pub fn nodes_ids_data(&self) -> NodeIdsDataIter<'_, T> {
464 NodeIdsDataIter {
465 nodes: self.nodes.iter(),
466 }
467 }
468
469 pub fn nodes_ids_data_mut(&mut self) -> NodeIdsDataIterMut<'_, T> {
471 NodeIdsDataIterMut {
472 nodes: self.nodes.iter_mut(),
473 }
474 }
475
476 pub fn wires(&self) -> impl Iterator<Item = (OutPinId, InPinId)> + '_ {
478 self.wires.iter().map(|wire| (wire.out_pin, wire.in_pin))
479 }
480
481 #[must_use]
483 pub fn in_pin(&self, pin: InPinId) -> InPin {
484 InPin::new(self, pin)
485 }
486
487 #[must_use]
489 pub fn out_pin(&self, pin: OutPinId) -> OutPin {
490 OutPin::new(self, pin)
491 }
492}
493
494impl<T> Index<NodeId> for Snarl<T> {
495 type Output = T;
496
497 #[inline]
498 #[track_caller]
499 fn index(&self, idx: NodeId) -> &Self::Output {
500 &self.nodes[idx.0].value
501 }
502}
503
504impl<T> IndexMut<NodeId> for Snarl<T> {
505 #[inline]
506 #[track_caller]
507 fn index_mut(&mut self, idx: NodeId) -> &mut Self::Output {
508 &mut self.nodes[idx.0].value
509 }
510}
511
512#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
514pub struct NodesIter<'a, T> {
515 nodes: slab::Iter<'a, Node<T>>,
516}
517
518impl<'a, T> Iterator for NodesIter<'a, T> {
519 type Item = &'a T;
520
521 fn size_hint(&self) -> (usize, Option<usize>) {
522 self.nodes.size_hint()
523 }
524
525 fn next(&mut self) -> Option<&'a T> {
526 let (_, node) = self.nodes.next()?;
527 Some(&node.value)
528 }
529
530 fn nth(&mut self, n: usize) -> Option<&'a T> {
531 let (_, node) = self.nodes.nth(n)?;
532 Some(&node.value)
533 }
534}
535
536#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
538pub struct NodesIterMut<'a, T> {
539 nodes: slab::IterMut<'a, Node<T>>,
540}
541
542impl<'a, T> Iterator for NodesIterMut<'a, T> {
543 type Item = &'a mut T;
544
545 fn size_hint(&self) -> (usize, Option<usize>) {
546 self.nodes.size_hint()
547 }
548
549 fn next(&mut self) -> Option<&'a mut T> {
550 let (_, node) = self.nodes.next()?;
551 Some(&mut node.value)
552 }
553
554 fn nth(&mut self, n: usize) -> Option<&'a mut T> {
555 let (_, node) = self.nodes.nth(n)?;
556 Some(&mut node.value)
557 }
558}
559
560#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
562pub struct NodesPosIter<'a, T> {
563 nodes: slab::Iter<'a, Node<T>>,
564}
565
566impl<'a, T> Iterator for NodesPosIter<'a, T> {
567 type Item = (Pos2, &'a T);
568
569 fn size_hint(&self) -> (usize, Option<usize>) {
570 self.nodes.size_hint()
571 }
572
573 fn next(&mut self) -> Option<(Pos2, &'a T)> {
574 let (_, node) = self.nodes.next()?;
575 Some((node.pos, &node.value))
576 }
577
578 fn nth(&mut self, n: usize) -> Option<(Pos2, &'a T)> {
579 let (_, node) = self.nodes.nth(n)?;
580 Some((node.pos, &node.value))
581 }
582}
583
584#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
586pub struct NodesPosIterMut<'a, T> {
587 nodes: slab::IterMut<'a, Node<T>>,
588}
589
590impl<'a, T> Iterator for NodesPosIterMut<'a, T> {
591 type Item = (Pos2, &'a mut T);
592
593 fn size_hint(&self) -> (usize, Option<usize>) {
594 self.nodes.size_hint()
595 }
596
597 fn next(&mut self) -> Option<(Pos2, &'a mut T)> {
598 let (_, node) = self.nodes.next()?;
599 Some((node.pos, &mut node.value))
600 }
601
602 fn nth(&mut self, n: usize) -> Option<(Pos2, &'a mut T)> {
603 let (_, node) = self.nodes.nth(n)?;
604 Some((node.pos, &mut node.value))
605 }
606}
607
608#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
610pub struct NodesIdsIter<'a, T> {
611 nodes: slab::Iter<'a, Node<T>>,
612}
613
614impl<'a, T> Iterator for NodesIdsIter<'a, T> {
615 type Item = (NodeId, &'a T);
616
617 fn size_hint(&self) -> (usize, Option<usize>) {
618 self.nodes.size_hint()
619 }
620
621 fn next(&mut self) -> Option<(NodeId, &'a T)> {
622 let (idx, node) = self.nodes.next()?;
623 Some((NodeId(idx), &node.value))
624 }
625
626 fn nth(&mut self, n: usize) -> Option<(NodeId, &'a T)> {
627 let (idx, node) = self.nodes.nth(n)?;
628 Some((NodeId(idx), &node.value))
629 }
630}
631
632#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
634pub struct NodesIdsIterMut<'a, T> {
635 nodes: slab::IterMut<'a, Node<T>>,
636}
637
638impl<'a, T> Iterator for NodesIdsIterMut<'a, T> {
639 type Item = (NodeId, &'a mut T);
640
641 fn size_hint(&self) -> (usize, Option<usize>) {
642 self.nodes.size_hint()
643 }
644
645 fn next(&mut self) -> Option<(NodeId, &'a mut T)> {
646 let (idx, node) = self.nodes.next()?;
647 Some((NodeId(idx), &mut node.value))
648 }
649
650 fn nth(&mut self, n: usize) -> Option<(NodeId, &'a mut T)> {
651 let (idx, node) = self.nodes.nth(n)?;
652 Some((NodeId(idx), &mut node.value))
653 }
654}
655
656#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
658pub struct NodesPosIdsIter<'a, T> {
659 nodes: slab::Iter<'a, Node<T>>,
660}
661
662impl<'a, T> Iterator for NodesPosIdsIter<'a, T> {
663 type Item = (NodeId, Pos2, &'a T);
664
665 fn size_hint(&self) -> (usize, Option<usize>) {
666 self.nodes.size_hint()
667 }
668
669 fn next(&mut self) -> Option<(NodeId, Pos2, &'a T)> {
670 let (idx, node) = self.nodes.next()?;
671 Some((NodeId(idx), node.pos, &node.value))
672 }
673
674 fn nth(&mut self, n: usize) -> Option<(NodeId, Pos2, &'a T)> {
675 let (idx, node) = self.nodes.nth(n)?;
676 Some((NodeId(idx), node.pos, &node.value))
677 }
678}
679
680#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
682pub struct NodesPosIdsIterMut<'a, T> {
683 nodes: slab::IterMut<'a, Node<T>>,
684}
685
686impl<'a, T> Iterator for NodesPosIdsIterMut<'a, T> {
687 type Item = (NodeId, Pos2, &'a mut T);
688
689 fn size_hint(&self) -> (usize, Option<usize>) {
690 self.nodes.size_hint()
691 }
692
693 fn next(&mut self) -> Option<(NodeId, Pos2, &'a mut T)> {
694 let (idx, node) = self.nodes.next()?;
695 Some((NodeId(idx), node.pos, &mut node.value))
696 }
697
698 fn nth(&mut self, n: usize) -> Option<(NodeId, Pos2, &'a mut T)> {
699 let (idx, node) = self.nodes.nth(n)?;
700 Some((NodeId(idx), node.pos, &mut node.value))
701 }
702}
703
704#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
706pub struct NodeInfoIter<'a, T> {
707 nodes: slab::Iter<'a, Node<T>>,
708}
709
710impl<'a, T> Iterator for NodeInfoIter<'a, T> {
711 type Item = &'a Node<T>;
712
713 fn size_hint(&self) -> (usize, Option<usize>) {
714 self.nodes.size_hint()
715 }
716
717 fn next(&mut self) -> Option<&'a Node<T>> {
718 let (_, node) = self.nodes.next()?;
719 Some(node)
720 }
721
722 fn nth(&mut self, n: usize) -> Option<&'a Node<T>> {
723 let (_, node) = self.nodes.nth(n)?;
724 Some(node)
725 }
726}
727
728#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
730pub struct NodeInfoIterMut<'a, T> {
731 nodes: slab::IterMut<'a, Node<T>>,
732}
733
734impl<'a, T> Iterator for NodeInfoIterMut<'a, T> {
735 type Item = &'a mut Node<T>;
736
737 fn size_hint(&self) -> (usize, Option<usize>) {
738 self.nodes.size_hint()
739 }
740
741 fn next(&mut self) -> Option<&'a mut Node<T>> {
742 let (_, node) = self.nodes.next()?;
743 Some(node)
744 }
745
746 fn nth(&mut self, n: usize) -> Option<&'a mut Node<T>> {
747 let (_, node) = self.nodes.nth(n)?;
748 Some(node)
749 }
750}
751
752#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
754pub struct NodeIdsDataIter<'a, T> {
755 nodes: slab::Iter<'a, Node<T>>,
756}
757
758impl<'a, T> Iterator for NodeIdsDataIter<'a, T> {
759 type Item = (NodeId, &'a Node<T>);
760
761 fn size_hint(&self) -> (usize, Option<usize>) {
762 self.nodes.size_hint()
763 }
764
765 fn next(&mut self) -> Option<(NodeId, &'a Node<T>)> {
766 let (id, node) = self.nodes.next()?;
767 Some((NodeId(id), node))
768 }
769
770 fn nth(&mut self, n: usize) -> Option<(NodeId, &'a Node<T>)> {
771 let (id, node) = self.nodes.nth(n)?;
772 Some((NodeId(id), node))
773 }
774}
775
776#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
778pub struct NodeIdsDataIterMut<'a, T> {
779 nodes: slab::IterMut<'a, Node<T>>,
780}
781
782impl<'a, T> Iterator for NodeIdsDataIterMut<'a, T> {
783 type Item = (NodeId, &'a mut Node<T>);
784
785 fn size_hint(&self) -> (usize, Option<usize>) {
786 self.nodes.size_hint()
787 }
788
789 fn next(&mut self) -> Option<(NodeId, &'a mut Node<T>)> {
790 let (id, node) = self.nodes.next()?;
791 Some((NodeId(id), node))
792 }
793
794 fn nth(&mut self, n: usize) -> Option<(NodeId, &'a mut Node<T>)> {
795 let (id, node) = self.nodes.nth(n)?;
796 Some((NodeId(id), node))
797 }
798}
799
800#[derive(Clone, Debug)]
802pub struct OutPin {
803 pub id: OutPinId,
805
806 pub remotes: Vec<InPinId>,
808}
809
810#[derive(Clone, Debug)]
812pub struct InPin {
813 pub id: InPinId,
815
816 pub remotes: Vec<OutPinId>,
818}
819
820impl OutPin {
821 fn new<T>(snarl: &Snarl<T>, pin: OutPinId) -> Self {
822 OutPin {
823 id: pin,
824 remotes: snarl.wires.wired_inputs(pin).collect(),
825 }
826 }
827}
828
829impl InPin {
830 fn new<T>(snarl: &Snarl<T>, pin: InPinId) -> Self {
831 InPin {
832 id: pin,
833 remotes: snarl.wires.wired_outputs(pin).collect(),
834 }
835 }
836}