1#![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 ui;
13
14use std::ops::{Index, IndexMut};
15
16use egui::{Pos2, ahash::HashSet};
17use slab::Slab;
18
19impl<T> Default for Snarl<T> {
20 fn default() -> Self {
21 Snarl::new()
22 }
23}
24
25#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
30#[repr(transparent)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(transparent))]
32pub struct NodeId(pub usize);
33
34#[derive(Clone, Debug)]
36#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
37#[non_exhaustive]
38pub struct Node<T> {
39 pub value: T,
41
42 pub pos: egui::Pos2,
45
46 pub open: bool,
48}
49
50#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
53#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
54pub struct OutPinId {
55 pub node: NodeId,
57
58 pub output: usize,
60}
61
62#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
64#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
65pub struct InPinId {
66 pub node: NodeId,
68
69 pub input: usize,
71}
72
73#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
79#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
80struct Wire {
81 out_pin: OutPinId,
82 in_pin: InPinId,
83}
84
85#[derive(Clone, Debug)]
86struct Wires {
87 wires: HashSet<Wire>,
88}
89
90#[cfg(feature = "serde")]
91impl serde::Serialize for Wires {
92 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
93 where
94 S: serde::Serializer,
95 {
96 use serde::ser::SerializeSeq;
97
98 let mut seq = serializer.serialize_seq(Some(self.wires.len()))?;
99 for wire in &self.wires {
100 seq.serialize_element(&wire)?;
101 }
102 seq.end()
103 }
104}
105
106#[cfg(feature = "serde")]
107impl<'de> serde::Deserialize<'de> for Wires {
108 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
109 where
110 D: serde::Deserializer<'de>,
111 {
112 struct Visitor;
113
114 impl<'de> serde::de::Visitor<'de> for Visitor {
115 type Value = HashSet<Wire>;
116
117 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
118 formatter.write_str("a sequence of wires")
119 }
120
121 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
122 where
123 A: serde::de::SeqAccess<'de>,
124 {
125 let mut wires = HashSet::with_hasher(egui::ahash::RandomState::new());
126 while let Some(wire) = seq.next_element()? {
127 wires.insert(wire);
128 }
129 Ok(wires)
130 }
131 }
132
133 let wires = deserializer.deserialize_seq(Visitor)?;
134 Ok(Wires { wires })
135 }
136}
137
138impl Wires {
139 fn new() -> Self {
140 Wires { wires: HashSet::with_hasher(egui::ahash::RandomState::new()) }
141 }
142
143 fn insert(&mut self, wire: Wire) -> bool {
144 self.wires.insert(wire)
145 }
146
147 fn remove(&mut self, wire: &Wire) -> bool {
148 self.wires.remove(wire)
149 }
150
151 fn drop_node(&mut self, node: NodeId) -> usize {
152 let count = self.wires.len();
153 self.wires.retain(|wire| wire.out_pin.node != node && wire.in_pin.node != node);
154 count - self.wires.len()
155 }
156
157 fn drop_inputs(&mut self, pin: InPinId) -> usize {
158 let count = self.wires.len();
159 self.wires.retain(|wire| wire.in_pin != pin);
160 count - self.wires.len()
161 }
162
163 fn drop_outputs(&mut self, pin: OutPinId) -> usize {
164 let count = self.wires.len();
165 self.wires.retain(|wire| wire.out_pin != pin);
166 count - self.wires.len()
167 }
168
169 fn wired_inputs(&self, out_pin: OutPinId) -> impl Iterator<Item = InPinId> + '_ {
170 self.wires.iter().filter(move |wire| wire.out_pin == out_pin).map(|wire| wire.in_pin)
171 }
172
173 fn wired_outputs(&self, in_pin: InPinId) -> impl Iterator<Item = OutPinId> + '_ {
174 self.wires.iter().filter(move |wire| wire.in_pin == in_pin).map(|wire| wire.out_pin)
175 }
176
177 fn iter(&self) -> impl Iterator<Item = Wire> + '_ {
178 self.wires.iter().copied()
179 }
180}
181
182#[derive(Clone, Debug)]
187#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
188pub struct Snarl<T> {
189 nodes: Slab<Node<T>>,
191 wires: Wires,
192}
193
194impl<T> Snarl<T> {
195 #[must_use]
204 pub fn new() -> Self {
205 Snarl { nodes: Slab::new(), wires: Wires::new() }
206 }
207
208 pub fn insert_node(&mut self, pos: egui::Pos2, node: T) -> NodeId {
219 let idx = self.nodes.insert(Node { value: node, pos, open: true });
220
221 NodeId(idx)
222 }
223
224 pub fn insert_node_collapsed(&mut self, pos: egui::Pos2, node: T) -> NodeId {
235 let idx = self.nodes.insert(Node { value: node, pos, open: false });
236
237 NodeId(idx)
238 }
239
240 #[track_caller]
246 pub fn open_node(&mut self, node: NodeId, open: bool) {
247 self.nodes[node.0].open = open;
248 }
249
250 #[track_caller]
266 pub fn remove_node(&mut self, idx: NodeId) -> T {
267 let value = self.nodes.remove(idx.0).value;
268 self.wires.drop_node(idx);
269 value
270 }
271
272 #[track_caller]
280 pub fn connect(&mut self, from: OutPinId, to: InPinId) -> bool {
281 assert!(self.nodes.contains(from.node.0));
282 assert!(self.nodes.contains(to.node.0));
283
284 let wire = Wire { out_pin: from, in_pin: to };
285 self.wires.insert(wire)
286 }
287
288 #[track_caller]
295 pub fn disconnect(&mut self, from: OutPinId, to: InPinId) -> bool {
296 assert!(self.nodes.contains(from.node.0));
297 assert!(self.nodes.contains(to.node.0));
298
299 let wire = Wire { out_pin: from, in_pin: to };
300
301 self.wires.remove(&wire)
302 }
303
304 #[track_caller]
312 pub fn drop_inputs(&mut self, pin: InPinId) -> usize {
313 assert!(self.nodes.contains(pin.node.0));
314 self.wires.drop_inputs(pin)
315 }
316
317 #[track_caller]
324 pub fn drop_outputs(&mut self, pin: OutPinId) -> usize {
325 assert!(self.nodes.contains(pin.node.0));
326 self.wires.drop_outputs(pin)
327 }
328
329 #[must_use]
331 pub fn get_node(&self, idx: NodeId) -> Option<&T> {
332 self.nodes.get(idx.0).map(|node| &node.value)
333 }
334
335 pub fn get_node_mut(&mut self, idx: NodeId) -> Option<&mut T> {
337 match self.nodes.get_mut(idx.0) {
338 Some(node) => Some(&mut node.value),
339 None => None,
340 }
341 }
342
343 #[must_use]
345 pub fn get_node_info(&self, idx: NodeId) -> Option<&Node<T>> {
346 self.nodes.get(idx.0)
347 }
348
349 pub fn get_node_info_mut(&mut self, idx: NodeId) -> Option<&mut Node<T>> {
351 self.nodes.get_mut(idx.0)
352 }
353
354 pub fn nodes(&self) -> NodesIter<'_, T> {
356 NodesIter { nodes: self.nodes.iter() }
357 }
358
359 pub fn nodes_mut(&mut self) -> NodesIterMut<'_, T> {
361 NodesIterMut { nodes: self.nodes.iter_mut() }
362 }
363
364 pub fn nodes_pos(&self) -> NodesPosIter<'_, T> {
366 NodesPosIter { nodes: self.nodes.iter() }
367 }
368
369 pub fn nodes_pos_mut(&mut self) -> NodesPosIterMut<'_, T> {
371 NodesPosIterMut { nodes: self.nodes.iter_mut() }
372 }
373
374 pub fn node_ids(&self) -> NodesIdsIter<'_, T> {
376 NodesIdsIter { nodes: self.nodes.iter() }
377 }
378
379 pub fn nodes_ids_mut(&mut self) -> NodesIdsIterMut<'_, T> {
381 NodesIdsIterMut { nodes: self.nodes.iter_mut() }
382 }
383
384 pub fn nodes_pos_ids(&self) -> NodesPosIdsIter<'_, T> {
386 NodesPosIdsIter { nodes: self.nodes.iter() }
387 }
388
389 pub fn nodes_pos_ids_mut(&mut self) -> NodesPosIdsIterMut<'_, T> {
391 NodesPosIdsIterMut { nodes: self.nodes.iter_mut() }
392 }
393
394 pub fn nodes_info(&self) -> NodeInfoIter<'_, T> {
396 NodeInfoIter { nodes: self.nodes.iter() }
397 }
398
399 pub fn nodes_info_mut(&mut self) -> NodeInfoIterMut<'_, T> {
401 NodeInfoIterMut { nodes: self.nodes.iter_mut() }
402 }
403
404 pub fn nodes_ids_data(&self) -> NodeIdsDataIter<'_, T> {
406 NodeIdsDataIter { nodes: self.nodes.iter() }
407 }
408
409 pub fn nodes_ids_data_mut(&mut self) -> NodeIdsDataIterMut<'_, T> {
411 NodeIdsDataIterMut { nodes: self.nodes.iter_mut() }
412 }
413
414 pub fn wires(&self) -> impl Iterator<Item = (OutPinId, InPinId)> + '_ {
416 self.wires.iter().map(|wire| (wire.out_pin, wire.in_pin))
417 }
418
419 #[must_use]
421 pub fn in_pin(&self, pin: InPinId) -> InPin {
422 InPin::new(self, pin)
423 }
424
425 #[must_use]
427 pub fn out_pin(&self, pin: OutPinId) -> OutPin {
428 OutPin::new(self, pin)
429 }
430}
431
432impl<T> Index<NodeId> for Snarl<T> {
433 type Output = T;
434
435 #[inline]
436 #[track_caller]
437 fn index(&self, idx: NodeId) -> &Self::Output {
438 &self.nodes[idx.0].value
439 }
440}
441
442impl<T> IndexMut<NodeId> for Snarl<T> {
443 #[inline]
444 #[track_caller]
445 fn index_mut(&mut self, idx: NodeId) -> &mut Self::Output {
446 &mut self.nodes[idx.0].value
447 }
448}
449
450#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
452pub struct NodesIter<'a, T> {
453 nodes: slab::Iter<'a, Node<T>>,
454}
455
456impl<'a, T> Iterator for NodesIter<'a, T> {
457 type Item = &'a T;
458
459 fn size_hint(&self) -> (usize, Option<usize>) {
460 self.nodes.size_hint()
461 }
462
463 fn next(&mut self) -> Option<&'a T> {
464 let (_, node) = self.nodes.next()?;
465 Some(&node.value)
466 }
467
468 fn nth(&mut self, n: usize) -> Option<&'a T> {
469 let (_, node) = self.nodes.nth(n)?;
470 Some(&node.value)
471 }
472}
473
474#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
476pub struct NodesIterMut<'a, T> {
477 nodes: slab::IterMut<'a, Node<T>>,
478}
479
480impl<'a, T> Iterator for NodesIterMut<'a, T> {
481 type Item = &'a mut T;
482
483 fn size_hint(&self) -> (usize, Option<usize>) {
484 self.nodes.size_hint()
485 }
486
487 fn next(&mut self) -> Option<&'a mut T> {
488 let (_, node) = self.nodes.next()?;
489 Some(&mut node.value)
490 }
491
492 fn nth(&mut self, n: usize) -> Option<&'a mut T> {
493 let (_, node) = self.nodes.nth(n)?;
494 Some(&mut node.value)
495 }
496}
497
498#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
500pub struct NodesPosIter<'a, T> {
501 nodes: slab::Iter<'a, Node<T>>,
502}
503
504impl<'a, T> Iterator for NodesPosIter<'a, T> {
505 type Item = (Pos2, &'a T);
506
507 fn size_hint(&self) -> (usize, Option<usize>) {
508 self.nodes.size_hint()
509 }
510
511 fn next(&mut self) -> Option<(Pos2, &'a T)> {
512 let (_, node) = self.nodes.next()?;
513 Some((node.pos, &node.value))
514 }
515
516 fn nth(&mut self, n: usize) -> Option<(Pos2, &'a T)> {
517 let (_, node) = self.nodes.nth(n)?;
518 Some((node.pos, &node.value))
519 }
520}
521
522#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
524pub struct NodesPosIterMut<'a, T> {
525 nodes: slab::IterMut<'a, Node<T>>,
526}
527
528impl<'a, T> Iterator for NodesPosIterMut<'a, T> {
529 type Item = (Pos2, &'a mut T);
530
531 fn size_hint(&self) -> (usize, Option<usize>) {
532 self.nodes.size_hint()
533 }
534
535 fn next(&mut self) -> Option<(Pos2, &'a mut T)> {
536 let (_, node) = self.nodes.next()?;
537 Some((node.pos, &mut node.value))
538 }
539
540 fn nth(&mut self, n: usize) -> Option<(Pos2, &'a mut T)> {
541 let (_, node) = self.nodes.nth(n)?;
542 Some((node.pos, &mut node.value))
543 }
544}
545
546#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
548pub struct NodesIdsIter<'a, T> {
549 nodes: slab::Iter<'a, Node<T>>,
550}
551
552impl<'a, T> Iterator for NodesIdsIter<'a, T> {
553 type Item = (NodeId, &'a T);
554
555 fn size_hint(&self) -> (usize, Option<usize>) {
556 self.nodes.size_hint()
557 }
558
559 fn next(&mut self) -> Option<(NodeId, &'a T)> {
560 let (idx, node) = self.nodes.next()?;
561 Some((NodeId(idx), &node.value))
562 }
563
564 fn nth(&mut self, n: usize) -> Option<(NodeId, &'a T)> {
565 let (idx, node) = self.nodes.nth(n)?;
566 Some((NodeId(idx), &node.value))
567 }
568}
569
570#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
572pub struct NodesIdsIterMut<'a, T> {
573 nodes: slab::IterMut<'a, Node<T>>,
574}
575
576impl<'a, T> Iterator for NodesIdsIterMut<'a, T> {
577 type Item = (NodeId, &'a mut T);
578
579 fn size_hint(&self) -> (usize, Option<usize>) {
580 self.nodes.size_hint()
581 }
582
583 fn next(&mut self) -> Option<(NodeId, &'a mut T)> {
584 let (idx, node) = self.nodes.next()?;
585 Some((NodeId(idx), &mut node.value))
586 }
587
588 fn nth(&mut self, n: usize) -> Option<(NodeId, &'a mut T)> {
589 let (idx, node) = self.nodes.nth(n)?;
590 Some((NodeId(idx), &mut node.value))
591 }
592}
593
594#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
596pub struct NodesPosIdsIter<'a, T> {
597 nodes: slab::Iter<'a, Node<T>>,
598}
599
600impl<'a, T> Iterator for NodesPosIdsIter<'a, T> {
601 type Item = (NodeId, Pos2, &'a T);
602
603 fn size_hint(&self) -> (usize, Option<usize>) {
604 self.nodes.size_hint()
605 }
606
607 fn next(&mut self) -> Option<(NodeId, Pos2, &'a T)> {
608 let (idx, node) = self.nodes.next()?;
609 Some((NodeId(idx), node.pos, &node.value))
610 }
611
612 fn nth(&mut self, n: usize) -> Option<(NodeId, Pos2, &'a T)> {
613 let (idx, node) = self.nodes.nth(n)?;
614 Some((NodeId(idx), node.pos, &node.value))
615 }
616}
617
618#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
620pub struct NodesPosIdsIterMut<'a, T> {
621 nodes: slab::IterMut<'a, Node<T>>,
622}
623
624impl<'a, T> Iterator for NodesPosIdsIterMut<'a, T> {
625 type Item = (NodeId, Pos2, &'a mut T);
626
627 fn size_hint(&self) -> (usize, Option<usize>) {
628 self.nodes.size_hint()
629 }
630
631 fn next(&mut self) -> Option<(NodeId, Pos2, &'a mut T)> {
632 let (idx, node) = self.nodes.next()?;
633 Some((NodeId(idx), node.pos, &mut node.value))
634 }
635
636 fn nth(&mut self, n: usize) -> Option<(NodeId, Pos2, &'a mut T)> {
637 let (idx, node) = self.nodes.nth(n)?;
638 Some((NodeId(idx), node.pos, &mut node.value))
639 }
640}
641
642#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
644pub struct NodeInfoIter<'a, T> {
645 nodes: slab::Iter<'a, Node<T>>,
646}
647
648impl<'a, T> Iterator for NodeInfoIter<'a, T> {
649 type Item = &'a Node<T>;
650
651 fn size_hint(&self) -> (usize, Option<usize>) {
652 self.nodes.size_hint()
653 }
654
655 fn next(&mut self) -> Option<&'a Node<T>> {
656 let (_, node) = self.nodes.next()?;
657 Some(node)
658 }
659
660 fn nth(&mut self, n: usize) -> Option<&'a Node<T>> {
661 let (_, node) = self.nodes.nth(n)?;
662 Some(node)
663 }
664}
665
666#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
668pub struct NodeInfoIterMut<'a, T> {
669 nodes: slab::IterMut<'a, Node<T>>,
670}
671
672impl<'a, T> Iterator for NodeInfoIterMut<'a, T> {
673 type Item = &'a mut Node<T>;
674
675 fn size_hint(&self) -> (usize, Option<usize>) {
676 self.nodes.size_hint()
677 }
678
679 fn next(&mut self) -> Option<&'a mut Node<T>> {
680 let (_, node) = self.nodes.next()?;
681 Some(node)
682 }
683
684 fn nth(&mut self, n: usize) -> Option<&'a mut Node<T>> {
685 let (_, node) = self.nodes.nth(n)?;
686 Some(node)
687 }
688}
689
690#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
692pub struct NodeIdsDataIter<'a, T> {
693 nodes: slab::Iter<'a, Node<T>>,
694}
695
696impl<'a, T> Iterator for NodeIdsDataIter<'a, T> {
697 type Item = (NodeId, &'a Node<T>);
698
699 fn size_hint(&self) -> (usize, Option<usize>) {
700 self.nodes.size_hint()
701 }
702
703 fn next(&mut self) -> Option<(NodeId, &'a Node<T>)> {
704 let (id, node) = self.nodes.next()?;
705 Some((NodeId(id), node))
706 }
707
708 fn nth(&mut self, n: usize) -> Option<(NodeId, &'a Node<T>)> {
709 let (id, node) = self.nodes.nth(n)?;
710 Some((NodeId(id), node))
711 }
712}
713
714#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
716pub struct NodeIdsDataIterMut<'a, T> {
717 nodes: slab::IterMut<'a, Node<T>>,
718}
719
720impl<'a, T> Iterator for NodeIdsDataIterMut<'a, T> {
721 type Item = (NodeId, &'a mut Node<T>);
722
723 fn size_hint(&self) -> (usize, Option<usize>) {
724 self.nodes.size_hint()
725 }
726
727 fn next(&mut self) -> Option<(NodeId, &'a mut Node<T>)> {
728 let (id, node) = self.nodes.next()?;
729 Some((NodeId(id), node))
730 }
731
732 fn nth(&mut self, n: usize) -> Option<(NodeId, &'a mut Node<T>)> {
733 let (id, node) = self.nodes.nth(n)?;
734 Some((NodeId(id), node))
735 }
736}
737
738#[derive(Clone, Debug)]
740pub struct OutPin {
741 pub id: OutPinId,
743
744 pub remotes: Vec<InPinId>,
746}
747
748#[derive(Clone, Debug)]
750pub struct InPin {
751 pub id: InPinId,
753
754 pub remotes: Vec<OutPinId>,
756}
757
758impl OutPin {
759 fn new<T>(snarl: &Snarl<T>, pin: OutPinId) -> Self {
760 OutPin { id: pin, remotes: snarl.wires.wired_inputs(pin).collect() }
761 }
762}
763
764impl InPin {
765 fn new<T>(snarl: &Snarl<T>, pin: InPinId) -> Self {
766 InPin { id: pin, remotes: snarl.wires.wired_outputs(pin).collect() }
767 }
768}