more helper functions for the Cluster functionality in HexoSynth
This commit is contained in:
parent
b7f544f102
commit
37b57a4472
3 changed files with 144 additions and 1 deletions
|
@ -73,6 +73,73 @@ impl CellDir {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn path_from_to(mut a: (usize, usize), b: (usize, usize))
|
||||
-> Vec<CellDir>
|
||||
{
|
||||
let mut path = vec![];
|
||||
|
||||
let mut defensive_max : i32 = 1024;
|
||||
|
||||
while (a.0 != b.0 || a.1 != b.1) && defensive_max > 0 {
|
||||
//d// println!("ITER START: A={:?} B={:?}", a, b);
|
||||
defensive_max -= 1;
|
||||
|
||||
let mut min_distance = 99999.0;
|
||||
let mut min_dir = CellDir::C;
|
||||
let mut min_new_a = a;
|
||||
|
||||
for e in 0..6 {
|
||||
let dir = Self::from(e);
|
||||
|
||||
if let Some(new_pos) = dir.offs_pos(a) {
|
||||
let dist =
|
||||
(b.0 as f32 - new_pos.0 as f32).powf(2.0)
|
||||
+ (b.1 as f32 - new_pos.1 as f32).powf(2.0);
|
||||
|
||||
//d// println!("DIST={:5.3} FOR {:?} (B={:?})", dist, new_pos, b);
|
||||
|
||||
if dist < min_distance {
|
||||
min_distance = dist;
|
||||
min_dir = dir;
|
||||
min_new_a = new_pos;
|
||||
}
|
||||
} else {
|
||||
//d// println!("NOPOS {:?} {:?}", dir, a);
|
||||
}
|
||||
}
|
||||
|
||||
if min_distance < 99999.0 {
|
||||
//d// println!("A={:?} => {:?} DIR={:?} B={:?}", a, min_new_a, min_dir, b);
|
||||
a = min_new_a;
|
||||
path.push(min_dir);
|
||||
} else {
|
||||
//d// println!("ITER BREAK");
|
||||
break;
|
||||
}
|
||||
|
||||
//d// println!("ITER END: A={:?} B={:?} MAX={}", a, b, defensive_max);
|
||||
}
|
||||
|
||||
//d// println!("PATH: {:?}", path);
|
||||
|
||||
path
|
||||
}
|
||||
|
||||
pub fn offs_pos(&self, pos: (usize, usize)) -> Option<(usize, usize)> {
|
||||
let offs = self.as_offs(pos.0);
|
||||
|
||||
let new_pos = (
|
||||
pos.0 as i32 + offs.0,
|
||||
pos.1 as i32 + offs.1
|
||||
);
|
||||
|
||||
if new_pos.0 >= 0 && new_pos.1 >= 0 {
|
||||
Some((new_pos.0 as usize, new_pos.1 as usize))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_offs(&self, x: usize) -> (i32, i32) {
|
||||
let even = x % 2 == 0;
|
||||
match self {
|
||||
|
|
|
@ -36,7 +36,7 @@ use std::collections::{HashMap, HashSet};
|
|||
///
|
||||
/// matrix.sync().unwrap();
|
||||
///```
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
|
||||
pub struct Cell {
|
||||
node_id: NodeId,
|
||||
x: u8,
|
||||
|
@ -178,6 +178,20 @@ impl Cell {
|
|||
(self.x as usize, self.y as usize)
|
||||
}
|
||||
|
||||
pub fn offs_dir(&mut self, dir: CellDir) -> bool {
|
||||
if let Some(new_pos) =
|
||||
dir.offs_pos((self.x as usize, self.y as usize))
|
||||
{
|
||||
self.x = new_pos.0 as u8;
|
||||
self.y = new_pos.1 as u8;
|
||||
true
|
||||
}
|
||||
else
|
||||
{
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn has_dir_set(&self, dir: CellDir) -> bool {
|
||||
match dir {
|
||||
CellDir::TR => self.out1.is_some(),
|
||||
|
@ -258,6 +272,8 @@ pub enum MatrixError {
|
|||
output1: (NodeId, u8),
|
||||
output2: (NodeId, u8),
|
||||
},
|
||||
NonEmptyCell { cell: Cell },
|
||||
PosOutOfRange
|
||||
}
|
||||
|
||||
/// An intermediate data structure to store a single edge in the [Matrix].
|
||||
|
@ -443,6 +459,58 @@ impl Matrix {
|
|||
}
|
||||
}
|
||||
|
||||
/// Like [Matrix::change_matrix] but the function passed to this
|
||||
/// needs to return a `Result<(), MatrixError>`.
|
||||
pub fn change_matrix_err<F>(&mut self, mut f: F)
|
||||
-> Result<(), MatrixError>
|
||||
where F: FnMut(&mut Self) -> Result<(), MatrixError>
|
||||
{
|
||||
self.save_matrix();
|
||||
|
||||
if let Err(e) = f(self) {
|
||||
self.restore_matrix();
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
if let Err(e) = self.check() {
|
||||
self.restore_matrix();
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Tries to place all `cells` at once, if they are placed in empty
|
||||
/// cells only! Returns an error of the destination cell is not empty
|
||||
/// or out of range, or if the placement of the cluster results in any
|
||||
/// other inconsistencies.
|
||||
///
|
||||
/// This action must be wrapped with [Matrix::change_matrix_err]!
|
||||
///
|
||||
/// Restores the matrix to the previous state if placing fails.
|
||||
pub fn place_multiple(&mut self, cells: &[Cell]) -> Result<(), MatrixError> {
|
||||
for cell in cells {
|
||||
let x = cell.pos().0;
|
||||
let y = cell.pos().1;
|
||||
|
||||
if let Some(existing) = self.get(x, y) {
|
||||
if !existing.is_empty() {
|
||||
return Err(MatrixError::NonEmptyCell { cell: *existing });
|
||||
}
|
||||
|
||||
self.place(x, y, *cell);
|
||||
} else {
|
||||
return Err(MatrixError::PosOutOfRange);
|
||||
}
|
||||
}
|
||||
|
||||
if let Err(e) = self.check() {
|
||||
Err(e)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Inserts a cell into the hexagonal grid of the matrix.
|
||||
/// You have to make sure that the resulting DSP graph topology
|
||||
/// does not have cycles, otherwise an upload to the DSP thread via
|
||||
|
|
|
@ -17,6 +17,12 @@ use crate::log;
|
|||
use ringbuf::{Producer, Consumer};
|
||||
use std::sync::Arc;
|
||||
|
||||
use core::arch::x86_64::{
|
||||
_MM_FLUSH_ZERO_ON,
|
||||
_MM_SET_FLUSH_ZERO_MODE,
|
||||
// _MM_GET_FLUSH_ZERO_MODE
|
||||
};
|
||||
|
||||
/// Holds the complete allocation of nodes and
|
||||
/// the program. New Nodes or the program is
|
||||
/// not newly allocated in the audio backend, but it is
|
||||
|
@ -256,6 +262,8 @@ impl NodeExecutor {
|
|||
GraphMessage::NewProg { prog, copy_old_out } => {
|
||||
let mut prev_prog = std::mem::replace(&mut self.prog, prog);
|
||||
|
||||
unsafe { _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); }
|
||||
|
||||
self.monitor_signal_cur_inp_indices =
|
||||
[UNUSED_MONITOR_IDX; MON_SIG_CNT];
|
||||
|
||||
|
|
Loading…
Reference in a new issue