// SonicForge DAW — desktop shell: spawn/terminate daw_engine.exe sidecar. use tauri::Manager; use tauri_plugin_shell::process::CommandChild; use tauri_plugin_shell::ShellExt; use std::sync::Mutex; struct EngineProcess(Mutex>); #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() .plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_dialog::init()) .setup(|app| { // 1. Spawn daw_engine (PyInstaller ONEDIR bundle — khong giai nen // moi lan chay nhu onefile, khoi dong nhanh). Bundle qua Tauri // resources: resource_dir()/daw_engine/daw_engine(.exe) let res_dir = app .path() .resource_dir() .expect("resource dir not found"); let engine_dir = res_dir.join("daw_engine"); let engine_exe = if cfg!(windows) { engine_dir.join("daw_engine.exe") } else { engine_dir.join("daw_engine") }; let (_rx, child) = app .shell() .command(engine_exe) .env("SF_PARENT_PID", std::process::id().to_string()) .spawn() .expect("Failed to spawn daw_engine (onedir resource) — run build_windows.ps1 first"); app.manage(EngineProcess(Mutex::new(Some(child)))); println!("Python Background Engine started (localhost:8000, auto-fallback 8000-8010)"); Ok(()) }) .on_window_event(|window, event| { // 2. Terminate sidecar khi DAW window dong — tranh orphan process if let tauri::WindowEvent::Destroyed = event { // Lay child ra khoi lock, guard drop ngay tai day (trach E0597) let child = window .state::() .0 .lock() .ok() .and_then(|mut lock| lock.take()); if let Some(child) = child { let _ = child.kill(); println!("daw_engine sidecar terminated."); } } }) .run(tauri::generate_context!()) .expect("error while running tauri application"); }