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

View file

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

View file

@ -29,10 +29,6 @@ pub async fn get_hierarchy() -> wellen::Hierarchy {
platform::get_hierarchy().await 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( pub async fn load_signal_and_get_timeline(
signal_ref: wellen::SignalRef, signal_ref: wellen::SignalRef,
screen_width: u32, 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() 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( pub(super) async fn load_signal_and_get_timeline(
signal_ref: wellen::SignalRef, signal_ref: wellen::SignalRef,
screen_width: u32, 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() 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( pub(super) async fn load_signal_and_get_timeline(
signal_ref: wellen::SignalRef, signal_ref: wellen::SignalRef,
screen_width: u32, screen_width: u32,
@ -55,9 +51,6 @@ mod tauri_glue {
#[wasm_bindgen(catch)] #[wasm_bindgen(catch)]
pub async fn get_hierarchy() -> Result<JsValue, JsValue>; pub async fn get_hierarchy() -> Result<JsValue, JsValue>;
#[wasm_bindgen(catch)]
pub async fn get_time_table() -> Result<JsValue, JsValue>;
#[wasm_bindgen(catch)] #[wasm_bindgen(catch)]
pub async fn load_signal_and_get_timeline( pub async fn load_signal_and_get_timeline(
signal_ref_index: usize, 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 wellen::GetItem;
use zoon::*; use zoon::*;
@ -11,17 +12,17 @@ const ROW_GAP: u32 = 4;
#[derive(Clone)] #[derive(Clone)]
pub struct WaveformPanel { pub struct WaveformPanel {
selected_var_refs: MutableVec<wellen::VarRef>, selected_var_refs: MutableVec<wellen::VarRef>,
hierarchy_and_time_table: Mutable<Option<HierarchyAndTimeTable>>, hierarchy: Mutable<Option<Rc<wellen::Hierarchy>>>,
} }
impl WaveformPanel { impl WaveformPanel {
pub fn new( pub fn new(
hierarchy_and_time_table: Mutable<Option<HierarchyAndTimeTable>>, hierarchy: Mutable<Option<Rc<wellen::Hierarchy>>>,
selected_var_refs: MutableVec<wellen::VarRef>, selected_var_refs: MutableVec<wellen::VarRef>,
) -> impl Element { ) -> impl Element {
Self { Self {
selected_var_refs, selected_var_refs,
hierarchy_and_time_table, hierarchy,
} }
.root() .root()
} }
@ -52,26 +53,26 @@ impl WaveformPanel {
fn canvas(&self, selected_vars_panel_height: ReadOnlyMutable<u32>) -> impl Element { fn canvas(&self, selected_vars_panel_height: ReadOnlyMutable<u32>) -> impl Element {
let selected_var_refs = self.selected_var_refs.clone(); 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) PixiCanvas::new(ROW_HEIGHT, ROW_GAP)
.s(Align::new().top()) .s(Align::new().top())
.s(Width::fill()) .s(Width::fill())
.s(Height::exact_signal(selected_vars_panel_height.signal())) .s(Height::exact_signal(selected_vars_panel_height.signal()))
.task_with_controller(move |controller| { .task_with_controller(move |controller| {
selected_var_refs.signal_vec().delay_remove(clone!((hierarchy_and_time_table) move |var_ref| { selected_var_refs.signal_vec().delay_remove(clone!((hierarchy) move |var_ref| {
clone!((var_ref, hierarchy_and_time_table) async move { clone!((var_ref, hierarchy) async move {
if let Some(hierarchy_and_time_table) = hierarchy_and_time_table.get_cloned() { if let Some(hierarchy) = hierarchy.get_cloned() {
platform::unload_signal(hierarchy_and_time_table.0.get(var_ref).signal_ref()).await; platform::unload_signal(hierarchy.get(var_ref).signal_ref()).await;
} }
}) })
})).for_each(clone!((controller, hierarchy_and_time_table) move |vec_diff| { })).for_each(clone!((controller, hierarchy) move |vec_diff| {
clone!((controller, hierarchy_and_time_table) async move { clone!((controller, hierarchy) async move {
match vec_diff { match vec_diff {
VecDiff::Replace { values } => { VecDiff::Replace { values } => {
let controller = controller.wait_for_some_cloned().await; let controller = controller.wait_for_some_cloned().await;
controller.clear_vars(); controller.clear_vars();
for var_ref in values { 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`") } 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::Move { old_index: _, new_index: _ } => { todo!("`task_with_controller` + `Move`") }
VecDiff::Push { value: var_ref } => { VecDiff::Push { value: var_ref } => {
if let Some(controller) = controller.lock_ref().as_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 {} => { VecDiff::Pop {} => {
@ -105,10 +106,10 @@ impl WaveformPanel {
async fn push_var( async fn push_var(
controller: &PixiController, controller: &PixiController,
hierarchy_and_time_table: &Mutable<Option<HierarchyAndTimeTable>>, hierarchy: &Mutable<Option<Rc<wellen::Hierarchy>>>,
var_ref: wellen::VarRef, 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 var = hierarchy.get(var_ref);
let signal_ref = var.signal_ref(); let signal_ref = var.signal_ref();
@ -134,7 +135,7 @@ impl WaveformPanel {
index: ReadOnlyMutable<Option<usize>>, index: ReadOnlyMutable<Option<usize>>,
var_ref: wellen::VarRef, var_ref: wellen::VarRef,
) -> Option<impl Element> { ) -> Option<impl Element> {
let Some((hierarchy, _)) = self.hierarchy_and_time_table.get_cloned() else { let Some(hierarchy) = self.hierarchy.get_cloned() else {
None? None?
}; };
let var = hierarchy.get(var_ref); 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 // 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 // and the `app.renderer`'s `resize` event is fired on every browser window size change
async resize(width, height) { async resize(width, height) {
this.app.resize();
const width_changed = width !== this.previous_parent_width; const width_changed = width !== this.previous_parent_width;
this.previous_parent_width = width; this.previous_parent_width = width;
if (width_changed) { if (width_changed) {
await this.redraw_rows(); await this.redraw_rows();
} }
this.app.resize();
} }
destroy() { destroy() {
const rendererDestroyOptions = { const rendererDestroyOptions = {

View file

@ -2520,9 +2520,6 @@ async function pick_and_load_waveform() {
async function get_hierarchy() { async function get_hierarchy() {
return await invoke2("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) { 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 }); 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 { export {
get_hierarchy, get_hierarchy,
get_time_table,
load_signal_and_get_timeline, load_signal_and_get_timeline,
pick_and_load_waveform, pick_and_load_waveform,
show_window, show_window,

View file

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

View file

@ -22,10 +22,6 @@ export async function get_hierarchy(): Promise<WellenHierarchy> {
return await invoke("get_hierarchy"); 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> { 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 }); 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()) 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")] #[tauri::command(rename_all = "snake_case")]
async fn load_signal_and_get_timeline( async fn load_signal_and_get_timeline(
signal_ref_index: usize, signal_ref_index: usize,
@ -53,7 +46,7 @@ async fn load_signal_and_get_timeline(
block_height: u32, block_height: u32,
store: tauri::State<'_, Store>, store: tauri::State<'_, Store>,
) -> Result<serde_json::Value, ()> { ) -> 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 signal_ref = wellen::SignalRef::from_index(signal_ref_index).unwrap();
let mut waveform_lock = store.waveform.lock().unwrap(); let mut waveform_lock = store.waveform.lock().unwrap();
let waveform = waveform_lock.as_mut().unwrap(); let waveform = waveform_lock.as_mut().unwrap();
@ -88,7 +81,6 @@ pub fn run() {
show_window, show_window,
pick_and_load_waveform, pick_and_load_waveform,
get_hierarchy, get_hierarchy,
get_time_table,
load_signal_and_get_timeline, load_signal_and_get_timeline,
unload_signal, unload_signal,
]) ])