More helper functions to make life easier for HexoSynth

This commit is contained in:
Weird Constructor 2021-08-01 20:35:57 +02:00
parent 8b07869963
commit 360adc10be
3 changed files with 76 additions and 13 deletions

View file

@ -168,6 +168,11 @@ impl Rng {
pub fn next(&mut self) -> f32 { pub fn next(&mut self) -> f32 {
self.sm.next_open01() as f32 self.sm.next_open01() as f32
} }
#[inline]
pub fn next_u64(&mut self) -> u64 {
self.sm.next_u64()
}
} }
thread_local! { thread_local! {
@ -179,6 +184,11 @@ pub fn rand_01() -> f32 {
GLOBAL_RNG.with(|r| r.borrow_mut().next()) 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. // Copyright 2018 Developers of the Rand project.
// //
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
@ -209,6 +219,15 @@ impl SplitMix64 {
Self::new(u64::from_be_bytes(seed.to_be_bytes())) Self::new(u64::from_be_bytes(seed.to_be_bytes()))
} }
pub fn new_time_seed() -> 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] #[inline]
pub fn next_u64(&mut self) -> u64 { pub fn next_u64(&mut self) -> u64 {
self.0 = self.0.wrapping_add(PHI); self.0 = self.0.wrapping_add(PHI);

View file

@ -1115,11 +1115,9 @@ macro_rules! make_node_info_enum {
$(NodeId::$variant(i) => *i as usize),+ $(NodeId::$variant(i) => *i as usize),+
} }
} }
}
pub fn list_all(&self) -> Vec<NodeId> { pub const ALL_NODE_IDS : &'static [NodeId] = &[$(NodeId::$variant(0)),+];
vec![$(NodeId::$variant(0)),+]
}
}
#[allow(non_snake_case, unused_variables)] #[allow(non_snake_case, unused_variables)]
pub mod round { pub mod round {

View file

@ -270,33 +270,79 @@ impl Cell {
/// Finds the first free input (one without an adjacent cell). If any free input /// Finds the first free input (one without an adjacent cell). If any free input
/// has an assigned input, that edge is returned. /// has an assigned input, that edge is returned.
pub fn find_adjacent_free_input(&self, m: &mut Matrix) -> Option<(CellDir, Option<u8>)> { /// With `dir` you can specify input with `CellDir::T`, output with `CellDir::B`
let mut free_inputs = vec![]; /// and any with `CellDir::C`.
pub fn find_first_adjacent_free(&self, m: &mut Matrix, dir: CellDir) -> Option<(CellDir, Option<u8>)> {
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 let Some(pos) = dir.offs_pos((self.x as usize, self.y as usize)) {
if m.get(pos.0, pos.1) if m.get(pos.0, pos.1)
.map(|c| c.is_empty()) .map(|c| c.is_empty())
.unwrap_or(false) .unwrap_or(false)
{ {
free_inputs.push(dir); free_ports.push(dir);
} }
} }
} }
for in_dir in &free_inputs { for in_dir in &free_ports {
if self.has_dir_set(*in_dir) { if self.has_dir_set(**in_dir) {
return Some((*in_dir, self.local_port_idx(*in_dir))); return Some((**in_dir, self.local_port_idx(**in_dir)));
} }
} }
if free_inputs.len() > 0 { if free_ports.len() > 0 {
Some((free_inputs[0], None)) Some((*free_ports[0], None))
} else { } else {
None 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. /// 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 self.has_dir_set(dir) {