chain word and better save/load UI
This commit is contained in:
@@ -6,7 +6,7 @@ use std::time::Duration;
|
||||
|
||||
use super::LinkState;
|
||||
use crate::model::{MAX_BANKS, MAX_PATTERNS};
|
||||
use crate::model::{Dictionary, ExecutionTrace, Rng, ScriptEngine, StepContext, Variables};
|
||||
use crate::model::{Dictionary, ExecutionTrace, Rng, ScriptEngine, StepContext, Value, Variables};
|
||||
use crate::state::LiveKeyState;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
@@ -367,10 +367,13 @@ fn sequencer_loop(
|
||||
step_traces.retain(|&(bank, pattern, _), _| {
|
||||
bank != id.bank || pattern != id.pattern
|
||||
});
|
||||
let chain_key = format!("__chain_{}_{}__", id.bank, id.pattern);
|
||||
variables.lock().unwrap().remove(&chain_key);
|
||||
}
|
||||
}
|
||||
|
||||
let prev_beat = audio_state.prev_beat;
|
||||
let mut chain_transitions: Vec<(PatternId, PatternId)> = Vec::new();
|
||||
|
||||
for (_id, active) in audio_state.active_patterns.iter_mut() {
|
||||
let Some(pattern) = pattern_cache.get(active.bank, active.pattern) else {
|
||||
@@ -397,6 +400,7 @@ fn sequencer_loop(
|
||||
let ctx = StepContext {
|
||||
step: step_idx,
|
||||
beat,
|
||||
bank: active.bank,
|
||||
pattern: active.pattern,
|
||||
tempo,
|
||||
phase: beat % quantum,
|
||||
@@ -440,11 +444,44 @@ fn sequencer_loop(
|
||||
let next_step = active.step_index + 1;
|
||||
if next_step >= pattern.length {
|
||||
active.iter += 1;
|
||||
let chain_key = format!("__chain_{}_{}__", active.bank, active.pattern);
|
||||
let chain_target = {
|
||||
let vars = variables.lock().unwrap();
|
||||
vars.get(&chain_key).and_then(|v| {
|
||||
if let Value::Str(s, _) = v {
|
||||
let parts: Vec<&str> = s.split(':').collect();
|
||||
if parts.len() == 2 {
|
||||
let b = parts[0].parse::<usize>().ok()?;
|
||||
let p = parts[1].parse::<usize>().ok()?;
|
||||
Some(PatternId { bank: b, pattern: p })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
};
|
||||
if let Some(target) = chain_target {
|
||||
let source = PatternId { bank: active.bank, pattern: active.pattern };
|
||||
chain_transitions.push((source, target));
|
||||
}
|
||||
}
|
||||
active.step_index = next_step % pattern.length;
|
||||
}
|
||||
}
|
||||
|
||||
for (source, target) in chain_transitions {
|
||||
if !audio_state.pending_stops.contains(&source) {
|
||||
audio_state.pending_stops.push(source);
|
||||
}
|
||||
if !audio_state.pending_starts.contains(&target) {
|
||||
audio_state.pending_starts.push(target);
|
||||
}
|
||||
let chain_key = format!("__chain_{}_{}__", source.bank, source.pattern);
|
||||
variables.lock().unwrap().remove(&chain_key);
|
||||
}
|
||||
|
||||
{
|
||||
let mut state = shared_state.lock().unwrap();
|
||||
state.active_patterns = audio_state
|
||||
|
||||
Reference in New Issue
Block a user