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 {
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 <LICENSE-APACHE or
@ -209,6 +219,15 @@ impl SplitMix64 {
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]
pub fn next_u64(&mut self) -> u64 {
self.0 = self.0.wrapping_add(PHI);

View file

@ -1115,12 +1115,10 @@ macro_rules! make_node_info_enum {
$(NodeId::$variant(i) => *i as usize),+
}
}
pub fn list_all(&self) -> Vec<NodeId> {
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 {

View file

@ -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<u8>)> {
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<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 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) {