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