fix(v8): 5 bugs — orphan bridge watchdog+state overwrite, stuck-note stop race, white VST GUI retry, VSTi auto-load via saved plugin_path, track-header button overflow
- native bridge: dedicated watchdog thread (parent death / PID-reuse via GetProcessTimes) -> TerminateProcess self; transportStopped flag drops note-on after STOP + CC64 sustain release + allNotesOff on stop - tauri: set_bridge_child overwrites managed BridgeProcess state (app.manage is no-op when state exists) so Destroyed handler kills restarted bridge - ui: stopAllPlayback syncs isPlayingRef/subTabsRef + second transport stop at 150ms; onStatusChange resets __bridgeLoadedChannels at callback start (auto-restart never emits bridge-down); openVstGuiRetry waits for async C++ load before OPEN_GUI; loadVstToBridge uses synth_engine.plugin_path / listPlugins fallback and persists plugin_path on load; shrink track-header Synth/GUI buttons
This commit is contained in:
+17
-3
@@ -24,6 +24,20 @@ struct EngineProcess(Mutex<Option<CommandChild>>);
|
||||
struct BridgeProcess(Mutex<Option<CommandChild>>);
|
||||
struct BridgeSampleRate(Mutex<u32>);
|
||||
|
||||
/// Overwrite the managed bridge child. `app.manage` is a NO-OP once the state
|
||||
/// exists (StateManager::set keeps the first value), so restarts would leave
|
||||
/// the state at None and the Destroyed handler would never kill the new
|
||||
/// bridge — orphan daw_vst_bridge.exe. First call still uses manage().
|
||||
fn set_bridge_child(app: &AppHandle, child: Option<CommandChild>) {
|
||||
if let Some(state) = app.try_state::<BridgeProcess>() {
|
||||
if let Ok(mut g) = state.0.lock() {
|
||||
*g = child;
|
||||
}
|
||||
} else {
|
||||
app.manage(BridgeProcess(Mutex::new(child)));
|
||||
}
|
||||
}
|
||||
|
||||
/// Kill the currently managed bridge child (if any) — a restart MUST never
|
||||
/// leave the old bridge running, else two daw_vst_bridge.exe race on the same
|
||||
/// SHM (double instrument load, double OPEN_GUI, garbled control queue).
|
||||
@@ -145,7 +159,7 @@ fn spawn_bridge(
|
||||
.spawn()
|
||||
{
|
||||
Ok((mut rx, child)) => {
|
||||
app.manage(BridgeProcess(Mutex::new(Some(child))));
|
||||
set_bridge_child(app, Some(child));
|
||||
// B3: redirect bridge stdout/stderr → %APPDATA%/SonicForgeDAW/logs/bridge.log
|
||||
// (tauri-shell pipe rồi vứt rx; đọc event ghi file — E5 UI tail được).
|
||||
let log_dir = std::env::var("APPDATA").unwrap_or_else(|_| ".".into());
|
||||
@@ -175,14 +189,14 @@ fn spawn_bridge(
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to spawn daw_vst_bridge {bridge_exe:?}: {e}");
|
||||
app.manage(BridgeProcess(Mutex::new(None)));
|
||||
set_bridge_child(app, None);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
println!("daw_vst_bridge binary not found — app will use WASM fallback");
|
||||
app.manage(BridgeProcess(Mutex::new(None)));
|
||||
set_bridge_child(app, None);
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user