save selected vars

This commit is contained in:
Martin Kavík 2024-06-19 01:43:31 +02:00
parent 54b1d0799e
commit e7aa41ce1f
5 changed files with 56 additions and 7 deletions

View file

@ -63,17 +63,19 @@ fn root() -> impl Element {
hierarchy.clone(), hierarchy.clone(),
selected_var_refs.clone(), selected_var_refs.clone(),
layout.clone(), layout.clone(),
loaded_filename, loaded_filename.clone(),
)) ))
.item_signal({ .item_signal({
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();
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) move || WaveformPanel::new( (*hierarchy_is_some && matches!(layout, Layout::Tree)).then(clone!((hierarchy, selected_var_refs, loaded_filename) move || WaveformPanel::new(
hierarchy.clone(), hierarchy.clone(),
selected_var_refs.clone(), selected_var_refs.clone(),
loaded_filename.clone(),
))) )))
} }
} }
@ -83,9 +85,10 @@ 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) move || WaveformPanel::new( (*hierarchy_is_some && matches!(layout, Layout::Columns)).then(clone!((hierarchy, selected_var_refs, loaded_filename) move || WaveformPanel::new(
hierarchy.clone(), hierarchy.clone(),
selected_var_refs.clone(), selected_var_refs.clone(),
loaded_filename.clone(),
))) )))
} }
} }

View file

@ -1,4 +1,4 @@
use crate::{platform, script_bridge}; use crate::{platform, script_bridge, Filename};
use std::sync::Arc; use std::sync::Arc;
use wellen::GetItem; use wellen::GetItem;
use zoon::*; use zoon::*;
@ -13,6 +13,7 @@ const ROW_GAP: u32 = 4;
pub struct WaveformPanel { 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>>,
canvas_controller: Mutable<ReadOnlyMutable<Option<PixiController>>>, canvas_controller: Mutable<ReadOnlyMutable<Option<PixiController>>>,
} }
@ -20,10 +21,12 @@ impl WaveformPanel {
pub fn new( pub fn new(
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>>,
) -> impl Element { ) -> impl Element {
Self { Self {
selected_var_refs, selected_var_refs,
hierarchy, hierarchy,
loaded_filename,
canvas_controller: Mutable::new(Mutable::default().read_only()), canvas_controller: Mutable::new(Mutable::default().read_only()),
} }
.root() .root()
@ -167,6 +170,9 @@ impl WaveformPanel {
fn save_selected_vars_button(&self) -> impl Element { fn save_selected_vars_button(&self) -> impl Element {
let (hovered, hovered_signal) = Mutable::new_and_signal(false); let (hovered, hovered_signal) = Mutable::new_and_signal(false);
let loaded_filename = self.loaded_filename.clone();
let selected_var_refs = self.selected_var_refs.clone();
let hierarchy = self.hierarchy.clone();
Button::new() Button::new()
.s(Padding::new().x(20).y(10)) .s(Padding::new().x(20).y(10))
.s(Background::new().color_signal( .s(Background::new().color_signal(
@ -175,7 +181,34 @@ impl WaveformPanel {
.s(RoundedCorners::all(15)) .s(RoundedCorners::all(15))
.label("Save") .label("Save")
.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 || zoon::println!("SAVE!")) .on_press(move || {
let loaded_filename = loaded_filename.get_cloned().unwrap_throw();
let file_name = format!("{}_vars.fw.js", loaded_filename.replace('.', "_"));
let hierarchy = hierarchy.get_cloned().unwrap_throw();
let mut full_var_names = Vec::new();
for var_ref in selected_var_refs.lock_ref().as_slice() {
let var = hierarchy.get(*var_ref);
let var_name = var.full_name(&hierarchy);
full_var_names.push(format!("\"{var_name}\""));
}
let full_var_names_string = full_var_names.join(",\n\t\t");
let file_content = include_str!("waveform_panel/template_vars.px.js")
.replacen("{LOADED_FILENAME}", &loaded_filename, 1)
.replacen("{FULL_VAR_NAMES}", &full_var_names_string, 1);
// @TODO we need to use ugly code with temp anchor element until (if ever)
// `showSaveFilePicker` is supported in Safari and Firefox (https://caniuse.com/?search=showSaveFilePicker)
let file = gloo_file::File::new(&file_name, file_content.as_str());
let file_object_url = gloo_file::ObjectUrl::from(file);
let a = document().create_element("a").unwrap_throw();
a.set_attribute("href", &file_object_url).unwrap_throw();
a.set_attribute("download", &file_name).unwrap_throw();
a.set_attribute("style", "display: none;").unwrap_throw();
dom::body().append_child(&a).unwrap_throw();
a.unchecked_ref::<web_sys::HtmlElement>().click();
a.remove();
})
} }
// @TODO autoscroll down // @TODO autoscroll down

View file

@ -0,0 +1,5 @@
if (FW.loaded_filename() === "{LOADED_FILENAME}") {
FW.select_vars([
{FULL_VAR_NAMES}
])
}

View file

@ -1,7 +1,7 @@
if (FW.loaded_filename() === "simple.vcd") { if (FW.loaded_filename() === "simple.vcd") {
FW.select_vars([ FW.select_vars([
"simple_tb.s.A", "simple_tb.s.A",
"simple_tb.s.A", "simple_tb.s.A",
"simple_tb.s.B" "simple_tb.s.B"
]) ])
} }

View file

@ -0,0 +1,8 @@
if (FW.loaded_filename() === "wave_27.fst") {
FW.select_vars([
"TOP.LsuPlugin_logic_bus_rsp_payload_error",
"TOP.LsuPlugin_logic_bus_rsp_payload_data",
"TOP.VexiiRiscv.integer_RegFilePlugin_logic_regfile_fpga.ramAsyncMwMux_1.io_writes_0_payload_data",
"TOP.VexiiRiscv.EmbeddedRiscvJtag_logic_onDebugCd_dmiDirect_logic.logic_jtagLogic_dmiStat_value_string"
])
}