chain word and better save/load UI
This commit is contained in:
@@ -79,4 +79,5 @@ pub enum Op {
|
||||
Ramp,
|
||||
Range,
|
||||
Noise,
|
||||
Chain,
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ pub struct ExecutionTrace {
|
||||
pub struct StepContext {
|
||||
pub step: usize,
|
||||
pub beat: f64,
|
||||
pub bank: usize,
|
||||
pub pattern: usize,
|
||||
pub tempo: f64,
|
||||
pub phase: f64,
|
||||
|
||||
@@ -299,6 +299,7 @@ impl Forth {
|
||||
let val = match name.as_str() {
|
||||
"step" => Value::Int(ctx.step as i64, None),
|
||||
"beat" => Value::Float(ctx.beat, None),
|
||||
"bank" => Value::Int(ctx.bank as i64, None),
|
||||
"pattern" => Value::Int(ctx.pattern as i64, None),
|
||||
"tempo" => Value::Float(ctx.tempo, None),
|
||||
"phase" => Value::Float(ctx.phase, None),
|
||||
@@ -628,6 +629,24 @@ impl Forth {
|
||||
.insert("__tempo__".to_string(), Value::Float(clamped, None));
|
||||
}
|
||||
|
||||
Op::Chain => {
|
||||
let pattern = stack.pop().ok_or("stack underflow")?.as_int()? - 1;
|
||||
let bank = stack.pop().ok_or("stack underflow")?.as_int()? - 1;
|
||||
if bank < 0 || pattern < 0 {
|
||||
return Err("chain: bank and pattern must be >= 1".into());
|
||||
}
|
||||
if bank as usize == ctx.bank && pattern as usize == ctx.pattern {
|
||||
// chaining to self is a no-op
|
||||
} else {
|
||||
let key = format!("__chain_{}_{}__", ctx.bank, ctx.pattern);
|
||||
let val = format!("{bank}:{pattern}");
|
||||
self.vars
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(key, Value::Str(val, None));
|
||||
}
|
||||
}
|
||||
|
||||
Op::ListStart => {
|
||||
stack.push(Value::Marker);
|
||||
}
|
||||
|
||||
@@ -428,6 +428,13 @@ pub const WORDS: &[Word] = &[
|
||||
example: "pattern => 0",
|
||||
compile: Context("pattern"),
|
||||
},
|
||||
Word {
|
||||
name: "pbank",
|
||||
stack: "(-- n)",
|
||||
desc: "Current pattern's bank index",
|
||||
example: "pbank => 0",
|
||||
compile: Context("bank"),
|
||||
},
|
||||
Word {
|
||||
name: "tempo",
|
||||
stack: "(-- f)",
|
||||
@@ -621,6 +628,13 @@ pub const WORDS: &[Word] = &[
|
||||
example: "140 tempo!",
|
||||
compile: Simple,
|
||||
},
|
||||
Word {
|
||||
name: "chain",
|
||||
stack: "(bank pattern --)",
|
||||
desc: "Chain to bank/pattern (1-indexed) when current pattern ends",
|
||||
example: "1 4 chain",
|
||||
compile: Simple,
|
||||
},
|
||||
// Lists
|
||||
Word {
|
||||
name: "[",
|
||||
@@ -1550,6 +1564,7 @@ pub(super) fn simple_op(name: &str) -> Option<Op> {
|
||||
"ramp" => Op::Ramp,
|
||||
"range" => Op::Range,
|
||||
"noise" => Op::Noise,
|
||||
"chain" => Op::Chain,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user