diagram plugins
This commit is contained in:
parent
1cdb558823
commit
e8a0051ea7
29 changed files with 1781 additions and 267 deletions
|
@ -1,125 +1,2 @@
|
|||
use crate::{AddedDecodersCount, DecoderPath, RemovedDecodersCount};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::sync::Arc;
|
||||
use tauri::async_runtime::{Mutex, RwLock};
|
||||
use wasmtime::component::{Component as WasmtimeComponent, *};
|
||||
use wasmtime::{AsContextMut, Engine, Store};
|
||||
use wasmtime_wasi::{WasiCtx, WasiView};
|
||||
|
||||
bindgen!();
|
||||
|
||||
pub static DECODERS: Lazy<Arc<RwLock<Vec<Component>>>> = Lazy::new(<_>::default);
|
||||
static ENGINE: Lazy<Engine> = Lazy::new(<_>::default);
|
||||
static LINKER: Lazy<Linker<State>> = 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
|
||||
});
|
||||
pub static STORE: Lazy<Arc<Mutex<Store<State>>>> = Lazy::new(|| {
|
||||
let store = Store::new(
|
||||
&ENGINE,
|
||||
State {
|
||||
ctx: WasiCtx::builder().build(),
|
||||
table: ResourceTable::new(),
|
||||
},
|
||||
);
|
||||
Arc::new(Mutex::new(store))
|
||||
});
|
||||
|
||||
pub struct State {
|
||||
ctx: WasiCtx,
|
||||
table: ResourceTable,
|
||||
}
|
||||
|
||||
impl WasiView for State {
|
||||
fn ctx(&mut self) -> &mut WasiCtx {
|
||||
&mut self.ctx
|
||||
}
|
||||
fn table(&mut self) -> &mut ResourceTable {
|
||||
&mut self.table
|
||||
}
|
||||
}
|
||||
|
||||
impl component::decoder::host::Host for State {
|
||||
fn log(&mut self, message: String) {
|
||||
println!("Decoder: {message}");
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn remove_all_decoders() -> RemovedDecodersCount {
|
||||
let mut decoders = DECODERS.write().await;
|
||||
let decoders_count = decoders.len();
|
||||
decoders.clear();
|
||||
decoders_count
|
||||
}
|
||||
|
||||
// @TODO Make println work on Windows in release mode?
|
||||
// https://github.com/tauri-apps/tauri/discussions/8626
|
||||
|
||||
// @TODO Remove / improve comments below
|
||||
// Testing
|
||||
//
|
||||
// Rust
|
||||
// FW.add_decoders(["../test_files/components/rust_decoder/rust_decoder.wasm"])
|
||||
// FW.add_decoders(["../test_files/components/rust_decoder/rust_decoder.wasm", "../test_files/components/rust_decoder/rust_decoder.wasm"])
|
||||
//
|
||||
// JS
|
||||
// FW.add_decoders(["../test_files/components/javascript_decoder/javascript_decoder.wasm"])
|
||||
//
|
||||
// Python
|
||||
// FW.add_decoders(["../test_files/components/python_decoder/python_decoder.wasm"])
|
||||
//
|
||||
// Remove all
|
||||
// FW.remove_all_decoders()
|
||||
//
|
||||
// All Debug
|
||||
// FW.add_decoders(["../test_files/components/rust_decoder/rust_decoder.wasm", "../test_files/components/javascript_decoder/javascript_decoder.wasm", "../test_files/components/python_decoder/python_decoder.wasm"])
|
||||
//
|
||||
// All Release
|
||||
// FW.add_decoders(["../../test_files/components/rust_decoder/rust_decoder.wasm", "../../test_files/components/javascript_decoder/javascript_decoder.wasm", "../../test_files/components/python_decoder/python_decoder.wasm"])
|
||||
pub async fn add_decoders(decoder_paths: Vec<DecoderPath>) -> AddedDecodersCount {
|
||||
println!("Decoders: {decoder_paths:#?}");
|
||||
println!("Current dir: {:#?}", std::env::current_dir().unwrap());
|
||||
|
||||
let mut added_decoders_count = 0;
|
||||
|
||||
// @TODO (?) New thread to prevent "Cannot start a runtime from within a runtime."
|
||||
// when a call to a component fails / panics
|
||||
// std::thread::spawn(move || {
|
||||
// futures::executor::block_on(async move {
|
||||
for decoder_path in decoder_paths {
|
||||
if let Err(error) = add_decoder(&decoder_path).await {
|
||||
eprintln!("add_decoders error: {error:?}");
|
||||
} else {
|
||||
added_decoders_count += 1;
|
||||
}
|
||||
}
|
||||
// })
|
||||
// }).join().unwrap();
|
||||
|
||||
added_decoders_count
|
||||
}
|
||||
|
||||
async fn add_decoder(path: &str) -> wasmtime::Result<()> {
|
||||
let wasmtime_component = WasmtimeComponent::from_file(&ENGINE, path)?;
|
||||
|
||||
let mut store_lock = STORE.lock().await;
|
||||
let mut store = store_lock.as_context_mut();
|
||||
|
||||
let component = Component::instantiate(&mut store, &wasmtime_component, &LINKER)?;
|
||||
|
||||
println!(
|
||||
"Decoder name: {}",
|
||||
component
|
||||
.component_decoder_decoder()
|
||||
.call_name(&mut store)?
|
||||
);
|
||||
component
|
||||
.component_decoder_decoder()
|
||||
.call_init(&mut store)?;
|
||||
|
||||
DECODERS.write().await.push(component);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub mod decoders;
|
||||
pub mod diagram_connectors;
|
||||
|
|
125
src-tauri/src/component_manager/decoders.rs
Normal file
125
src-tauri/src/component_manager/decoders.rs
Normal file
|
@ -0,0 +1,125 @@
|
|||
use crate::{AddedDecodersCount, DecoderPath, RemovedDecodersCount};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::sync::Arc;
|
||||
use tauri::async_runtime::{Mutex, RwLock};
|
||||
use wasmtime::component::{Component as WasmtimeComponent, *};
|
||||
use wasmtime::{AsContextMut, Engine, Store};
|
||||
use wasmtime_wasi::{WasiCtx, WasiView};
|
||||
|
||||
bindgen!(in "wit/decoder");
|
||||
|
||||
pub static DECODERS: Lazy<Arc<RwLock<Vec<Component>>>> = Lazy::new(<_>::default);
|
||||
static ENGINE: Lazy<Engine> = Lazy::new(<_>::default);
|
||||
static LINKER: Lazy<Linker<State>> = 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
|
||||
});
|
||||
pub static STORE: Lazy<Arc<Mutex<Store<State>>>> = Lazy::new(|| {
|
||||
let store = Store::new(
|
||||
&ENGINE,
|
||||
State {
|
||||
ctx: WasiCtx::builder().build(),
|
||||
table: ResourceTable::new(),
|
||||
},
|
||||
);
|
||||
Arc::new(Mutex::new(store))
|
||||
});
|
||||
|
||||
pub struct State {
|
||||
ctx: WasiCtx,
|
||||
table: ResourceTable,
|
||||
}
|
||||
|
||||
impl WasiView for State {
|
||||
fn ctx(&mut self) -> &mut WasiCtx {
|
||||
&mut self.ctx
|
||||
}
|
||||
fn table(&mut self) -> &mut ResourceTable {
|
||||
&mut self.table
|
||||
}
|
||||
}
|
||||
|
||||
impl component::decoder::host::Host for State {
|
||||
fn log(&mut self, message: String) {
|
||||
println!("Decoder: {message}");
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn remove_all_decoders() -> RemovedDecodersCount {
|
||||
let mut decoders = DECODERS.write().await;
|
||||
let decoders_count = decoders.len();
|
||||
decoders.clear();
|
||||
decoders_count
|
||||
}
|
||||
|
||||
// @TODO Make println work on Windows in release mode?
|
||||
// https://github.com/tauri-apps/tauri/discussions/8626
|
||||
|
||||
// @TODO Remove / improve comments below
|
||||
// Testing
|
||||
//
|
||||
// Rust
|
||||
// FW.add_decoders(["../test_files/components/rust_decoder/rust_decoder.wasm"])
|
||||
// FW.add_decoders(["../test_files/components/rust_decoder/rust_decoder.wasm", "../test_files/components/rust_decoder/rust_decoder.wasm"])
|
||||
//
|
||||
// JS
|
||||
// FW.add_decoders(["../test_files/components/javascript_decoder/javascript_decoder.wasm"])
|
||||
//
|
||||
// Python
|
||||
// FW.add_decoders(["../test_files/components/python_decoder/python_decoder.wasm"])
|
||||
//
|
||||
// Remove all
|
||||
// FW.remove_all_decoders()
|
||||
//
|
||||
// All Debug
|
||||
// FW.add_decoders(["../test_files/components/rust_decoder/rust_decoder.wasm", "../test_files/components/javascript_decoder/javascript_decoder.wasm", "../test_files/components/python_decoder/python_decoder.wasm"])
|
||||
//
|
||||
// All Release
|
||||
// FW.add_decoders(["../../test_files/components/rust_decoder/rust_decoder.wasm", "../../test_files/components/javascript_decoder/javascript_decoder.wasm", "../../test_files/components/python_decoder/python_decoder.wasm"])
|
||||
pub async fn add_decoders(decoder_paths: Vec<DecoderPath>) -> AddedDecodersCount {
|
||||
println!("Decoders: {decoder_paths:#?}");
|
||||
println!("Current dir: {:#?}", std::env::current_dir().unwrap());
|
||||
|
||||
let mut added_decoders_count = 0;
|
||||
|
||||
// @TODO (?) New thread to prevent "Cannot start a runtime from within a runtime."
|
||||
// when a call to a component fails / panics
|
||||
// std::thread::spawn(move || {
|
||||
// futures::executor::block_on(async move {
|
||||
for decoder_path in decoder_paths {
|
||||
if let Err(error) = add_decoder(&decoder_path).await {
|
||||
eprintln!("add_decoders error: {error:?}");
|
||||
} else {
|
||||
added_decoders_count += 1;
|
||||
}
|
||||
}
|
||||
// })
|
||||
// }).join().unwrap();
|
||||
|
||||
added_decoders_count
|
||||
}
|
||||
|
||||
async fn add_decoder(path: &str) -> wasmtime::Result<()> {
|
||||
let wasmtime_component = WasmtimeComponent::from_file(&ENGINE, path)?;
|
||||
|
||||
let mut store_lock = STORE.lock().await;
|
||||
let mut store = store_lock.as_context_mut();
|
||||
|
||||
let component = Component::instantiate(&mut store, &wasmtime_component, &LINKER)?;
|
||||
|
||||
println!(
|
||||
"Decoder name: {}",
|
||||
component
|
||||
.component_decoder_decoder()
|
||||
.call_name(&mut store)?
|
||||
);
|
||||
component
|
||||
.component_decoder_decoder()
|
||||
.call_init(&mut store)?;
|
||||
|
||||
DECODERS.write().await.push(component);
|
||||
|
||||
Ok(())
|
||||
}
|
273
src-tauri/src/component_manager/diagram_connectors.rs
Normal file
273
src-tauri/src/component_manager/diagram_connectors.rs
Normal file
|
@ -0,0 +1,273 @@
|
|||
use crate::{
|
||||
AddedDiagramConnectorsCount, ComponentId, DiagramConnectorName, DiagramConnectorPath,
|
||||
RemovedDiagramConnectorsCount, APP_HANDLE, WAVEFORM,
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
use shared::{DiagramConnectorMessage, VarFormat};
|
||||
use std::sync::Arc;
|
||||
use tauri::async_runtime::{Mutex, RwLock};
|
||||
use tauri::Manager;
|
||||
use wasmtime::component::{Component as WasmtimeComponent, *};
|
||||
use wasmtime::{AsContextMut, Engine, Store};
|
||||
use wasmtime_wasi::{WasiCtx, WasiView};
|
||||
use wellen::GetItem;
|
||||
|
||||
bindgen!(in "wit/diagram_connector");
|
||||
|
||||
pub static DIAGRAM_CONNECTORS: Lazy<Arc<RwLock<Vec<Component>>>> = Lazy::new(<_>::default);
|
||||
static ENGINE: Lazy<Engine> = Lazy::new(<_>::default);
|
||||
static LINKER: Lazy<Linker<State>> = 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
|
||||
});
|
||||
pub static STORE: Lazy<Arc<Mutex<Store<State>>>> = Lazy::new(|| {
|
||||
let store = Store::new(
|
||||
&ENGINE,
|
||||
State {
|
||||
ctx: WasiCtx::builder().build(),
|
||||
table: ResourceTable::new(),
|
||||
},
|
||||
);
|
||||
Arc::new(Mutex::new(store))
|
||||
});
|
||||
|
||||
pub struct State {
|
||||
ctx: WasiCtx,
|
||||
table: ResourceTable,
|
||||
}
|
||||
|
||||
impl WasiView for State {
|
||||
fn ctx(&mut self) -> &mut WasiCtx {
|
||||
&mut self.ctx
|
||||
}
|
||||
fn table(&mut self) -> &mut ResourceTable {
|
||||
&mut self.table
|
||||
}
|
||||
}
|
||||
|
||||
impl component::diagram_connector::host::Host for State {
|
||||
fn log(&mut self, message: String) {
|
||||
println!("Diagram Connector: {message}");
|
||||
}
|
||||
|
||||
fn listen_for_component_text_changes(
|
||||
&mut self,
|
||||
diagram_connector_name: String,
|
||||
component_id: String,
|
||||
) {
|
||||
let message = DiagramConnectorMessage::ListenForComponentTextChanges {
|
||||
diagram_connector_name,
|
||||
component_id,
|
||||
};
|
||||
APP_HANDLE
|
||||
.read()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.emit("diagram_connector_message", message)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn set_component_text(&mut self, component_id: String, text: String) {
|
||||
let message = DiagramConnectorMessage::SetComponentText { component_id, text };
|
||||
APP_HANDLE
|
||||
.read()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.emit("diagram_connector_message", message)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// @TODO `resource` in WIT or async in the future
|
||||
// @TODO move business logic to the diagram connector
|
||||
fn address_and_way(&mut self, time_text: String) -> Result<(String, Option<u32>), ()> {
|
||||
let input_time = time_text.parse::<u64>().map_err(|error| {
|
||||
eprintln!("Failed to parse time_text '{time_text}', error: {error:#}");
|
||||
})?;
|
||||
|
||||
let waveform_wrapper = WAVEFORM.read().unwrap();
|
||||
let mut maybe_waveform = waveform_wrapper.try_write().unwrap();
|
||||
let waveform = maybe_waveform.as_mut().unwrap();
|
||||
|
||||
let hierarchy = waveform.hierarchy();
|
||||
|
||||
// @TODO remove
|
||||
// let timescale = hierarchy.timescale().unwrap();
|
||||
// println!("Timescale: {timescale:#?}");
|
||||
|
||||
let refill_valid_ref = hierarchy
|
||||
.lookup_var(
|
||||
&["TOP", "VexiiRiscv"],
|
||||
&"FetchL1Plugin_logic_refill_start_valid",
|
||||
)
|
||||
.unwrap();
|
||||
let refill_address_ref = hierarchy
|
||||
.lookup_var(
|
||||
&["TOP", "VexiiRiscv"],
|
||||
&"FetchL1Plugin_logic_refill_start_address",
|
||||
)
|
||||
.unwrap();
|
||||
let refill_way_ref = hierarchy
|
||||
.lookup_var(
|
||||
&["TOP", "VexiiRiscv"],
|
||||
&"FetchL1Plugin_logic_refill_start_wayToAllocate",
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let refill_valid_var = hierarchy.get(refill_valid_ref);
|
||||
let refill_address_var = hierarchy.get(refill_address_ref);
|
||||
let refill_way_var = hierarchy.get(refill_way_ref);
|
||||
|
||||
let refill_valid_signal_ref = refill_valid_var.signal_ref();
|
||||
let refill_address_signal_ref = refill_address_var.signal_ref();
|
||||
let refill_way_signal_ref = refill_way_var.signal_ref();
|
||||
|
||||
let mut time_table_idx = None;
|
||||
for (idx, time) in waveform.time_table().iter().enumerate() {
|
||||
if *time >= input_time {
|
||||
time_table_idx = Some(idx as u32);
|
||||
break;
|
||||
}
|
||||
}
|
||||
let Some(time_table_idx) = time_table_idx else {
|
||||
eprintln!("time_table_idx is None");
|
||||
Err(())?
|
||||
};
|
||||
|
||||
waveform.load_signals_multi_threaded(&[
|
||||
refill_valid_signal_ref,
|
||||
refill_address_signal_ref,
|
||||
refill_way_signal_ref,
|
||||
]);
|
||||
|
||||
let refill_valid_signal = waveform.get_signal(refill_valid_signal_ref).unwrap();
|
||||
let refill_valid_offset = refill_valid_signal.get_offset(time_table_idx).unwrap();
|
||||
let refill_valid_value = refill_valid_signal
|
||||
.get_value_at(&refill_valid_offset, 0)
|
||||
.to_string();
|
||||
|
||||
let refill_address_signal = waveform.get_signal(refill_address_signal_ref).unwrap();
|
||||
let refill_address_offset = refill_address_signal.get_offset(time_table_idx).unwrap();
|
||||
let refill_address_value = refill_address_signal.get_value_at(&refill_address_offset, 0);
|
||||
let refill_address_value = VarFormat::Hexadecimal.format(refill_address_value);
|
||||
|
||||
if refill_valid_value == "0" {
|
||||
return Ok((refill_address_value, None));
|
||||
}
|
||||
|
||||
let refill_way_signal = waveform.get_signal(refill_way_signal_ref).unwrap();
|
||||
let refill_way_offset = refill_way_signal.get_offset(time_table_idx).unwrap();
|
||||
let refill_way_value = refill_way_signal.get_value_at(&refill_way_offset, 0);
|
||||
let refill_way_value = VarFormat::Unsigned.format(refill_way_value);
|
||||
|
||||
Ok((
|
||||
refill_address_value,
|
||||
Some(refill_way_value.parse().unwrap()),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn remove_all_diagram_connectors() -> RemovedDiagramConnectorsCount {
|
||||
let mut diagram_connectors = DIAGRAM_CONNECTORS.write().await;
|
||||
let diagram_connectors_count = diagram_connectors.len();
|
||||
diagram_connectors.clear();
|
||||
diagram_connectors_count
|
||||
}
|
||||
|
||||
// @TODO Make println work on Windows in release mode?
|
||||
// https://github.com/tauri-apps/tauri/discussions/8626
|
||||
|
||||
// @TODO Remove / improve comments below
|
||||
// Testing
|
||||
//
|
||||
// Rust
|
||||
// FW.add_diagram_connectors(["../test_files/components/rust_diagram_connector/rust_diagram_connector.wasm"])
|
||||
//
|
||||
// Remove all
|
||||
// FW.remove_all_diagram_connectors()
|
||||
//
|
||||
// All Debug
|
||||
// FW.add_diagram_connectors(["../test_files/components/rust_diagram_connector/rust_diagram_connector.wasm"])
|
||||
//
|
||||
// All Release
|
||||
// FW.add_diagram_connectors(["../../test_files/components/rust_diagram_connector/rust_diagram_connector.wasm"])
|
||||
pub async fn add_diagram_connectors(
|
||||
diagram_connector_paths: Vec<DiagramConnectorPath>,
|
||||
) -> AddedDiagramConnectorsCount {
|
||||
println!("Diagram Connectors: {diagram_connector_paths:#?}");
|
||||
println!("Current dir: {:#?}", std::env::current_dir().unwrap());
|
||||
|
||||
let mut added_diagram_connectors_count = 0;
|
||||
|
||||
// @TODO (?) New thread to prevent "Cannot start a runtime from within a runtime."
|
||||
// when a call to a component fails / panics
|
||||
// std::thread::spawn(move || {
|
||||
// futures::executor::block_on(async move {
|
||||
for diagram_connector_path in diagram_connector_paths {
|
||||
if let Err(error) = add_diagram_connector(&diagram_connector_path).await {
|
||||
eprintln!("add_diagram_connectors error: {error:?}");
|
||||
} else {
|
||||
added_diagram_connectors_count += 1;
|
||||
}
|
||||
}
|
||||
// })
|
||||
// }).join().unwrap();
|
||||
|
||||
added_diagram_connectors_count
|
||||
}
|
||||
|
||||
async fn add_diagram_connector(path: &str) -> wasmtime::Result<()> {
|
||||
let wasmtime_component = WasmtimeComponent::from_file(&ENGINE, path)?;
|
||||
|
||||
let mut store_lock = STORE.lock().await;
|
||||
let mut store = store_lock.as_context_mut();
|
||||
|
||||
let component = Component::instantiate(&mut store, &wasmtime_component, &LINKER)?;
|
||||
|
||||
println!(
|
||||
"Diagram Connector name: {}",
|
||||
component
|
||||
.component_diagram_connector_diagram_connector()
|
||||
.call_name(&mut store)?
|
||||
);
|
||||
component
|
||||
.component_diagram_connector_diagram_connector()
|
||||
.call_init(&mut store)?;
|
||||
|
||||
DIAGRAM_CONNECTORS.write().await.push(component);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// @TODO rename `ComponentId` everywhere to something like `DiagramElementId`?
|
||||
// @TODO get rid of unwraps
|
||||
pub async fn notify_diagram_connector_text_change(
|
||||
diagram_connector: DiagramConnectorName,
|
||||
component_id: ComponentId,
|
||||
text: String,
|
||||
) {
|
||||
let mut store_lock = STORE.lock().await;
|
||||
let mut store = store_lock.as_context_mut();
|
||||
|
||||
let diagram_connectors = DIAGRAM_CONNECTORS.read().await;
|
||||
|
||||
// @TODO store diagram_collectors in a hashmap/btreemap?
|
||||
let diagram_connector = diagram_connectors
|
||||
.iter()
|
||||
.find(|diagram_collector| {
|
||||
let name = diagram_collector
|
||||
.component_diagram_connector_diagram_connector()
|
||||
.call_name(&mut store)
|
||||
.unwrap();
|
||||
name == diagram_connector
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
diagram_connector
|
||||
.component_diagram_connector_diagram_connector()
|
||||
.call_on_component_text_changed(&mut store, &component_id, &text)
|
||||
.unwrap();
|
||||
}
|
|
@ -1,20 +1,32 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use std::fs;
|
||||
use tauri::async_runtime::RwLock;
|
||||
use std::sync::{Arc, RwLock as StdRwLock};
|
||||
use tauri::{async_runtime::RwLock, AppHandle};
|
||||
use tauri_plugin_dialog::DialogExt;
|
||||
use wasmtime::AsContextMut;
|
||||
use wellen::simple::Waveform;
|
||||
|
||||
type Filename = String;
|
||||
type JavascriptCode = String;
|
||||
|
||||
type AddedDecodersCount = usize;
|
||||
type RemovedDecodersCount = usize;
|
||||
type DecoderPath = String;
|
||||
|
||||
type AddedDiagramConnectorsCount = usize;
|
||||
type RemovedDiagramConnectorsCount = usize;
|
||||
type DiagramConnectorPath = String;
|
||||
type DiagramConnectorName = String;
|
||||
type ComponentId = String;
|
||||
|
||||
mod component_manager;
|
||||
|
||||
pub static APP_HANDLE: Lazy<Arc<StdRwLock<Option<AppHandle>>>> = Lazy::new(<_>::default);
|
||||
pub static WAVEFORM: Lazy<StdRwLock<Arc<RwLock<Option<Waveform>>>>> = Lazy::new(<_>::default);
|
||||
|
||||
#[derive(Default)]
|
||||
struct Store {
|
||||
waveform: RwLock<Option<Waveform>>,
|
||||
waveform: Arc<RwLock<Option<Waveform>>>,
|
||||
}
|
||||
|
||||
#[tauri::command(rename_all = "snake_case")]
|
||||
|
@ -37,6 +49,7 @@ async fn pick_and_load_waveform(
|
|||
panic!("Waveform file reading failed")
|
||||
};
|
||||
*store.waveform.write().await = Some(waveform);
|
||||
*WAVEFORM.write().unwrap() = Arc::clone(&store.waveform);
|
||||
Ok(Some(file_response.name.unwrap()))
|
||||
}
|
||||
|
||||
|
@ -92,8 +105,8 @@ async fn load_signal_and_get_timeline(
|
|||
// @TODO Workaround? Is it a problem only for non-Rust components? Is it needed only when there is a problem in the component (e.g. "`Err` value: wasm trap: cannot enter component instance"?)
|
||||
// let value = std::thread::spawn(move || {
|
||||
// futures::executor::block_on(async move {
|
||||
let decoders = component_manager::DECODERS.read().await;
|
||||
let mut store_lock = component_manager::STORE.lock().await;
|
||||
let decoders = component_manager::decoders::DECODERS.read().await;
|
||||
let mut store_lock = component_manager::decoders::STORE.lock().await;
|
||||
let mut store = store_lock.as_context_mut();
|
||||
|
||||
for decoder in decoders.iter() {
|
||||
|
@ -127,12 +140,43 @@ 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<DecoderPath>) -> Result<AddedDecodersCount, ()> {
|
||||
Ok(component_manager::add_decoders(decoder_paths).await)
|
||||
Ok(component_manager::decoders::add_decoders(decoder_paths).await)
|
||||
}
|
||||
|
||||
#[tauri::command(rename_all = "snake_case")]
|
||||
async fn remove_all_decoders() -> Result<RemovedDecodersCount, ()> {
|
||||
Ok(component_manager::remove_all_decoders().await)
|
||||
Ok(component_manager::decoders::remove_all_decoders().await)
|
||||
}
|
||||
|
||||
#[tauri::command(rename_all = "snake_case")]
|
||||
async fn add_diagram_connectors(
|
||||
diagram_connector_paths: Vec<DiagramConnectorPath>,
|
||||
) -> Result<AddedDiagramConnectorsCount, ()> {
|
||||
Ok(
|
||||
component_manager::diagram_connectors::add_diagram_connectors(diagram_connector_paths)
|
||||
.await,
|
||||
)
|
||||
}
|
||||
|
||||
#[tauri::command(rename_all = "snake_case")]
|
||||
async fn remove_all_diagram_connectors() -> Result<RemovedDiagramConnectorsCount, ()> {
|
||||
Ok(component_manager::diagram_connectors::remove_all_diagram_connectors().await)
|
||||
}
|
||||
|
||||
#[tauri::command(rename_all = "snake_case")]
|
||||
async fn notify_diagram_connector_text_change(
|
||||
diagram_connector: DiagramConnectorName,
|
||||
component_id: ComponentId,
|
||||
text: String,
|
||||
) -> Result<(), ()> {
|
||||
Ok(
|
||||
component_manager::diagram_connectors::notify_diagram_connector_text_change(
|
||||
diagram_connector,
|
||||
component_id,
|
||||
text,
|
||||
)
|
||||
.await,
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
|
@ -145,7 +189,7 @@ pub fn run() {
|
|||
.manage(Store::default())
|
||||
.plugin(tauri_plugin_window_state::Builder::default().build())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
// Npte: Add all handlers to `frontend/src/tauri_bridge.rs`
|
||||
// Note: Add all handlers to `frontend/src/tauri_bridge.rs`
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
show_window,
|
||||
pick_and_load_waveform,
|
||||
|
@ -155,7 +199,14 @@ pub fn run() {
|
|||
unload_signal,
|
||||
add_decoders,
|
||||
remove_all_decoders,
|
||||
add_diagram_connectors,
|
||||
remove_all_diagram_connectors,
|
||||
notify_diagram_connector_text_change,
|
||||
])
|
||||
.setup(|app| {
|
||||
*APP_HANDLE.write().unwrap() = Some(app.handle().to_owned());
|
||||
Ok(())
|
||||
})
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
|
19
src-tauri/wit/diagram_connector/world.wit
Normal file
19
src-tauri/wit/diagram_connector/world.wit
Normal file
|
@ -0,0 +1,19 @@
|
|||
package component:diagram-connector;
|
||||
|
||||
interface host {
|
||||
log: func(message: string);
|
||||
listen-for-component-text-changes: func(diagram-connect-name: string, component-id: string);
|
||||
set-component-text: func(component-id: string, text: string);
|
||||
address-and-way: func(time-text: string) -> result<tuple<string, option<u32>>>;
|
||||
}
|
||||
|
||||
interface diagram-connector {
|
||||
init: func();
|
||||
name: func() -> string;
|
||||
on-component-text-changed: func(component-id: string, text: string);
|
||||
}
|
||||
|
||||
world component {
|
||||
import host;
|
||||
export diagram-connector;
|
||||
}
|
Reference in a new issue