1#![deny(missing_docs)]
9#![deny(clippy::correctness, clippy::complexity, clippy::perf, clippy::style)]
10#![allow(clippy::inline_always, clippy::use_self)]
12
13pub mod ui;
14
15use std::ops::{Index, IndexMut};
16
17use egui::{ahash::HashSet, Pos2};
18use slab::Slab;
19
20impl<T> Default for Snarl<T> {
21 fn default() -> Self {
22 Snarl::new()
23 }
24}
25
26#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
31#[repr(transparent)]
32#[cfg_attr(
33 feature = "serde",
34 derive(serde::Serialize, serde::Deserialize),
35 serde(transparent)
36)]
37pub struct NodeId(pub usize);
38
39#[derive(Clone, Debug)]
41#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
42#[non_exhaustive]
43pub struct Node<T> {
44 pub value: T,
46
47 pub pos: egui::Pos2,
50
51 pub open: bool,
53}
54
55#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
58#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
59pub struct OutPinId {
60 pub node: NodeId,
62
63 pub output: usize,
65}
66
67#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
69#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
70pub struct InPinId {
71 pub node: NodeId,
73
74 pub input: usize,
76}
77
78#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
84#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
85struct Wire {
86 out_pin: OutPinId,
87 in_pin: InPinId,
88}
89
90#[derive(Clone, Debug)]
91struct Wires {
92 wires: HashSet<Wire>,
93}
94
95#[cfg(feature = "serde")]
96impl serde::Serialize for Wires {
97 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
98 where
99 S: serde::Serializer,
100 {
101 use serde::ser::SerializeSeq;
102
103 let mut seq = serializer.serialize_seq(Some(self.wires.len()))?;
104 for wire in &self.wires {
105 seq.serialize_element(&wire)?;
106 }
107 seq.end()
108 }
109}
110
111#[cfg(feature = "serde")]
112impl<'de> serde::Deserialize<'de> for Wires {
113 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
114 where
115 D: serde::Deserializer<'de>,
116 {
117 struct Visitor;
118
119 impl<'de> serde::de::Visitor<'de> for Visitor {
120 type Value = HashSet<Wire>;
121
122 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
123 formatter.write_str("a sequence of wires")
124 }
125
126 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
127 where
128 A: serde::de::SeqAccess<'de>,
129 {
130 let mut wires = HashSet::with_hasher(egui::ahash::RandomState::new());
131 while let Some(wire) = seq.next_element()? {
132 wires.insert(wire);
133 }
134 Ok(wires)
135 }
136 }
137
138 let wires = deserializer.deserialize_seq(Visitor)?;
139 Ok(Wires { wires })
140 }
141}
142
143impl Wires {
144 fn new() -> Self {
145 Wires {
146 wires: HashSet::with_hasher(egui::ahash::RandomState::new()),
147 }
148 }
149
150 fn insert(&mut self, wire: Wire) -> bool {
151 self.wires.insert(wire)
152 }
153
154 fn remove(&mut self, wire: &Wire) -> bool {
155 self.wires.remove(wire)
156 }
157
158 fn drop_node(&mut self, node: NodeId) -> usize {
159 let count = self.wires.len();
160 self.wires
161 .retain(|wire| wire.out_pin.node != node && wire.in_pin.node != node);
162 count - self.wires.len()
163 }
164
165 fn drop_inputs(&mut self, pin: InPinId) -> usize {
166 let count = self.wires.len();
167 self.wires.retain(|wire| wire.in_pin != pin);
168 count - self.wires.len()
169 }
170
171 fn drop_outputs(&mut self, pin: OutPinId) -> usize {
172 let count = self.wires.len();
173 self.wires.retain(|wire| wire.out_pin != pin);
174 count - self.wires.len()
175 }
176
177 fn wired_inputs(&self, out_pin: OutPinId) -> impl Iterator<Item = InPinId> + '_ {
178 self.wires
179 .iter()
180 .filter(move |wire| wire.out_pin == out_pin)
181 .map(|wire| (wire.in_pin))
182 }
183
184 fn wired_outputs(&self, in_pin: InPinId) -> impl Iterator<Item = OutPinId> + '_ {
185 self.wires
186 .iter()
187 .filter(move |wire| wire.in_pin == in_pin)
188 .map(|wire| (wire.out_pin))
189 }
190
191 fn iter(&self) -> impl Iterator<Item = Wire> + '_ {
192 self.wires.iter().copied()
193 }
194}
195
196#[derive(Clone, Debug)]
201#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
202pub struct Snarl<T> {
203 nodes: Slab<Node<T>>,
205 wires: Wires,
206}
207
208impl<T> Snarl<T> {
209 #[must_use]
218 pub fn new() -> Self {
219 Snarl {
220 nodes: Slab::new(),
221 wires: Wires::new(),
222 }
223 }
224
225 pub fn insert_node(&mut self, pos: egui::Pos2, node: T) -> NodeId {
236 let idx = self.nodes.insert(Node {
237 value: node,
238 pos,
239 open: true,
240 });
241
242 NodeId(idx)
243 }
244
245 pub fn insert_node_collapsed(&mut self, pos: egui::Pos2, node: T) -> NodeId {
256 let idx = self.nodes.insert(Node {
257 value: node,
258 pos,
259 open: false,
260 });
261
262 NodeId(idx)
263 }
264
265 #[track_caller]
271 pub fn open_node(&mut self, node: NodeId, open: bool) {
272 self.nodes[node.0].open = open;
273 }
274
275 #[track_caller]
291 pub fn remove_node(&mut self, idx: NodeId) -> T {
292 let value = self.nodes.remove(idx.0).value;
293 self.wires.drop_node(idx);
294 value
295 }
296
297 #[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 {
310 out_pin: from,
311 in_pin: to,
312 };
313 self.wires.insert(wire)
314 }
315
316 #[track_caller]
323 pub fn disconnect(&mut self, from: OutPinId, to: InPinId) -> bool {
324 assert!(self.nodes.contains(from.node.0));
325 assert!(self.nodes.contains(to.node.0));
326
327 let wire = Wire {
328 out_pin: from,
329 in_pin: to,
330 };
331
332 self.wires.remove(&wire)
333 }
334
335 #[track_caller]
343 pub fn drop_inputs(&mut self, pin: InPinId) -> usize {
344 assert!(self.nodes.contains(pin.node.0));
345 self.wires.drop_inputs(pin)
346 }
347
348 #[track_caller]
355 pub fn drop_outputs(&mut self, pin: OutPinId) -> usize {
356 assert!(self.nodes.contains(pin.node.0));
357 self.wires.drop_outputs(pin)
358 }
359
360 #[must_use]
362 pub fn get_node(&self, idx: NodeId) -> Option<&T> {
363 self.nodes.get(idx.0).map(|node| &node.value)
364 }
365
366 pub fn get_node_mut(&mut self, idx: NodeId) -> Option<&mut T> {
368 match self.nodes.get_mut(idx.0) {
369 Some(node) => Some(&mut node.value),
370 None => None,
371 }
372 }
373
374 #[must_use]
376 pub fn get_node_info(&self, idx: NodeId) -> Option<&Node<T>> {
377 self.nodes.get(idx.0)
378 }
379
380 pub fn get_node_info_mut(&mut self, idx: NodeId) -> Option<&mut Node<T>> {
382 self.nodes.get_mut(idx.0)
383 }
384
385 pub fn nodes(&self) -> NodesIter<'_, T> {
387 NodesIter {
388 nodes: self.nodes.iter(),
389 }
390 }
391
392 pub fn nodes_mut(&mut self) -> NodesIterMut<'_, T> {
394 NodesIterMut {
395 nodes: self.nodes.iter_mut(),
396 }
397 }
398
399 pub fn nodes_pos(&self) -> NodesPosIter<'_, T> {
401 NodesPosIter {
402 nodes: self.nodes.iter(),
403 }
404 }
405
406 pub fn nodes_pos_mut(&mut self) -> NodesPosIterMut<'_, T> {
408 NodesPosIterMut {
409 nodes: self.nodes.iter_mut(),
410 }
411 }
412
413 pub fn node_ids(&self) -> NodesIdsIter<'_, T> {
415 NodesIdsIter {
416 nodes: self.nodes.iter(),
417 }
418 }
419
420 pub fn nodes_ids_mut(&mut self) -> NodesIdsIterMut<'_, T> {
422 NodesIdsIterMut {
423 nodes: self.nodes.iter_mut(),
424 }
425 }
426
427 pub fn nodes_pos_ids(&self) -> NodesPosIdsIter<'_, T> {
429 NodesPosIdsIter {
430 nodes: self.nodes.iter(),
431 }
432 }
433
434 pub fn nodes_pos_ids_mut(&mut self) -> NodesPosIdsIterMut<'_, T> {
436 NodesPosIdsIterMut {
437 nodes: self.nodes.iter_mut(),
438 }
439 }
440
441 pub fn nodes_info(&self) -> NodeInfoIter<'_, T> {
443 NodeInfoIter {
444 nodes: self.nodes.iter(),
445 }
446 }
447
448 pub fn nodes_info_mut(&mut self) -> NodeInfoIterMut<'_, T> {
450 NodeInfoIterMut {
451 nodes: self.nodes.iter_mut(),
452 }
453 }
454
455 pub fn nodes_ids_data(&self) -> NodeIdsDataIter<'_, T> {
457 NodeIdsDataIter {
458 nodes: self.nodes.iter(),
459 }
460 }
461
462 pub fn nodes_ids_data_mut(&mut self) -> NodeIdsDataIterMut<'_, T> {
464 NodeIdsDataIterMut {
465 nodes: self.nodes.iter_mut(),
466 }
467 }
468
469 pub fn wires(&self) -> impl Iterator<Item = (OutPinId, InPinId)> + '_ {
471 self.wires.iter().map(|wire| (wire.out_pin, wire.in_pin))
472 }
473
474 #[must_use]
476 pub fn in_pin(&self, pin: InPinId) -> InPin {
477 InPin::new(self, pin)
478 }
479
480 #[must_use]
482 pub fn out_pin(&self, pin: OutPinId) -> OutPin {
483 OutPin::new(self, pin)
484 }
485}
486
487impl<T> Index<NodeId> for Snarl<T> {
488 type Output = T;
489
490 #[inline]
491 #[track_caller]
492 fn index(&self, idx: NodeId) -> &Self::Output {
493 &self.nodes[idx.0].value
494 }
495}
496
497impl<T> IndexMut<NodeId> for Snarl<T> {
498 #[inline]
499 #[track_caller]
500 fn index_mut(&mut self, idx: NodeId) -> &mut Self::Output {
501 &mut self.nodes[idx.0].value
502 }
503}
504
505#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
507pub struct NodesIter<'a, T> {
508 nodes: slab::Iter<'a, Node<T>>,
509}
510
511impl<'a, T> Iterator for NodesIter<'a, T> {
512 type Item = &'a T;
513
514 fn size_hint(&self) -> (usize, Option<usize>) {
515 self.nodes.size_hint()
516 }
517
518 fn next(&mut self) -> Option<&'a T> {
519 let (_, node) = self.nodes.next()?;
520 Some(&node.value)
521 }
522
523 fn nth(&mut self, n: usize) -> Option<&'a T> {
524 let (_, node) = self.nodes.nth(n)?;
525 Some(&node.value)
526 }
527}
528
529#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
531pub struct NodesIterMut<'a, T> {
532 nodes: slab::IterMut<'a, Node<T>>,
533}
534
535impl<'a, T> Iterator for NodesIterMut<'a, T> {
536 type Item = &'a mut T;
537
538 fn size_hint(&self) -> (usize, Option<usize>) {
539 self.nodes.size_hint()
540 }
541
542 fn next(&mut self) -> Option<&'a mut T> {
543 let (_, node) = self.nodes.next()?;
544 Some(&mut node.value)
545 }
546
547 fn nth(&mut self, n: usize) -> Option<&'a mut T> {
548 let (_, node) = self.nodes.nth(n)?;
549 Some(&mut node.value)
550 }
551}
552
553#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
555pub struct NodesPosIter<'a, T> {
556 nodes: slab::Iter<'a, Node<T>>,
557}
558
559impl<'a, T> Iterator for NodesPosIter<'a, T> {
560 type Item = (Pos2, &'a T);
561
562 fn size_hint(&self) -> (usize, Option<usize>) {
563 self.nodes.size_hint()
564 }
565
566 fn next(&mut self) -> Option<(Pos2, &'a T)> {
567 let (_, node) = self.nodes.next()?;
568 Some((node.pos, &node.value))
569 }
570
571 fn nth(&mut self, n: usize) -> Option<(Pos2, &'a T)> {
572 let (_, node) = self.nodes.nth(n)?;
573 Some((node.pos, &node.value))
574 }
575}
576
577#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
579pub struct NodesPosIterMut<'a, T> {
580 nodes: slab::IterMut<'a, Node<T>>,
581}
582
583impl<'a, T> Iterator for NodesPosIterMut<'a, T> {
584 type Item = (Pos2, &'a mut T);
585
586 fn size_hint(&self) -> (usize, Option<usize>) {
587 self.nodes.size_hint()
588 }
589
590 fn next(&mut self) -> Option<(Pos2, &'a mut T)> {
591 let (_, node) = self.nodes.next()?;
592 Some((node.pos, &mut node.value))
593 }
594
595 fn nth(&mut self, n: usize) -> Option<(Pos2, &'a mut T)> {
596 let (_, node) = self.nodes.nth(n)?;
597 Some((node.pos, &mut node.value))
598 }
599}
600
601#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
603pub struct NodesIdsIter<'a, T> {
604 nodes: slab::Iter<'a, Node<T>>,
605}
606
607impl<'a, T> Iterator for NodesIdsIter<'a, T> {
608 type Item = (NodeId, &'a T);
609
610 fn size_hint(&self) -> (usize, Option<usize>) {
611 self.nodes.size_hint()
612 }
613
614 fn next(&mut self) -> Option<(NodeId, &'a T)> {
615 let (idx, node) = self.nodes.next()?;
616 Some((NodeId(idx), &node.value))
617 }
618
619 fn nth(&mut self, n: usize) -> Option<(NodeId, &'a T)> {
620 let (idx, node) = self.nodes.nth(n)?;
621 Some((NodeId(idx), &node.value))
622 }
623}
624
625#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
627pub struct NodesIdsIterMut<'a, T> {
628 nodes: slab::IterMut<'a, Node<T>>,
629}
630
631impl<'a, T> Iterator for NodesIdsIterMut<'a, T> {
632 type Item = (NodeId, &'a mut T);
633
634 fn size_hint(&self) -> (usize, Option<usize>) {
635 self.nodes.size_hint()
636 }
637
638 fn next(&mut self) -> Option<(NodeId, &'a mut T)> {
639 let (idx, node) = self.nodes.next()?;
640 Some((NodeId(idx), &mut node.value))
641 }
642
643 fn nth(&mut self, n: usize) -> Option<(NodeId, &'a mut T)> {
644 let (idx, node) = self.nodes.nth(n)?;
645 Some((NodeId(idx), &mut node.value))
646 }
647}
648
649#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
651pub struct NodesPosIdsIter<'a, T> {
652 nodes: slab::Iter<'a, Node<T>>,
653}
654
655impl<'a, T> Iterator for NodesPosIdsIter<'a, T> {
656 type Item = (NodeId, Pos2, &'a T);
657
658 fn size_hint(&self) -> (usize, Option<usize>) {
659 self.nodes.size_hint()
660 }
661
662 fn next(&mut self) -> Option<(NodeId, Pos2, &'a T)> {
663 let (idx, node) = self.nodes.next()?;
664 Some((NodeId(idx), node.pos, &node.value))
665 }
666
667 fn nth(&mut self, n: usize) -> Option<(NodeId, Pos2, &'a T)> {
668 let (idx, node) = self.nodes.nth(n)?;
669 Some((NodeId(idx), node.pos, &node.value))
670 }
671}
672
673#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
675pub struct NodesPosIdsIterMut<'a, T> {
676 nodes: slab::IterMut<'a, Node<T>>,
677}
678
679impl<'a, T> Iterator for NodesPosIdsIterMut<'a, T> {
680 type Item = (NodeId, Pos2, &'a mut T);
681
682 fn size_hint(&self) -> (usize, Option<usize>) {
683 self.nodes.size_hint()
684 }
685
686 fn next(&mut self) -> Option<(NodeId, Pos2, &'a mut T)> {
687 let (idx, node) = self.nodes.next()?;
688 Some((NodeId(idx), node.pos, &mut node.value))
689 }
690
691 fn nth(&mut self, n: usize) -> Option<(NodeId, Pos2, &'a mut T)> {
692 let (idx, node) = self.nodes.nth(n)?;
693 Some((NodeId(idx), node.pos, &mut node.value))
694 }
695}
696
697#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
699pub struct NodeInfoIter<'a, T> {
700 nodes: slab::Iter<'a, Node<T>>,
701}
702
703impl<'a, T> Iterator for NodeInfoIter<'a, T> {
704 type Item = &'a Node<T>;
705
706 fn size_hint(&self) -> (usize, Option<usize>) {
707 self.nodes.size_hint()
708 }
709
710 fn next(&mut self) -> Option<&'a Node<T>> {
711 let (_, node) = self.nodes.next()?;
712 Some(node)
713 }
714
715 fn nth(&mut self, n: usize) -> Option<&'a Node<T>> {
716 let (_, node) = self.nodes.nth(n)?;
717 Some(node)
718 }
719}
720
721#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
723pub struct NodeInfoIterMut<'a, T> {
724 nodes: slab::IterMut<'a, Node<T>>,
725}
726
727impl<'a, T> Iterator for NodeInfoIterMut<'a, T> {
728 type Item = &'a mut Node<T>;
729
730 fn size_hint(&self) -> (usize, Option<usize>) {
731 self.nodes.size_hint()
732 }
733
734 fn next(&mut self) -> Option<&'a mut Node<T>> {
735 let (_, node) = self.nodes.next()?;
736 Some(node)
737 }
738
739 fn nth(&mut self, n: usize) -> Option<&'a mut Node<T>> {
740 let (_, node) = self.nodes.nth(n)?;
741 Some(node)
742 }
743}
744
745#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
747pub struct NodeIdsDataIter<'a, T> {
748 nodes: slab::Iter<'a, Node<T>>,
749}
750
751impl<'a, T> Iterator for NodeIdsDataIter<'a, T> {
752 type Item = (NodeId, &'a Node<T>);
753
754 fn size_hint(&self) -> (usize, Option<usize>) {
755 self.nodes.size_hint()
756 }
757
758 fn next(&mut self) -> Option<(NodeId, &'a Node<T>)> {
759 let (id, node) = self.nodes.next()?;
760 Some((NodeId(id), node))
761 }
762
763 fn nth(&mut self, n: usize) -> Option<(NodeId, &'a Node<T>)> {
764 let (id, node) = self.nodes.nth(n)?;
765 Some((NodeId(id), node))
766 }
767}
768
769#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
771pub struct NodeIdsDataIterMut<'a, T> {
772 nodes: slab::IterMut<'a, Node<T>>,
773}
774
775impl<'a, T> Iterator for NodeIdsDataIterMut<'a, T> {
776 type Item = (NodeId, &'a mut Node<T>);
777
778 fn size_hint(&self) -> (usize, Option<usize>) {
779 self.nodes.size_hint()
780 }
781
782 fn next(&mut self) -> Option<(NodeId, &'a mut Node<T>)> {
783 let (id, node) = self.nodes.next()?;
784 Some((NodeId(id), node))
785 }
786
787 fn nth(&mut self, n: usize) -> Option<(NodeId, &'a mut Node<T>)> {
788 let (id, node) = self.nodes.nth(n)?;
789 Some((NodeId(id), node))
790 }
791}
792
793#[derive(Clone, Debug)]
795pub struct OutPin {
796 pub id: OutPinId,
798
799 pub remotes: Vec<InPinId>,
801}
802
803#[derive(Clone, Debug)]
805pub struct InPin {
806 pub id: InPinId,
808
809 pub remotes: Vec<OutPinId>,
811}
812
813impl OutPin {
814 fn new<T>(snarl: &Snarl<T>, pin: OutPinId) -> Self {
815 OutPin {
816 id: pin,
817 remotes: snarl.wires.wired_inputs(pin).collect(),
818 }
819 }
820}
821
822impl InPin {
823 fn new<T>(snarl: &Snarl<T>, pin: InPinId) -> Self {
824 InPin {
825 id: pin,
826 remotes: snarl.wires.wired_outputs(pin).collect(),
827 }
828 }
829}