remove HierarchyAndTimeTable

This commit is contained in:
Martin Kavík 2024-06-07 23:18:06 +02:00
parent 4906634ffb
commit bc023d38b8
11 changed files with 50 additions and 88 deletions

View file

@ -1,5 +1,4 @@
use crate::{platform, HierarchyAndTimeTable, Layout};
use futures_util::join;
use crate::{platform, Layout};
use std::cell::Cell;
use std::mem;
use std::ops::Not;
@ -35,7 +34,7 @@ struct ScopeForUI {
#[derive(Clone)]
pub struct ControlsPanel {
selected_scope_ref: Mutable<Option<wellen::ScopeRef>>,
hierarchy_and_time_table: Mutable<Option<HierarchyAndTimeTable>>,
hierarchy: Mutable<Option<Rc<wellen::Hierarchy>>>,
selected_var_refs: MutableVec<wellen::VarRef>,
layout: Mutable<Layout>,
loaded_filename: Mutable<Option<Filename>>,
@ -43,13 +42,13 @@ pub struct ControlsPanel {
impl ControlsPanel {
pub fn new(
hierarchy_and_time_table: Mutable<Option<HierarchyAndTimeTable>>,
hierarchy: Mutable<Option<Rc<wellen::Hierarchy>>>,
selected_var_refs: MutableVec<wellen::VarRef>,
layout: Mutable<Layout>,
) -> impl Element {
Self {
selected_scope_ref: <_>::default(),
hierarchy_and_time_table,
hierarchy,
selected_var_refs,
layout,
loaded_filename: <_>::default(),
@ -60,7 +59,7 @@ impl ControlsPanel {
fn triggers(&self) -> Vec<TaskHandle> {
vec![Task::start_droppable(clone!((self => s) async move {
let was_some = Cell::new(false);
s.hierarchy_and_time_table
s.hierarchy
.signal_ref(Option::is_some)
.dedupe()
.for_each_sync(clone!((s) move |is_some| {
@ -81,8 +80,8 @@ impl ControlsPanel {
let layout = self.layout.clone();
let layout_and_hierarchy_signal = map_ref! {
let layout = layout.signal(),
let hierarchy_and_time_table = self.hierarchy_and_time_table.signal_cloned() => {
(*layout, hierarchy_and_time_table.clone().map(|(hierarchy, _)| hierarchy))
let hierarchy = self.hierarchy.signal_cloned() => {
(*layout, hierarchy.clone())
}
};
Column::new()
@ -110,9 +109,9 @@ impl ControlsPanel {
.item(self.layout_switcher()),
)
.item_signal(
self.hierarchy_and_time_table
self.hierarchy
.signal_cloned()
.map_some(clone!((self => s) move |(hierarchy, _)| s.scopes_panel(hierarchy))),
.map_some(clone!((self => s) move |hierarchy| s.scopes_panel(hierarchy))),
)
.item_signal(layout_and_hierarchy_signal.map(
clone!((self => s) move |(layout, hierarchy)| {
@ -126,7 +125,7 @@ impl ControlsPanel {
#[cfg(FASTWAVE_PLATFORM = "TAURI")]
fn load_button(&self) -> impl Element {
let (hovered, hovered_signal) = Mutable::new_and_signal(false);
let hierarchy_and_time_table = self.hierarchy_and_time_table.clone();
let hierarchy = self.hierarchy.clone();
let loaded_filename = self.loaded_filename.clone();
Button::new()
.s(Padding::new().x(20).y(10))
@ -143,21 +142,18 @@ impl ControlsPanel {
))
.on_hovered_change(move |is_hovered| hovered.set_neq(is_hovered))
.on_press(move || {
let mut hierarchy_and_time_table_lock = hierarchy_and_time_table.lock_mut();
if hierarchy_and_time_table_lock.is_some() {
*hierarchy_and_time_table_lock = None;
let mut hierarchy_lock = hierarchy.lock_mut();
if hierarchy_lock.is_some() {
*hierarchy_lock = None;
return;
}
drop(hierarchy_and_time_table_lock);
let hierarchy_and_time_table = hierarchy_and_time_table.clone();
drop(hierarchy_lock);
let hierarchy = hierarchy.clone();
let loaded_filename = loaded_filename.clone();
Task::start(async move {
if let Some(filename) = platform::pick_and_load_waveform(None).await {
loaded_filename.set_neq(Some(filename));
let (hierarchy, time_table) =
join!(platform::get_hierarchy(), platform::get_time_table());
hierarchy_and_time_table
.set(Some((Rc::new(hierarchy), Rc::new(time_table))))
hierarchy.set(Some(Rc::new(platform::get_hierarchy().await)))
}
})
})
@ -166,7 +162,7 @@ impl ControlsPanel {
#[cfg(FASTWAVE_PLATFORM = "BROWSER")]
fn load_button(&self) -> impl Element {
let (hovered, hovered_signal) = Mutable::new_and_signal(false);
let hierarchy_and_time_table = self.hierarchy_and_time_table.clone();
let hierarchy = self.hierarchy.clone();
let loaded_filename = self.loaded_filename.clone();
let file_input_id = "file_input";
Row::new()
@ -187,10 +183,10 @@ impl ControlsPanel {
))
.on_hovered_change(move |is_hovered| hovered.set_neq(is_hovered))
.for_input(file_input_id)
.on_click_event_with_options(EventOptions::new().preventable(), clone!((hierarchy_and_time_table) move |event| {
let mut hierarchy_and_time_table_lock = hierarchy_and_time_table.lock_mut();
if hierarchy_and_time_table_lock.is_some() {
*hierarchy_and_time_table_lock = None;
.on_click_event_with_options(EventOptions::new().preventable(), clone!((hierarchy) move |event| {
let mut hierarchy_lock = hierarchy.lock_mut();
if hierarchy_lock.is_some() {
*hierarchy_lock = None;
if let RawMouseEvent::Click(raw_event) = event.raw_event {
// @TODO Move to MoonZoon as a new API
raw_event.prevent_default();
@ -218,14 +214,14 @@ impl ControlsPanel {
zoon::println!("file list is empty");
return;
};
let hierarchy_and_time_table = hierarchy_and_time_table.clone();
let hierarchy = hierarchy.clone();
let loaded_filename = loaded_filename.clone();
Task::start(async move {
if let Some(filename) = platform::pick_and_load_waveform(Some(file)).await {
loaded_filename.set_neq(Some(filename));
let (hierarchy, time_table) =
join!(platform::get_hierarchy(), platform::get_time_table());
hierarchy_and_time_table
hierarchy
.set(Some((Rc::new(hierarchy), Rc::new(time_table))))
}
})

View file

@ -1,5 +1,5 @@
use std::rc::Rc;
use zoon::*;
use std::rc::Rc;
mod platform;
@ -9,8 +9,6 @@ use controls_panel::ControlsPanel;
mod waveform_panel;
use waveform_panel::WaveformPanel;
type HierarchyAndTimeTable = (Rc<wellen::Hierarchy>, Rc<wellen::TimeTable>);
#[derive(Clone, Copy, Default)]
enum Layout {
Tree,
@ -28,7 +26,7 @@ fn main() {
}
fn root() -> impl Element {
let hierarchy_and_time_table: Mutable<Option<HierarchyAndTimeTable>> = <_>::default();
let hierarchy: Mutable<Option<Rc<wellen::Hierarchy>>> = <_>::default();
let selected_var_refs: MutableVec<wellen::VarRef> = <_>::default();
let layout: Mutable<Layout> = <_>::default();
Column::new()
@ -40,17 +38,17 @@ fn root() -> impl Element {
.s(Height::fill())
.s(Gap::new().x(15))
.item(ControlsPanel::new(
hierarchy_and_time_table.clone(),
hierarchy.clone(),
selected_var_refs.clone(),
layout.clone(),
))
.item_signal(layout.signal().map(|layout| matches!(layout, Layout::Tree)).map_true(clone!((hierarchy_and_time_table, selected_var_refs) move || WaveformPanel::new(
hierarchy_and_time_table.clone(),
.item_signal(layout.signal().map(|layout| matches!(layout, Layout::Tree)).map_true(clone!((hierarchy, selected_var_refs) move || WaveformPanel::new(
hierarchy.clone(),
selected_var_refs.clone(),
))))
)
.item_signal(layout.signal().map(|layout| matches!(layout, Layout::Columns)).map_true(move || WaveformPanel::new(
hierarchy_and_time_table.clone(),
hierarchy.clone(),
selected_var_refs.clone(),
)))
}

View file

@ -29,10 +29,6 @@ pub async fn get_hierarchy() -> wellen::Hierarchy {
platform::get_hierarchy().await
}
pub async fn get_time_table() -> wellen::TimeTable {
platform::get_time_table().await
}
pub async fn load_signal_and_get_timeline(
signal_ref: wellen::SignalRef,
screen_width: u32,

View file

@ -74,13 +74,6 @@ pub(super) async fn get_hierarchy() -> wellen::Hierarchy {
serde_json::from_value(serde_json::to_value(hierarchy).unwrap_throw()).unwrap_throw()
}
pub(super) async fn get_time_table() -> wellen::TimeTable {
let waveform = STORE.waveform.lock().unwrap_throw();
let time_table = waveform.as_ref().unwrap_throw().time_table();
// @TODO Wrap `time_table` in `Waveform` with `Rc/Arc` or add the method `take` / `clone` or refactor?
serde_json::from_value(serde_json::to_value(time_table).unwrap_throw()).unwrap_throw()
}
pub(super) async fn load_signal_and_get_timeline(
signal_ref: wellen::SignalRef,
screen_width: u32,

View file

@ -17,10 +17,6 @@ pub(super) async fn get_hierarchy() -> wellen::Hierarchy {
serde_wasm_bindgen::from_value(tauri_glue::get_hierarchy().await.unwrap_throw()).unwrap_throw()
}
pub(super) async fn get_time_table() -> wellen::TimeTable {
serde_wasm_bindgen::from_value(tauri_glue::get_time_table().await.unwrap_throw()).unwrap_throw()
}
pub(super) async fn load_signal_and_get_timeline(
signal_ref: wellen::SignalRef,
screen_width: u32,
@ -55,9 +51,6 @@ mod tauri_glue {
#[wasm_bindgen(catch)]
pub async fn get_hierarchy() -> Result<JsValue, JsValue>;
#[wasm_bindgen(catch)]
pub async fn get_time_table() -> Result<JsValue, JsValue>;
#[wasm_bindgen(catch)]
pub async fn load_signal_and_get_timeline(
signal_ref_index: usize,

View file

@ -1,4 +1,5 @@
use crate::{platform, HierarchyAndTimeTable};
use crate::platform;
use std::rc::Rc;
use wellen::GetItem;
use zoon::*;
@ -11,17 +12,17 @@ const ROW_GAP: u32 = 4;
#[derive(Clone)]
pub struct WaveformPanel {
selected_var_refs: MutableVec<wellen::VarRef>,
hierarchy_and_time_table: Mutable<Option<HierarchyAndTimeTable>>,
hierarchy: Mutable<Option<Rc<wellen::Hierarchy>>>,
}
impl WaveformPanel {
pub fn new(
hierarchy_and_time_table: Mutable<Option<HierarchyAndTimeTable>>,
hierarchy: Mutable<Option<Rc<wellen::Hierarchy>>>,
selected_var_refs: MutableVec<wellen::VarRef>,
) -> impl Element {
Self {
selected_var_refs,
hierarchy_and_time_table,
hierarchy,
}
.root()
}
@ -52,26 +53,26 @@ impl WaveformPanel {
fn canvas(&self, selected_vars_panel_height: ReadOnlyMutable<u32>) -> impl Element {
let selected_var_refs = self.selected_var_refs.clone();
let hierarchy_and_time_table = self.hierarchy_and_time_table.clone();
let hierarchy = self.hierarchy.clone();
PixiCanvas::new(ROW_HEIGHT, ROW_GAP)
.s(Align::new().top())
.s(Width::fill())
.s(Height::exact_signal(selected_vars_panel_height.signal()))
.task_with_controller(move |controller| {
selected_var_refs.signal_vec().delay_remove(clone!((hierarchy_and_time_table) move |var_ref| {
clone!((var_ref, hierarchy_and_time_table) async move {
if let Some(hierarchy_and_time_table) = hierarchy_and_time_table.get_cloned() {
platform::unload_signal(hierarchy_and_time_table.0.get(var_ref).signal_ref()).await;
selected_var_refs.signal_vec().delay_remove(clone!((hierarchy) move |var_ref| {
clone!((var_ref, hierarchy) async move {
if let Some(hierarchy) = hierarchy.get_cloned() {
platform::unload_signal(hierarchy.get(var_ref).signal_ref()).await;
}
})
})).for_each(clone!((controller, hierarchy_and_time_table) move |vec_diff| {
clone!((controller, hierarchy_and_time_table) async move {
})).for_each(clone!((controller, hierarchy) move |vec_diff| {
clone!((controller, hierarchy) async move {
match vec_diff {
VecDiff::Replace { values } => {
let controller = controller.wait_for_some_cloned().await;
controller.clear_vars();
for var_ref in values {
Self::push_var(&controller, &hierarchy_and_time_table, var_ref).await;
Self::push_var(&controller, &hierarchy, var_ref).await;
}
},
VecDiff::InsertAt { index: _, value: _ } => { todo!("`task_with_controller` + `InsertAt`") }
@ -84,7 +85,7 @@ impl WaveformPanel {
VecDiff::Move { old_index: _, new_index: _ } => { todo!("`task_with_controller` + `Move`") }
VecDiff::Push { value: var_ref } => {
if let Some(controller) = controller.lock_ref().as_ref() {
Self::push_var(controller, &hierarchy_and_time_table, var_ref).await;
Self::push_var(controller, &hierarchy, var_ref).await;
}
}
VecDiff::Pop {} => {
@ -105,10 +106,10 @@ impl WaveformPanel {
async fn push_var(
controller: &PixiController,
hierarchy_and_time_table: &Mutable<Option<HierarchyAndTimeTable>>,
hierarchy: &Mutable<Option<Rc<wellen::Hierarchy>>>,
var_ref: wellen::VarRef,
) {
let (hierarchy, time_table) = hierarchy_and_time_table.get_cloned().unwrap();
let hierarchy = hierarchy.get_cloned().unwrap();
let var = hierarchy.get(var_ref);
let signal_ref = var.signal_ref();
@ -134,7 +135,7 @@ impl WaveformPanel {
index: ReadOnlyMutable<Option<usize>>,
var_ref: wellen::VarRef,
) -> Option<impl Element> {
let Some((hierarchy, _)) = self.hierarchy_and_time_table.get_cloned() else {
let Some(hierarchy) = self.hierarchy.get_cloned() else {
None?
};
let var = hierarchy.get(var_ref);

View file

@ -35152,12 +35152,12 @@ var PixiController = class {
// Default automatic Pixi resizing according to the parent is not reliable
// and the `app.renderer`'s `resize` event is fired on every browser window size change
async resize(width, height) {
this.app.resize();
const width_changed = width !== this.previous_parent_width;
this.previous_parent_width = width;
if (width_changed) {
await this.redraw_rows();
}
this.app.resize();
}
destroy() {
const rendererDestroyOptions = {

View file

@ -2520,9 +2520,6 @@ async function pick_and_load_waveform() {
async function get_hierarchy() {
return await invoke2("get_hierarchy");
}
async function get_time_table() {
return await invoke2("get_time_table");
}
async function load_signal_and_get_timeline(signal_ref_index, screen_width, block_height) {
return await invoke2("load_signal_and_get_timeline", { signal_ref_index, screen_width, block_height });
}
@ -2531,7 +2528,6 @@ async function unload_signal(signal_ref_index) {
}
export {
get_hierarchy,
get_time_table,
load_signal_and_get_timeline,
pick_and_load_waveform,
show_window,

View file

@ -46,13 +46,14 @@ export class PixiController {
// Default automatic Pixi resizing according to the parent is not reliable
// and the `app.renderer`'s `resize` event is fired on every browser window size change
async resize(width: number, height: number) {
this.app.resize();
// -- FastWave-specific --
const width_changed = width !== this.previous_parent_width;
this.previous_parent_width = width;
if (width_changed) {
await this.redraw_rows();
}
// -- // --
this.app.resize();
}
destroy() {

View file

@ -22,10 +22,6 @@ export async function get_hierarchy(): Promise<WellenHierarchy> {
return await invoke("get_hierarchy");
}
export async function get_time_table(): Promise<WellenTimeTable> {
return await invoke("get_time_table");
}
export async function load_signal_and_get_timeline(signal_ref_index: number, screen_width: number, block_height: number): Promise<Timeline> {
return await invoke("load_signal_and_get_timeline", { signal_ref_index, screen_width, block_height });
}

View file

@ -39,13 +39,6 @@ async fn get_hierarchy(store: tauri::State<'_, Store>) -> Result<serde_json::Val
Ok(serde_json::to_value(hierarchy).unwrap())
}
#[tauri::command(rename_all = "snake_case")]
async fn get_time_table(store: tauri::State<'_, Store>) -> Result<serde_json::Value, ()> {
let waveform = store.waveform.lock().unwrap();
let time_table = waveform.as_ref().unwrap().time_table();
Ok(serde_json::to_value(time_table).unwrap())
}
#[tauri::command(rename_all = "snake_case")]
async fn load_signal_and_get_timeline(
signal_ref_index: usize,
@ -53,7 +46,7 @@ async fn load_signal_and_get_timeline(
block_height: u32,
store: tauri::State<'_, Store>,
) -> Result<serde_json::Value, ()> {
// @TODO run (all?) in a blocking thread
// @TODO run (all?) in a blocking thread?
let signal_ref = wellen::SignalRef::from_index(signal_ref_index).unwrap();
let mut waveform_lock = store.waveform.lock().unwrap();
let waveform = waveform_lock.as_mut().unwrap();
@ -88,7 +81,6 @@ pub fn run() {
show_window,
pick_and_load_waveform,
get_hierarchy,
get_time_table,
load_signal_and_get_timeline,
unload_signal,
])