Fix preset loading not updating node graph editor
This commit is contained in:
parent
725faa4445
commit
16011e5f28
|
|
@ -698,6 +698,9 @@ struct EditorApp {
|
|||
audio_controller: Option<std::sync::Arc<std::sync::Mutex<daw_backend::EngineController>>>,
|
||||
audio_event_rx: Option<rtrb::Consumer<daw_backend::AudioEvent>>,
|
||||
audio_events_pending: std::sync::Arc<std::sync::atomic::AtomicBool>,
|
||||
/// Count of in-flight graph preset loads — keeps the repaint loop alive
|
||||
/// until the audio thread sends GraphPresetLoaded events for all of them
|
||||
pending_graph_loads: std::sync::Arc<std::sync::atomic::AtomicU32>,
|
||||
#[allow(dead_code)] // Stored for future export/recording configuration
|
||||
audio_sample_rate: u32,
|
||||
#[allow(dead_code)]
|
||||
|
|
@ -937,6 +940,7 @@ impl EditorApp {
|
|||
audio_controller,
|
||||
audio_event_rx,
|
||||
audio_events_pending: std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false)),
|
||||
pending_graph_loads: std::sync::Arc::new(std::sync::atomic::AtomicU32::new(0)),
|
||||
audio_sample_rate,
|
||||
audio_channels,
|
||||
video_manager: std::sync::Arc::new(std::sync::Mutex::new(
|
||||
|
|
@ -3976,6 +3980,10 @@ impl eframe::App for EditorApp {
|
|||
if self.audio_events_pending.load(std::sync::atomic::Ordering::Relaxed) {
|
||||
ctx.request_repaint();
|
||||
}
|
||||
// Keep repainting while waiting for graph preset loads to complete
|
||||
if self.pending_graph_loads.load(std::sync::atomic::Ordering::Relaxed) > 0 {
|
||||
ctx.request_repaint();
|
||||
}
|
||||
|
||||
// Drain recording mirror buffer for live waveform display
|
||||
if self.is_recording {
|
||||
|
|
@ -4354,6 +4362,19 @@ impl eframe::App for EditorApp {
|
|||
self.waveform_gpu_dirty.insert(pool_index);
|
||||
ctx.request_repaint();
|
||||
}
|
||||
AudioEvent::GraphPresetLoaded(_track_id) => {
|
||||
// Preset was loaded on the audio thread — bump generation
|
||||
// so the node graph pane reloads from backend
|
||||
self.project_generation += 1;
|
||||
// Decrement pending counter (saturating to avoid underflow from
|
||||
// loads not initiated by the preset browser, e.g. default instruments)
|
||||
let _ = self.pending_graph_loads.fetch_update(
|
||||
std::sync::atomic::Ordering::Relaxed,
|
||||
std::sync::atomic::Ordering::Relaxed,
|
||||
|v| if v > 0 { Some(v - 1) } else { Some(0) },
|
||||
);
|
||||
ctx.request_repaint();
|
||||
}
|
||||
_ => {} // Ignore other events for now
|
||||
}
|
||||
}
|
||||
|
|
@ -4731,6 +4752,7 @@ impl eframe::App for EditorApp {
|
|||
script_saved: &mut self.script_saved,
|
||||
region_selection: &mut self.region_selection,
|
||||
region_select_mode: &mut self.region_select_mode,
|
||||
pending_graph_loads: &self.pending_graph_loads,
|
||||
};
|
||||
|
||||
render_layout_node(
|
||||
|
|
@ -5065,6 +5087,8 @@ struct RenderContext<'a> {
|
|||
region_selection: &'a mut Option<lightningbeam_core::selection::RegionSelection>,
|
||||
/// Region select mode (Rectangle or Lasso)
|
||||
region_select_mode: &'a mut lightningbeam_core::tool::RegionSelectMode,
|
||||
/// Counter for in-flight graph preset loads (keeps repaint loop alive)
|
||||
pending_graph_loads: &'a std::sync::Arc<std::sync::atomic::AtomicU32>,
|
||||
}
|
||||
|
||||
/// Recursively render a layout node with drag support
|
||||
|
|
@ -5551,6 +5575,7 @@ fn render_pane(
|
|||
script_saved: ctx.script_saved,
|
||||
region_selection: ctx.region_selection,
|
||||
region_select_mode: ctx.region_select_mode,
|
||||
pending_graph_loads: ctx.pending_graph_loads,
|
||||
editing_clip_id: ctx.editing_clip_id,
|
||||
editing_instance_id: ctx.editing_instance_id,
|
||||
editing_parent_layer_id: ctx.editing_parent_layer_id,
|
||||
|
|
@ -5631,6 +5656,7 @@ fn render_pane(
|
|||
script_saved: ctx.script_saved,
|
||||
region_selection: ctx.region_selection,
|
||||
region_select_mode: ctx.region_select_mode,
|
||||
pending_graph_loads: ctx.pending_graph_loads,
|
||||
editing_clip_id: ctx.editing_clip_id,
|
||||
editing_instance_id: ctx.editing_instance_id,
|
||||
editing_parent_layer_id: ctx.editing_parent_layer_id,
|
||||
|
|
|
|||
|
|
@ -237,6 +237,10 @@ pub struct SharedPaneState<'a> {
|
|||
pub region_selection: &'a mut Option<lightningbeam_core::selection::RegionSelection>,
|
||||
/// Region select mode (Rectangle or Lasso)
|
||||
pub region_select_mode: &'a mut lightningbeam_core::tool::RegionSelectMode,
|
||||
/// Counter for in-flight graph preset loads — increment when sending a
|
||||
/// GraphLoadPreset command so the repaint loop stays alive until the
|
||||
/// audio thread sends GraphPresetLoaded back
|
||||
pub pending_graph_loads: &'a std::sync::Arc<std::sync::atomic::AtomicU32>,
|
||||
}
|
||||
|
||||
/// Trait for pane rendering
|
||||
|
|
|
|||
|
|
@ -191,8 +191,9 @@ impl PresetBrowserPane {
|
|||
let mut controller = audio_controller.lock().unwrap();
|
||||
controller.graph_load_preset(track_id, preset.path.to_string_lossy().to_string());
|
||||
}
|
||||
|
||||
*shared.project_generation += 1;
|
||||
// Note: project_generation is incremented by the GraphPresetLoaded event handler
|
||||
// in main.rs, which fires after the audio thread has actually processed the load.
|
||||
// This avoids a race where the node graph queries stale backend state.
|
||||
}
|
||||
|
||||
/// Render the save preset dialog
|
||||
|
|
@ -509,6 +510,9 @@ impl PaneRenderer for PresetBrowserPane {
|
|||
// Deferred actions after ScrollArea borrow is released
|
||||
if let Some(idx) = load_index {
|
||||
self.load_preset(idx, shared);
|
||||
// Signal that we're expecting a GraphPresetLoaded event so the
|
||||
// repaint loop stays alive until the audio thread responds.
|
||||
shared.pending_graph_loads.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
if let Some(path) = delete_path {
|
||||
if let Err(e) = std::fs::remove_file(&path) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue