more fixes
All checks were successful
Deploy Website / deploy (push) Has been skipped

This commit is contained in:
2026-03-01 03:33:22 +01:00
parent b72c782b2b
commit 11cc925faf
24 changed files with 269 additions and 189 deletions

View File

@@ -141,8 +141,6 @@ pub struct PatternSnapshot {
pub speed: crate::model::PatternSpeed,
pub length: usize,
pub steps: Vec<StepSnapshot>,
#[allow(dead_code)]
pub quantization: LaunchQuantization,
pub sync_mode: SyncMode,
pub follow_up: FollowUp,
}
@@ -544,7 +542,7 @@ struct StepResult {
fn format_speed_key(buf: &mut String, bank: usize, pattern: usize) -> &str {
use std::fmt::Write;
buf.clear();
write!(buf, "__speed_{bank}_{pattern}__").unwrap();
write!(buf, "__speed_{bank}_{pattern}__").expect("write to String");
buf
}
@@ -553,7 +551,7 @@ pub struct SequencerState {
pattern_cache: PatternCache,
pending_updates: HashMap<(usize, usize), PatternSnapshot>,
runs_counter: RunsCounter,
step_traces: Arc<StepTracesMap>,
step_traces: StepTracesMap,
event_count: usize,
script_engine: ScriptEngine,
variables: Variables,
@@ -590,7 +588,7 @@ impl SequencerState {
pattern_cache: PatternCache::new(),
pending_updates: HashMap::new(),
runs_counter: RunsCounter::new(),
step_traces: Arc::new(HashMap::new()),
step_traces: HashMap::new(),
event_count: 0,
script_engine,
variables,
@@ -709,7 +707,7 @@ impl SequencerState {
self.audio_state.active_patterns.clear();
self.audio_state.pending_starts.clear();
self.audio_state.pending_stops.clear();
Arc::make_mut(&mut self.step_traces).clear();
self.step_traces.clear();
self.runs_counter.counts.clear();
self.audio_state.flush_midi_notes = true;
}
@@ -727,7 +725,7 @@ impl SequencerState {
self.speed_overrides.clear();
self.script_engine.clear_global_params();
self.runs_counter.counts.clear();
Arc::make_mut(&mut self.step_traces).clear();
self.step_traces.clear();
self.audio_state.flush_midi_notes = true;
}
SeqCommand::ResetScriptState => {
@@ -807,7 +805,7 @@ impl SequencerState {
fn tick_paused(&mut self) -> TickOutput {
for pending in self.audio_state.pending_stops.drain(..) {
self.audio_state.active_patterns.remove(&pending.id);
Arc::make_mut(&mut self.step_traces).retain(|&(bank, pattern, _), _| {
self.step_traces.retain(|&(bank, pattern, _), _| {
bank != pending.id.bank || pattern != pending.id.pattern
});
let key = (pending.id.bank, pending.id.pattern);
@@ -889,7 +887,7 @@ impl SequencerState {
for pending in &self.audio_state.pending_stops {
if check_quantization_boundary(pending.quantization, beat, prev_beat, quantum) {
self.audio_state.active_patterns.remove(&pending.id);
Arc::make_mut(&mut self.step_traces).retain(|&(bank, pattern, _), _| {
self.step_traces.retain(|&(bank, pattern, _), _| {
bank != pending.id.bank || pattern != pending.id.pattern
});
// Flush pending update so cache stays current for future launches
@@ -1009,7 +1007,7 @@ impl SequencerState {
.script_engine
.evaluate_with_trace(script, &ctx, &mut trace)
{
Arc::make_mut(&mut self.step_traces).insert(
self.step_traces.insert(
(active.bank, active.pattern, source_idx),
std::mem::take(&mut trace),
);
@@ -1198,7 +1196,7 @@ impl SequencerState {
last_step_beat: a.last_step_beat,
})
.collect(),
step_traces: Arc::clone(&self.step_traces),
step_traces: Arc::new(self.step_traces.clone()),
event_count: self.event_count,
tempo: self.last_tempo,
beat: self.last_beat,
@@ -1490,7 +1488,6 @@ mod tests {
source: None,
})
.collect(),
quantization: LaunchQuantization::Immediate,
sync_mode: SyncMode::Reset,
follow_up: FollowUp::default(),
}
@@ -1709,19 +1706,19 @@ mod tests {
// beat_int at 0.5 is 2, prev_beat_int at 0.0 is 0
// steps_to_fire = 2-0 = 2, firing steps 0 and 1, wrapping to 0
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).unwrap();
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).expect("pattern in active set");
assert_eq!(ap.step_index, 0);
assert_eq!(ap.iter, 1);
// beat_int at 0.75 is 3, prev is 2, fires 1 step (step 0), advances to 1
state.tick(tick_at(0.75, true));
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).unwrap();
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).expect("pattern in active set");
assert_eq!(ap.step_index, 1);
assert_eq!(ap.iter, 1);
// beat_int at 1.0 is 4, prev is 3, fires 1 step (step 1), wraps to 0
state.tick(tick_at(1.0, true));
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).unwrap();
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).expect("pattern in active set");
assert_eq!(ap.step_index, 0);
assert_eq!(ap.iter, 2);
}
@@ -1754,12 +1751,12 @@ mod tests {
// At 2x speed: beat_int at 0.5 is (0.5*4*2)=4, prev at 0.0 is 0
// Fires 4 steps (0,1,2,3), advancing to step 4
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).unwrap();
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).expect("pattern in active set");
assert_eq!(ap.step_index, 4);
// beat_int at 0.625 is (0.625*4*2)=5, prev is 4, fires 1 step
state.tick(tick_at(0.625, true));
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).unwrap();
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).expect("pattern in active set");
assert_eq!(ap.step_index, 5);
}
@@ -1866,17 +1863,17 @@ mod tests {
));
// beat_int at 0.5 is 2, prev at 0.0 is 0, fires 2 steps (0,1), step_index=2
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).unwrap();
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).expect("pattern in active set");
assert_eq!(ap.step_index, 2);
// beat_int at 0.75 is 3, prev is 2, fires 1 step (2), step_index=3
state.tick(tick_at(0.75, true));
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).unwrap();
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).expect("pattern in active set");
assert_eq!(ap.step_index, 3);
// beat_int at 1.0 is 4, prev is 3, fires 1 step (3), wraps to step_index=0
state.tick(tick_at(1.0, true));
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).unwrap();
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).expect("pattern in active set");
assert_eq!(ap.step_index, 0);
// Update pattern to length 2 while running — deferred until iteration boundary
@@ -1890,7 +1887,7 @@ mod tests {
}],
1.25,
));
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).unwrap();
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).expect("pattern in active set");
assert_eq!(ap.step_index, 1); // still length 4
// Advance through remaining steps of original length-4 pattern
@@ -1901,12 +1898,12 @@ mod tests {
// Now length=2 is applied. Next tick uses new length.
// beat=2.25: step 0 fires, advances to 1
state.tick(tick_at(2.25, true));
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).unwrap();
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).expect("pattern in active set");
assert_eq!(ap.step_index, 1);
// beat=2.5: step 1 fires, wraps to 0 (length 2)
state.tick(tick_at(2.5, true));
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).unwrap();
let ap = state.audio_state.active_patterns.get(&pid(0, 0)).expect("pattern in active set");
assert_eq!(ap.step_index, 0);
}
@@ -2056,7 +2053,6 @@ mod tests {
source: None,
})
.collect(),
quantization: LaunchQuantization::Immediate,
sync_mode: SyncMode::Reset,
follow_up: FollowUp::default(),
}