From 360adc10be7dfaf582300c20582f83e214e32c33 Mon Sep 17 00:00:00 2001 From: Weird Constructor Date: Sun, 1 Aug 2021 20:35:57 +0200 Subject: [PATCH] More helper functions to make life easier for HexoSynth --- src/dsp/helpers.rs | 19 ++++++++++++++ src/dsp/mod.rs | 6 ++--- src/matrix.rs | 64 +++++++++++++++++++++++++++++++++++++++------- 3 files changed, 76 insertions(+), 13 deletions(-) diff --git a/src/dsp/helpers.rs b/src/dsp/helpers.rs index 8a7c9a5..29af7e9 100644 --- a/src/dsp/helpers.rs +++ b/src/dsp/helpers.rs @@ -168,6 +168,11 @@ impl Rng { pub fn next(&mut self) -> f32 { self.sm.next_open01() as f32 } + + #[inline] + pub fn next_u64(&mut self) -> u64 { + self.sm.next_u64() + } } thread_local! { @@ -179,6 +184,11 @@ pub fn rand_01() -> f32 { GLOBAL_RNG.with(|r| r.borrow_mut().next()) } +#[inline] +pub fn rand_u64() -> u64 { + GLOBAL_RNG.with(|r| r.borrow_mut().next_u64()) +} + // Copyright 2018 Developers of the Rand project. // // Licensed under the Apache License, Version 2.0 Self { + use std::time::SystemTime; + + match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) { + Ok(n) => Self::new(n.as_secs() as u64), + Err(_) => Self::new(123456789), + } + } + #[inline] pub fn next_u64(&mut self) -> u64 { self.0 = self.0.wrapping_add(PHI); diff --git a/src/dsp/mod.rs b/src/dsp/mod.rs index 693feb3..c117d56 100644 --- a/src/dsp/mod.rs +++ b/src/dsp/mod.rs @@ -1115,12 +1115,10 @@ macro_rules! make_node_info_enum { $(NodeId::$variant(i) => *i as usize),+ } } - - pub fn list_all(&self) -> Vec { - vec![$(NodeId::$variant(0)),+] - } } + pub const ALL_NODE_IDS : &'static [NodeId] = &[$(NodeId::$variant(0)),+]; + #[allow(non_snake_case, unused_variables)] pub mod round { $(pub mod $variant { diff --git a/src/matrix.rs b/src/matrix.rs index e8df1dc..f4ff695 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -270,33 +270,79 @@ impl Cell { /// 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![]; + /// With `dir` you can specify input with `CellDir::T`, output with `CellDir::B` + /// and any with `CellDir::C`. + pub fn find_first_adjacent_free(&self, m: &mut Matrix, dir: CellDir) -> Option<(CellDir, Option)> { + let mut free_ports = vec![]; - for dir in [CellDir::T, CellDir::TL, CellDir::BL] { + let options : &[CellDir] = + if dir == CellDir::C { + &[CellDir::T, CellDir::TL, CellDir::BL, + CellDir::TR, CellDir::BR, CellDir::B] + + } else if dir.is_input() { + &[CellDir::T, CellDir::TL, CellDir::BL] + + } else { + &[CellDir::TR, CellDir::BR, CellDir::B] + }; + + for dir in options { 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); + free_ports.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))); + for in_dir in &free_ports { + 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)) + if free_ports.len() > 0 { + Some((*free_ports[0], None)) } else { None } } + /// Finds the all adjacent free places around the current cell. + /// With `dir` you can specify input with `CellDir::T`, output with `CellDir::B` + /// and any with `CellDir::C`. + pub fn find_all_adjacent_free(&self, m: &mut Matrix, dir: CellDir) -> Vec<(CellDir, (usize, usize))> { + let mut free_ports = vec![]; + + let options : &[CellDir] = + if dir == CellDir::C { + &[CellDir::T, CellDir::TL, CellDir::BL, + CellDir::TR, CellDir::BR, CellDir::B] + + } else if dir.is_input() { + &[CellDir::T, CellDir::TL, CellDir::BL] + + } else { + &[CellDir::TR, CellDir::BR, CellDir::B] + }; + + for dir in options { + 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_ports.push((*dir, pos)); + } + } + } + + free_ports.to_vec() + } + /// 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)> { if self.has_dir_set(dir) {