diff --git a/src/dsp/mod.rs b/src/dsp/mod.rs index 81b4594..693feb3 100644 --- a/src/dsp/mod.rs +++ b/src/dsp/mod.rs @@ -1115,6 +1115,10 @@ macro_rules! make_node_info_enum { $(NodeId::$variant(i) => *i as usize),+ } } + + pub fn list_all(&self) -> Vec { + vec![$(NodeId::$variant(0)),+] + } } #[allow(non_snake_case, unused_variables)] @@ -1382,6 +1386,22 @@ macro_rules! make_node_info_enum { } } + pub fn default_output(&self) -> Option { + if self.out_count() > 0 { + Some(0) + } else { + None + } + } + + pub fn default_input(&self) -> Option { + if self.in_count() > 0 { + Some(0) + } else { + None + } + } + pub fn out_count(&self) -> usize { match self { NodeInfo::$v1 => 0, diff --git a/src/matrix.rs b/src/matrix.rs index 9b89893..e8df1dc 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -151,6 +151,13 @@ impl Cell { pub fn set_node_id(&mut self, new_id: NodeId) { self.node_id = new_id; + // With a new node id, we also need new I/Os: + self.in1 = None; + self.in2 = None; + self.in3 = None; + self.out1 = None; + self.out2 = None; + self.out3 = None; } pub fn label<'a>(&self, buf: &'a mut [u8]) -> Option<&'a str> { @@ -261,8 +268,37 @@ impl Cell { self } + /// Finds the first free input (one without an adjacent cell). If any free input + /// has an assigned input, that edge is returned. + pub fn find_adjacent_free_input(&self, m: &mut Matrix) -> Option<(CellDir, Option)> { + let mut free_inputs = vec![]; + + for dir in [CellDir::T, CellDir::TL, CellDir::BL] { + if let Some(pos) = dir.offs_pos((self.x as usize, self.y as usize)) { + if m.get(pos.0, pos.1) + .map(|c| c.is_empty()) + .unwrap_or(false) + { + free_inputs.push(dir); + } + } + } + + for in_dir in &free_inputs { + if self.has_dir_set(*in_dir) { + return Some((*in_dir, self.local_port_idx(*in_dir))); + } + } + + if free_inputs.len() > 0 { + Some((free_inputs[0], None)) + } else { + None + } + } + /// If the port is connected, it will return the position of the other cell. - pub fn is_port_dir_connected(self, m: &mut Matrix, dir: CellDir) -> Option<(usize, usize)> { + pub fn is_port_dir_connected(&self, m: &mut Matrix, dir: CellDir) -> Option<(usize, usize)> { if self.has_dir_set(dir) { if let Some(new_pos) = dir.offs_pos((self.x as usize, self.y as usize))