Feat: more predictable projet load behavior
Some checks failed
Deploy Website / deploy (push) Failing after 4m48s

This commit is contained in:
2026-02-02 01:01:01 +01:00
parent 6b95f31afd
commit 71146c7cea
5 changed files with 35 additions and 2 deletions

View File

@@ -25,6 +25,8 @@ struct ProjectFile {
sample_paths: Vec<PathBuf>,
#[serde(default = "default_tempo")]
tempo: f64,
#[serde(default)]
playing_patterns: Vec<(usize, usize)>,
}
fn default_tempo() -> f64 {
@@ -38,6 +40,7 @@ impl From<&Project> for ProjectFile {
banks: project.banks.clone(),
sample_paths: project.sample_paths.clone(),
tempo: project.tempo,
playing_patterns: project.playing_patterns.clone(),
}
}
}
@@ -48,6 +51,7 @@ impl From<ProjectFile> for Project {
banks: file.banks,
sample_paths: file.sample_paths,
tempo: file.tempo,
playing_patterns: file.playing_patterns,
};
project.normalize();
project

View File

@@ -450,6 +450,8 @@ pub struct Project {
pub sample_paths: Vec<PathBuf>,
#[serde(default = "default_tempo")]
pub tempo: f64,
#[serde(default)]
pub playing_patterns: Vec<(usize, usize)>,
}
fn default_tempo() -> f64 {
@@ -462,6 +464,7 @@ impl Default for Project {
banks: (0..MAX_BANKS).map(|_| Bank::default()).collect(),
sample_paths: Vec::new(),
tempo: default_tempo(),
playing_patterns: Vec::new(),
}
}
}

View File

@@ -527,10 +527,15 @@ impl App {
self.load_step_to_editor();
}
pub fn save(&mut self, path: PathBuf, link: &LinkState) {
pub fn save(&mut self, path: PathBuf, link: &LinkState, snapshot: &SequencerSnapshot) {
self.save_editor_to_step();
self.project_state.project.sample_paths = self.audio.config.sample_paths.clone();
self.project_state.project.tempo = link.tempo();
self.project_state.project.playing_patterns = snapshot
.active_patterns
.iter()
.map(|p| (p.bank, p.pattern))
.collect();
match model::save(&self.project_state.project, &path) {
Ok(final_path) => {
self.ui
@@ -547,12 +552,27 @@ impl App {
match model::load(&path) {
Ok(project) => {
let tempo = project.tempo;
let playing = project.playing_patterns.clone();
self.project_state.project = project;
self.editor_ctx.step = 0;
self.load_step_to_editor();
self.compile_all_steps(link);
self.mark_all_patterns_dirty();
link.set_tempo(tempo);
self.playback.clear_queues();
self.variables.lock().unwrap().clear();
self.dict.lock().unwrap().clear();
for (bank, pattern) in playing {
self.playback.queued_changes.push(StagedChange {
change: PatternChange::Start { bank, pattern },
quantization: crate::model::LaunchQuantization::Immediate,
sync_mode: crate::model::SyncMode::Reset,
});
}
self.ui.set_status(format!("Loaded: {}", path.display()));
self.project_state.file_path = Some(path);
}
@@ -1103,7 +1123,7 @@ impl App {
}
self.project_state.mark_dirty(bank, pattern);
}
AppCommand::Save(path) => self.save(path, link),
AppCommand::Save(path) => self.save(path, link, snapshot),
AppCommand::Load(path) => self.load(path, link),
// UI

View File

@@ -258,6 +258,7 @@ fn handle_modal_input(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
match mode {
FileBrowserMode::Save => ctx.dispatch(AppCommand::Save(path)),
FileBrowserMode::Load => {
let _ = ctx.seq_cmd_tx.send(SeqCommand::StopAll);
ctx.dispatch(AppCommand::Load(path));
load_project_samples(ctx);
}

View File

@@ -28,4 +28,9 @@ impl PlaybackState {
pub fn toggle(&mut self) {
self.playing = !self.playing;
}
pub fn clear_queues(&mut self) {
self.staged_changes.clear();
self.queued_changes.clear();
}
}