1#![no_std]
2use core::array;
3
4pub struct Node<
5 P: Processor<D, MAX_IN, MAX_OUT>,
6 D: Default,
7 const MAX_IN: usize,
8 const MAX_OUT: usize,
9> {
10 processor: Option<P>,
11 read: [D; MAX_OUT],
12 write: [D; MAX_OUT],
13}
14
15impl<P: Processor<D, MAX_IN, MAX_OUT>, D: Default, const MAX_IN: usize, const MAX_OUT: usize>
16 Node<P, D, MAX_IN, MAX_OUT>
17{
18 pub fn new(processor: Option<P>) -> Self {
19 Self {
20 processor,
21 read: array::from_fn(|_| D::default()),
22 write: array::from_fn(|_| D::default()),
23 }
24 }
25}
26
27pub trait Processor<D, const MAX_IN: usize, const MAX_OUT: usize> {
28 fn process(&mut self, inputs: &[Option<&D>; MAX_IN]) -> [D; MAX_OUT];
29}
30
31pub struct StaticGraph<
32 P: Processor<D, MAX_IN, MAX_OUT>,
33 D: Default,
34 const MAX_IN: usize,
35 const MAX_OUT: usize,
36 const MAX_NODES: usize,
37> {
38 nodes: [Node<P, D, MAX_IN, MAX_OUT>; MAX_NODES],
39 used: [bool; MAX_NODES],
40 connections: [[Option<(usize, usize)>; MAX_IN]; MAX_NODES],
41}
42
43pub struct NodeHandle(usize);
44
45impl<
46 P: Processor<D, MAX_IN, MAX_OUT>,
47 D: Default,
48 const MAX_IN: usize,
49 const MAX_OUT: usize,
50 const MAX_NODES: usize,
51 > StaticGraph<P, D, MAX_IN, MAX_OUT, MAX_NODES>
52{
53 pub fn new() -> Self {
54 Self {
55 nodes: array::from_fn(|_| Node::new(None)),
56 used: [false; MAX_NODES],
57 connections: [[None; MAX_IN]; MAX_NODES],
58 }
59 }
60 pub fn process(&mut self) {
61 for i in 0..MAX_NODES {
62 core::mem::swap(&mut self.nodes[i].read, &mut self.nodes[i].write)
63 }
64 for i in 0..MAX_NODES {
65 if self.used[i] {
66 let mut inputs = array::from_fn(|_| None);
67 for (j, input) in self.connections[i].iter().enumerate() {
68 if let Some((in_node, in_port)) = input {
69 inputs[j] = Some(&self.nodes[*in_node].read[*in_port]);
70 }
71 }
72 if let Some(ref mut processor) = self.nodes[i].processor {
73 self.nodes[i].write = processor.process(&inputs);
74 }
75 }
76 }
77 }
78
79 pub fn add_node(&mut self, processor: P) -> Option<NodeHandle> {
80 for i in 0..MAX_NODES {
81 if !self.used[i] {
82 self.nodes[i].processor = Some(processor);
83 self.used[i] = true;
84 return Some(NodeHandle(i));
85 }
86 }
87 return None;
88 }
89
90 pub fn remove_node(&mut self, idx: NodeHandle) {
91 let idx = idx.0;
92 self.used[idx] = false;
93
94 for i in self.connections.iter_mut() {
95 for j in i.iter_mut() {
96 if let Some((in_node, _)) = *j {
97 if in_node == idx {
98 *j = None;
99 }
100 }
101 }
102 }
103 }
104 pub fn set_edge(
105 &mut self,
106 to: &NodeHandle,
107 to_sink: usize,
108 from: &NodeHandle,
109 from_source: usize,
110 ) {
111 self.connections[to.0][to_sink] = Some((from.0, from_source));
112 }
113 pub fn unset_edge(&mut self, to: &NodeHandle, to_sink: usize) {
114 self.connections[to.0][to_sink] = None;
115 }
116}