Feat: UI/UX fixes + removing clones from places
This commit is contained in:
@@ -112,7 +112,7 @@ impl Forth {
|
||||
let vars_snapshot = self.vars.load_full();
|
||||
let mut var_writes: HashMap<String, Value> = HashMap::new();
|
||||
|
||||
cmd.set_global(self.global_params.lock().clone());
|
||||
cmd.set_global(std::mem::take(&mut *self.global_params.lock()));
|
||||
|
||||
self.execute_ops(
|
||||
ops,
|
||||
@@ -459,7 +459,7 @@ impl Forth {
|
||||
if b.as_float().map_or(true, |v| v == 0.0) {
|
||||
return Err("division by zero".into());
|
||||
}
|
||||
stack.push(lift_binary(a, b, |x, y| x / y)?);
|
||||
stack.push(lift_binary(&a, &b, |x, y| x / y)?);
|
||||
}
|
||||
Op::Mod => {
|
||||
let b = pop(stack)?;
|
||||
@@ -467,47 +467,47 @@ impl Forth {
|
||||
if b.as_float().map_or(true, |v| v == 0.0) {
|
||||
return Err("modulo by zero".into());
|
||||
}
|
||||
let result = lift_binary(a, b, |x, y| (x as i64 % y as i64) as f64)?;
|
||||
let result = lift_binary(&a, &b, |x, y| (x as i64 % y as i64) as f64)?;
|
||||
stack.push(result);
|
||||
}
|
||||
Op::Neg => {
|
||||
let v = pop(stack)?;
|
||||
stack.push(lift_unary(v, |x| -x)?);
|
||||
stack.push(lift_unary(&v, |x| -x)?);
|
||||
}
|
||||
Op::Abs => {
|
||||
let v = pop(stack)?;
|
||||
stack.push(lift_unary(v, |x| x.abs())?);
|
||||
stack.push(lift_unary(&v, |x| x.abs())?);
|
||||
}
|
||||
Op::Floor => {
|
||||
let v = pop(stack)?;
|
||||
stack.push(lift_unary(v, |x| x.floor())?);
|
||||
stack.push(lift_unary(&v, |x| x.floor())?);
|
||||
}
|
||||
Op::Ceil => {
|
||||
let v = pop(stack)?;
|
||||
stack.push(lift_unary(v, |x| x.ceil())?);
|
||||
stack.push(lift_unary(&v, |x| x.ceil())?);
|
||||
}
|
||||
Op::Round => {
|
||||
let v = pop(stack)?;
|
||||
stack.push(lift_unary(v, |x| x.round())?);
|
||||
stack.push(lift_unary(&v, |x| x.round())?);
|
||||
}
|
||||
Op::Min => binary_op(stack, |a, b| a.min(b))?,
|
||||
Op::Max => binary_op(stack, |a, b| a.max(b))?,
|
||||
Op::Pow => binary_op(stack, |a, b| a.powf(b))?,
|
||||
Op::Sqrt => {
|
||||
let v = pop(stack)?;
|
||||
stack.push(lift_unary(v, |x| x.sqrt())?);
|
||||
stack.push(lift_unary(&v, |x| x.sqrt())?);
|
||||
}
|
||||
Op::Sin => {
|
||||
let v = pop(stack)?;
|
||||
stack.push(lift_unary(v, |x| x.sin())?);
|
||||
stack.push(lift_unary(&v, |x| x.sin())?);
|
||||
}
|
||||
Op::Cos => {
|
||||
let v = pop(stack)?;
|
||||
stack.push(lift_unary(v, |x| x.cos())?);
|
||||
stack.push(lift_unary(&v, |x| x.cos())?);
|
||||
}
|
||||
Op::Log => {
|
||||
let v = pop(stack)?;
|
||||
stack.push(lift_unary(v, |x| x.ln())?);
|
||||
stack.push(lift_unary(&v, |x| x.ln())?);
|
||||
}
|
||||
|
||||
Op::Eq => cmp_op(stack, |a, b| (a - b).abs() < f64::EPSILON)?,
|
||||
@@ -1055,7 +1055,7 @@ impl Forth {
|
||||
let key = read_key(&var_writes_cell, vars_snapshot);
|
||||
let values = std::mem::take(stack);
|
||||
for val in values {
|
||||
let result = lift_unary_int(val, |degree| {
|
||||
let result = lift_unary_int(&val, |degree| {
|
||||
let octave_offset = degree.div_euclid(len);
|
||||
let idx = degree.rem_euclid(len) as usize;
|
||||
key + octave_offset * 12 + pattern[idx]
|
||||
@@ -1155,7 +1155,7 @@ impl Forth {
|
||||
Op::Oct => {
|
||||
let shift = pop(stack)?;
|
||||
let note = pop(stack)?;
|
||||
let result = lift_binary(note, shift, |n, s| n + s * 12.0)?;
|
||||
let result = lift_binary(¬e, &shift, |n, s| n + s * 12.0)?;
|
||||
stack.push(result);
|
||||
}
|
||||
|
||||
@@ -1921,65 +1921,65 @@ fn float_to_value(result: f64) -> Value {
|
||||
}
|
||||
}
|
||||
|
||||
fn lift_unary<F>(val: Value, f: F) -> Result<Value, String>
|
||||
fn lift_unary<F>(val: &Value, f: F) -> Result<Value, String>
|
||||
where
|
||||
F: Fn(f64) -> f64 + Copy,
|
||||
{
|
||||
match val {
|
||||
Value::ArpList(items) => {
|
||||
let mapped: Result<Vec<_>, _> = items.iter().map(|x| lift_unary(x.clone(), f)).collect();
|
||||
let mapped: Result<Vec<_>, _> = items.iter().map(|x| lift_unary(x, f)).collect();
|
||||
Ok(Value::ArpList(Arc::from(mapped?)))
|
||||
}
|
||||
Value::CycleList(items) => {
|
||||
let mapped: Result<Vec<_>, _> = items.iter().map(|x| lift_unary(x.clone(), f)).collect();
|
||||
let mapped: Result<Vec<_>, _> = items.iter().map(|x| lift_unary(x, f)).collect();
|
||||
Ok(Value::CycleList(Arc::from(mapped?)))
|
||||
}
|
||||
v => Ok(float_to_value(f(v.as_float()?))),
|
||||
}
|
||||
}
|
||||
|
||||
fn lift_unary_int<F>(val: Value, f: F) -> Result<Value, String>
|
||||
fn lift_unary_int<F>(val: &Value, f: F) -> Result<Value, String>
|
||||
where
|
||||
F: Fn(i64) -> i64 + Copy,
|
||||
{
|
||||
match val {
|
||||
Value::ArpList(items) => {
|
||||
let mapped: Result<Vec<_>, _> =
|
||||
items.iter().map(|x| lift_unary_int(x.clone(), f)).collect();
|
||||
items.iter().map(|x| lift_unary_int(x, f)).collect();
|
||||
Ok(Value::ArpList(Arc::from(mapped?)))
|
||||
}
|
||||
Value::CycleList(items) => {
|
||||
let mapped: Result<Vec<_>, _> =
|
||||
items.iter().map(|x| lift_unary_int(x.clone(), f)).collect();
|
||||
items.iter().map(|x| lift_unary_int(x, f)).collect();
|
||||
Ok(Value::CycleList(Arc::from(mapped?)))
|
||||
}
|
||||
v => Ok(Value::Int(f(v.as_int()?), None)),
|
||||
}
|
||||
}
|
||||
|
||||
fn lift_binary<F>(a: Value, b: Value, f: F) -> Result<Value, String>
|
||||
fn lift_binary<F>(a: &Value, b: &Value, f: F) -> Result<Value, String>
|
||||
where
|
||||
F: Fn(f64, f64) -> f64 + Copy,
|
||||
{
|
||||
match (a, b) {
|
||||
(Value::ArpList(items), b) => {
|
||||
let mapped: Result<Vec<_>, _> =
|
||||
items.iter().map(|x| lift_binary(x.clone(), b.clone(), f)).collect();
|
||||
items.iter().map(|x| lift_binary(x, b, f)).collect();
|
||||
Ok(Value::ArpList(Arc::from(mapped?)))
|
||||
}
|
||||
(a, Value::ArpList(items)) => {
|
||||
let mapped: Result<Vec<_>, _> =
|
||||
items.iter().map(|x| lift_binary(a.clone(), x.clone(), f)).collect();
|
||||
items.iter().map(|x| lift_binary(a, x, f)).collect();
|
||||
Ok(Value::ArpList(Arc::from(mapped?)))
|
||||
}
|
||||
(Value::CycleList(items), b) => {
|
||||
let mapped: Result<Vec<_>, _> =
|
||||
items.iter().map(|x| lift_binary(x.clone(), b.clone(), f)).collect();
|
||||
items.iter().map(|x| lift_binary(x, b, f)).collect();
|
||||
Ok(Value::CycleList(Arc::from(mapped?)))
|
||||
}
|
||||
(a, Value::CycleList(items)) => {
|
||||
let mapped: Result<Vec<_>, _> =
|
||||
items.iter().map(|x| lift_binary(a.clone(), x.clone(), f)).collect();
|
||||
items.iter().map(|x| lift_binary(a, x, f)).collect();
|
||||
Ok(Value::CycleList(Arc::from(mapped?)))
|
||||
}
|
||||
(a, b) => Ok(float_to_value(f(a.as_float()?, b.as_float()?))),
|
||||
@@ -1992,7 +1992,7 @@ where
|
||||
{
|
||||
let b = pop(stack)?;
|
||||
let a = pop(stack)?;
|
||||
stack.push(lift_binary(a, b, f)?);
|
||||
stack.push(lift_binary(&a, &b, f)?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -170,6 +170,17 @@ impl LaunchQuantization {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn short_label(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Immediate => "Imm",
|
||||
Self::Beat => "Bt",
|
||||
Self::Bar => "1B",
|
||||
Self::Bars2 => "2B",
|
||||
Self::Bars4 => "4B",
|
||||
Self::Bars8 => "8B",
|
||||
}
|
||||
}
|
||||
|
||||
/// Cycle to the next longer quantization, clamped at `Bars8`.
|
||||
pub fn next(&self) -> Self {
|
||||
match self {
|
||||
@@ -212,6 +223,13 @@ impl SyncMode {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn short_label(&self) -> &'static str {
|
||||
match self {
|
||||
Self::Reset => "Rst",
|
||||
Self::PhaseLock => "Plk",
|
||||
}
|
||||
}
|
||||
|
||||
/// Toggle between Reset and PhaseLock.
|
||||
pub fn toggle(&self) -> Self {
|
||||
match self {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! Script editor widget with completion, search, and sample finder popups.
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::theme;
|
||||
use ratatui::{
|
||||
@@ -25,7 +26,7 @@ pub struct CompletionCandidate {
|
||||
}
|
||||
|
||||
struct CompletionState {
|
||||
candidates: Vec<CompletionCandidate>,
|
||||
candidates: Arc<[CompletionCandidate]>,
|
||||
matches: Vec<usize>,
|
||||
cursor: usize,
|
||||
prefix: String,
|
||||
@@ -37,7 +38,7 @@ struct CompletionState {
|
||||
impl CompletionState {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
candidates: Vec::new(),
|
||||
candidates: Arc::from([]),
|
||||
matches: Vec::new(),
|
||||
cursor: 0,
|
||||
prefix: String::new(),
|
||||
@@ -171,7 +172,7 @@ impl Editor {
|
||||
self.scroll_offset.set(0);
|
||||
}
|
||||
|
||||
pub fn set_candidates(&mut self, candidates: Vec<CompletionCandidate>) {
|
||||
pub fn set_candidates(&mut self, candidates: Arc<[CompletionCandidate]>) {
|
||||
self.completion.candidates = candidates;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user