request_timeline_redraw()

This commit is contained in:
Martin Kavík 2024-07-08 02:23:48 +02:00
parent 24e0e30d3e
commit f873ed6587
7 changed files with 64 additions and 16 deletions

View file

@ -8,7 +8,7 @@ mod controls_panel;
use controls_panel::ControlsPanel; use controls_panel::ControlsPanel;
mod waveform_panel; mod waveform_panel;
use waveform_panel::WaveformPanel; use waveform_panel::{PixiController, WaveformPanel};
mod header_panel; mod header_panel;
use header_panel::HeaderPanel; use header_panel::HeaderPanel;
@ -27,6 +27,7 @@ struct Store {
selected_var_refs: MutableVec<wellen::VarRef>, selected_var_refs: MutableVec<wellen::VarRef>,
hierarchy: Mutable<Option<Arc<wellen::Hierarchy>>>, hierarchy: Mutable<Option<Arc<wellen::Hierarchy>>>,
loaded_filename: Mutable<Option<Filename>>, loaded_filename: Mutable<Option<Filename>>,
canvas_controller: Mutable<Mutable<Option<SendWrapper<PixiController>>>>,
} }
static STORE: Lazy<Store> = lazy::default(); static STORE: Lazy<Store> = lazy::default();
@ -45,6 +46,7 @@ fn root() -> impl Element {
let selected_var_refs = STORE.selected_var_refs.clone(); let selected_var_refs = STORE.selected_var_refs.clone();
let layout: Mutable<Layout> = <_>::default(); let layout: Mutable<Layout> = <_>::default();
let loaded_filename = STORE.loaded_filename.clone(); let loaded_filename = STORE.loaded_filename.clone();
let canvas_controller = STORE.canvas_controller.clone();
Column::new() Column::new()
.s(Height::fill()) .s(Height::fill())
.s(Scrollbars::y_and_clip_x()) .s(Scrollbars::y_and_clip_x())
@ -69,13 +71,15 @@ fn root() -> impl Element {
let hierarchy = hierarchy.clone(); let hierarchy = hierarchy.clone();
let selected_var_refs = selected_var_refs.clone(); let selected_var_refs = selected_var_refs.clone();
let loaded_filename = loaded_filename.clone(); let loaded_filename = loaded_filename.clone();
let canvas_controller = canvas_controller.clone();
map_ref!{ map_ref!{
let layout = layout.signal(), let layout = layout.signal(),
let hierarchy_is_some = hierarchy.signal_ref(Option::is_some) => { let hierarchy_is_some = hierarchy.signal_ref(Option::is_some) => {
(*hierarchy_is_some && matches!(layout, Layout::Tree)).then(clone!((hierarchy, selected_var_refs, loaded_filename) move || WaveformPanel::new( (*hierarchy_is_some && matches!(layout, Layout::Tree)).then(clone!((hierarchy, selected_var_refs, loaded_filename, canvas_controller) move || WaveformPanel::new(
hierarchy.clone(), hierarchy.clone(),
selected_var_refs.clone(), selected_var_refs.clone(),
loaded_filename.clone(), loaded_filename.clone(),
canvas_controller.clone(),
))) )))
} }
} }
@ -85,10 +89,11 @@ fn root() -> impl Element {
map_ref!{ map_ref!{
let layout = layout.signal(), let layout = layout.signal(),
let hierarchy_is_some = hierarchy.signal_ref(Option::is_some) => { let hierarchy_is_some = hierarchy.signal_ref(Option::is_some) => {
(*hierarchy_is_some && matches!(layout, Layout::Columns)).then(clone!((hierarchy, selected_var_refs, loaded_filename) move || WaveformPanel::new( (*hierarchy_is_some && matches!(layout, Layout::Columns)).then(clone!((hierarchy, selected_var_refs, loaded_filename, canvas_controller) move || WaveformPanel::new(
hierarchy.clone(), hierarchy.clone(),
selected_var_refs.clone(), selected_var_refs.clone(),
loaded_filename.clone(), loaded_filename.clone(),
canvas_controller.clone(),
))) )))
} }
} }

View file

@ -3,6 +3,8 @@
// NOTE: `FASTWAVE_PLATFORM` is set in `Makefile.toml` tasks and then in `build.rs` // NOTE: `FASTWAVE_PLATFORM` is set in `Makefile.toml` tasks and then in `build.rs`
use crate::STORE;
#[cfg(FASTWAVE_PLATFORM = "TAURI")] #[cfg(FASTWAVE_PLATFORM = "TAURI")]
mod tauri; mod tauri;
#[cfg(FASTWAVE_PLATFORM = "TAURI")] #[cfg(FASTWAVE_PLATFORM = "TAURI")]
@ -63,9 +65,23 @@ pub async fn unload_signal(signal_ref: wellen::SignalRef) {
} }
pub async fn add_decoders(decoder_paths: Vec<DecoderPath>) -> AddedDecodersCount { pub async fn add_decoders(decoder_paths: Vec<DecoderPath>) -> AddedDecodersCount {
platform::add_decoders(decoder_paths).await let count = platform::add_decoders(decoder_paths).await;
if count > 0 {
redraw_all_timeline_rows().await;
}
count
} }
pub async fn remove_all_decoders() -> RemovedDecodersCount { pub async fn remove_all_decoders() -> RemovedDecodersCount {
platform::remove_all_decoders().await let count = platform::remove_all_decoders().await;
if count > 0 {
redraw_all_timeline_rows().await;
}
count
}
async fn redraw_all_timeline_rows() {
if let Some(controller) = STORE.canvas_controller.get_cloned().get_cloned() {
controller.redraw_all_rows().await
}
} }

View file

@ -4,7 +4,8 @@ use wellen::GetItem;
use zoon::*; use zoon::*;
mod pixi_canvas; mod pixi_canvas;
use pixi_canvas::{PixiCanvas, PixiController}; use pixi_canvas::PixiCanvas;
pub use pixi_canvas::PixiController;
const ROW_HEIGHT: u32 = 40; const ROW_HEIGHT: u32 = 40;
const ROW_GAP: u32 = 4; const ROW_GAP: u32 = 4;
@ -14,7 +15,7 @@ pub struct WaveformPanel {
selected_var_refs: MutableVec<wellen::VarRef>, selected_var_refs: MutableVec<wellen::VarRef>,
hierarchy: Mutable<Option<Arc<wellen::Hierarchy>>>, hierarchy: Mutable<Option<Arc<wellen::Hierarchy>>>,
loaded_filename: Mutable<Option<Filename>>, loaded_filename: Mutable<Option<Filename>>,
canvas_controller: Mutable<ReadOnlyMutable<Option<PixiController>>>, canvas_controller: Mutable<Mutable<Option<SendWrapper<PixiController>>>>,
} }
impl WaveformPanel { impl WaveformPanel {
@ -22,12 +23,13 @@ impl WaveformPanel {
hierarchy: Mutable<Option<Arc<wellen::Hierarchy>>>, hierarchy: Mutable<Option<Arc<wellen::Hierarchy>>>,
selected_var_refs: MutableVec<wellen::VarRef>, selected_var_refs: MutableVec<wellen::VarRef>,
loaded_filename: Mutable<Option<Filename>>, loaded_filename: Mutable<Option<Filename>>,
canvas_controller: Mutable<Mutable<Option<SendWrapper<PixiController>>>>,
) -> impl Element { ) -> impl Element {
Self { Self {
selected_var_refs, selected_var_refs,
hierarchy, hierarchy,
loaded_filename, loaded_filename,
canvas_controller: Mutable::new(Mutable::default().read_only()), canvas_controller,
} }
.root() .root()
} }

View file

@ -5,7 +5,7 @@ use zoon::*;
pub struct PixiCanvas { pub struct PixiCanvas {
raw_el: RawHtmlEl<web_sys::HtmlElement>, raw_el: RawHtmlEl<web_sys::HtmlElement>,
controller: ReadOnlyMutable<Option<js_bridge::PixiController>>, controller: Mutable<Option<SendWrapper<js_bridge::PixiController>>>,
#[allow(dead_code)] #[allow(dead_code)]
width: ReadOnlyMutable<u32>, width: ReadOnlyMutable<u32>,
#[allow(dead_code)] #[allow(dead_code)]
@ -32,7 +32,8 @@ impl HasIds for PixiCanvas {}
impl PixiCanvas { impl PixiCanvas {
pub fn new(row_height: u32, row_gap: u32) -> Self { pub fn new(row_height: u32, row_gap: u32) -> Self {
let controller: Mutable<Option<js_bridge::PixiController>> = Mutable::new(None); let controller: Mutable<Option<SendWrapper<js_bridge::PixiController>>> =
Mutable::new(None);
let width = Mutable::new(0); let width = Mutable::new(0);
let height = Mutable::new(0); let height = Mutable::new(0);
let resize_task = Task::start_droppable( let resize_task = Task::start_droppable(
@ -77,7 +78,7 @@ impl PixiCanvas {
)); ));
// -- // -- // -- // --
Self { Self {
controller: controller.read_only(), controller: controller.clone(),
width: width.read_only(), width: width.read_only(),
height: height.read_only(), height: height.read_only(),
task_with_controller: task_with_controller.clone(), task_with_controller: task_with_controller.clone(),
@ -105,14 +106,14 @@ impl PixiCanvas {
}) })
.after_insert(clone!((controller, timeline_getter) move |element| { .after_insert(clone!((controller, timeline_getter) move |element| {
Task::start(async move { Task::start(async move {
let pixi_controller = js_bridge::PixiController::new( let pixi_controller = SendWrapper::new(js_bridge::PixiController::new(
1., 1.,
width.get(), width.get(),
0, 0,
row_height, row_height,
row_gap, row_gap,
&timeline_getter &timeline_getter
); ));
pixi_controller.init(&element).await; pixi_controller.init(&element).await;
controller.set(Some(pixi_controller)); controller.set(Some(pixi_controller));
}); });
@ -131,7 +132,7 @@ impl PixiCanvas {
pub fn task_with_controller<FUT: Future<Output = ()> + 'static>( pub fn task_with_controller<FUT: Future<Output = ()> + 'static>(
self, self,
f: impl FnOnce(ReadOnlyMutable<Option<js_bridge::PixiController>>) -> FUT, f: impl FnOnce(Mutable<Option<SendWrapper<js_bridge::PixiController>>>) -> FUT,
) -> Self { ) -> Self {
self.task_with_controller self.task_with_controller
.set(Some(Task::start_droppable(f(self.controller.clone())))); .set(Some(Task::start_droppable(f(self.controller.clone()))));
@ -186,6 +187,8 @@ mod js_bridge {
#[wasm_bindgen(method)] #[wasm_bindgen(method)]
pub fn destroy(this: &PixiController); pub fn destroy(this: &PixiController);
// -- FastWave-specific --
#[wasm_bindgen(method)] #[wasm_bindgen(method)]
pub fn get_timeline_zoom(this: &PixiController) -> f64; pub fn get_timeline_zoom(this: &PixiController) -> f64;
@ -195,8 +198,6 @@ mod js_bridge {
#[wasm_bindgen(method)] #[wasm_bindgen(method)]
pub fn get_timeline_viewport_x(this: &PixiController) -> i32; pub fn get_timeline_viewport_x(this: &PixiController) -> i32;
// -- FastWave-specific --
#[wasm_bindgen(method)] #[wasm_bindgen(method)]
pub fn set_var_format(this: &PixiController, index: usize, var_format: JsValue); pub fn set_var_format(this: &PixiController, index: usize, var_format: JsValue);
@ -224,5 +225,8 @@ mod js_bridge {
#[wasm_bindgen(method)] #[wasm_bindgen(method)]
pub fn clear_vars(this: &PixiController); pub fn clear_vars(this: &PixiController);
#[wasm_bindgen(method)]
pub async fn redraw_all_rows(this: &PixiController);
} }
} }

View file

@ -35265,6 +35265,8 @@ var PixiController = class {
clear_vars() { clear_vars() {
this.var_signal_rows.slice().reverse().forEach((row) => row.destroy()); this.var_signal_rows.slice().reverse().forEach((row) => row.destroy());
} }
request_timeline_redraw() {
}
}; };
var VarSignalRow = class { var VarSignalRow = class {
signal_ref_index; signal_ref_index;

View file

@ -199,6 +199,10 @@ export class PixiController {
clear_vars() { clear_vars() {
this.var_signal_rows.slice().reverse().forEach(row => row.destroy()); this.var_signal_rows.slice().reverse().forEach(row => row.destroy());
} }
request_timeline_redraw() {
}
} }
class VarSignalRow { class VarSignalRow {

View file

@ -59,10 +59,25 @@ pub async fn remove_all_decoders() -> RemovedDecodersCount {
// @TODO Remove / improve comments below // @TODO Remove / improve comments below
// Testing // Testing
//
// Rust
// FW.add_decoders(["../test_files/components/rust_decoder/rust_decoder.wasm"]) // 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"]) // 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"]) // FW.add_decoders(["../test_files/components/javascript_decoder/javascript_decoder.wasm"])
//
// Python
// FW.add_decoders(["../test_files/components/python_decoder/python_decoder.wasm"]) // 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 { pub async fn add_decoders(decoder_paths: Vec<DecoderPath>) -> AddedDecodersCount {
println!("decoders in Tauri: {decoder_paths:#?}"); println!("decoders in Tauri: {decoder_paths:#?}");
println!("Current dir: {:#?}", std::env::current_dir().unwrap()); println!("Current dir: {:#?}", std::env::current_dir().unwrap());