diff --git a/Cargo.lock b/Cargo.lock index 3fd5a28..e499807 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1691,6 +1691,7 @@ checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" name = "fastwave" version = "0.1.0" dependencies = [ + "once_cell", "serde", "serde_json", "shared", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 2822864..f0b386c 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -23,6 +23,7 @@ serde = { version = "1.0", features = ["derive"] } tauri = { version = "=2.0.0-beta.22", features = ["macos-private-api", "linux-ipc-protocol"] } tauri-plugin-window-state = "=2.0.0-beta.9" tauri-plugin-dialog = "=2.0.0-beta.9" +once_cell = "1.19.0" # wasmtime = "22.0.0" # wasmtime-wasi = "22.0.0" diff --git a/src-tauri/src/component_manager.rs b/src-tauri/src/component_manager.rs index 942bcb1..6cc3a5d 100644 --- a/src-tauri/src/component_manager.rs +++ b/src-tauri/src/component_manager.rs @@ -1,10 +1,32 @@ use crate::{AddedDecodersCount, DecoderPath, RemovedDecodersCount}; use wasmtime::component::{Component as WasmtimeComponent, *}; -use wasmtime::{Engine, Store}; +use wasmtime::{AsContextMut, Engine, Store}; use wasmtime_wasi::{WasiCtx, WasiView}; +use once_cell::sync::Lazy; +use tauri::async_runtime::Mutex; +use std::sync::Arc; bindgen!(); +static DECODERS: Lazy>>> = Lazy::new(<_>::default); +static ENGINE: Lazy = Lazy::new(<_>::default); +static LINKER: Lazy> = Lazy::new(|| { + let mut linker = Linker::new(&ENGINE); + wasmtime_wasi::add_to_linker_sync(&mut linker).unwrap(); + Component::add_to_linker(&mut linker, |state: &mut State| state).unwrap(); + linker +}); +static STORE: Lazy>>> = Lazy::new(|| { + let store = Store::new( + &ENGINE, + State { + ctx: WasiCtx::builder().build(), + table: ResourceTable::new(), + }, + ); + Arc::new(Mutex::new(store)) +}); + struct State { ctx: WasiCtx, table: ResourceTable, @@ -25,11 +47,14 @@ impl component::decoder::host::Host for State { } } -pub fn remove_all_decoders() -> RemovedDecodersCount { - 156 +pub async fn remove_all_decoders() -> RemovedDecodersCount { + let mut decoders = DECODERS.lock().await; + let decoders_count = decoders.len(); + decoders.clear(); + decoders_count } -// @TODO Make println work on Windows? +// @TODO Make println work on Windows in release mode? // https://github.com/tauri-apps/tauri/discussions/8626 // @TODO Remove / improve comments below @@ -37,42 +62,28 @@ pub fn remove_all_decoders() -> RemovedDecodersCount { // FW.add_decoders(["../test_files/components/rust_decoder/rust_decoder.wasm"]) // FW.add_decoders(["../test_files/components/javascript_decoder/javascript_decoder.wasm"]) // FW.add_decoders(["../test_files/components/python_decoder/python_decoder.wasm"]) -pub fn add_decoders(decoder_paths: Vec) -> AddedDecodersCount { +pub async fn add_decoders(decoder_paths: Vec) -> AddedDecodersCount { println!("decoders in Tauri: {decoder_paths:#?}"); println!("Current dir: {:#?}", std::env::current_dir().unwrap()); let decoder_paths_len = decoder_paths.len(); // New thread to prevent panics caused by running runtime in runtime - // @TODO replace with Tokio's spawn_blocking? - std::thread::spawn(move || { - if let Err(error) = add_decoder(&decoder_paths[0]) { + tauri::async_runtime::spawn_blocking(move || async move { + if let Err(error) = add_decoder(&decoder_paths[0]).await { eprintln!("add_decoders error: {error:?}"); } - }) - .join() - .unwrap(); + }).await.unwrap().await; decoder_paths_len } -fn add_decoder(path: &str) -> wasmtime::Result<()> { - let engine = Engine::default(); +async fn add_decoder(path: &str) -> wasmtime::Result<()> { + let wasmtime_component = WasmtimeComponent::from_file(&ENGINE, path)?; - let wasmtime_component = WasmtimeComponent::from_file(&engine, path)?; + let mut store_lock = STORE.lock().await; + let mut store = store_lock.as_context_mut(); - let mut linker = Linker::new(&engine); - wasmtime_wasi::add_to_linker_sync(&mut linker)?; - Component::add_to_linker(&mut linker, |state: &mut State| state)?; - - let mut store = Store::new( - &engine, - State { - ctx: WasiCtx::builder().build(), - table: ResourceTable::new(), - }, - ); - - let component = Component::instantiate(&mut store, &wasmtime_component, &linker)?; + let component = Component::instantiate(&mut store, &wasmtime_component, &LINKER)?; println!( "Decoder name: {}", @@ -84,5 +95,7 @@ fn add_decoder(path: &str) -> wasmtime::Result<()> { .component_decoder_decoder() .call_init(&mut store)?; + DECODERS.lock().await.push(component); + Ok(()) } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 9e07f01..9dc98c6 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -98,12 +98,12 @@ async fn unload_signal(signal_ref_index: usize, store: tauri::State<'_, Store>) #[tauri::command(rename_all = "snake_case")] async fn add_decoders(decoder_paths: Vec) -> Result { - Ok(component_manager::add_decoders(decoder_paths)) + Ok(component_manager::add_decoders(decoder_paths).await) } #[tauri::command(rename_all = "snake_case")] async fn remove_all_decoders() -> Result { - Ok(component_manager::remove_all_decoders()) + Ok(component_manager::remove_all_decoders().await) } #[cfg_attr(mobile, tauri::mobile_entry_point)]