From 48dad951a529d3f26ad0be6047e3e725144e3b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kav=C3=ADk?= Date: Mon, 10 Jun 2024 00:27:01 +0200 Subject: [PATCH] signal_to_timeline.rs --- frontend/src/platform/browser.rs | 75 +------------------------------- shared/src/lib.rs | 3 ++ shared/src/signal_to_timeline.rs | 72 ++++++++++++++++++++++++++++++ src-tauri/src/lib.rs | 75 +------------------------------- 4 files changed, 79 insertions(+), 146 deletions(-) create mode 100644 shared/src/signal_to_timeline.rs diff --git a/frontend/src/platform/browser.rs b/frontend/src/platform/browser.rs index 8192d25..bc29666 100644 --- a/frontend/src/platform/browser.rs +++ b/frontend/src/platform/browser.rs @@ -85,7 +85,8 @@ pub(super) async fn load_signal_and_get_timeline( waveform.load_signals_multi_threaded(&[signal_ref]); let signal = waveform.get_signal(signal_ref).unwrap(); let time_table = waveform.time_table(); - let timeline = signal_to_timeline(signal, time_table, screen_width, block_height, var_format); + let timeline = + shared::signal_to_timeline(signal, time_table, screen_width, block_height, var_format); timeline } @@ -94,75 +95,3 @@ pub(super) async fn unload_signal(signal_ref: wellen::SignalRef) { let waveform = waveform_lock.as_mut().unwrap_throw(); waveform.unload_signals(&[signal_ref]); } - -// @TODO keep in sync with the same method in `src-tauri/src/lib.rs` -fn signal_to_timeline( - signal: &wellen::Signal, - time_table: &[wellen::Time], - screen_width: u32, - block_height: u32, - var_format: shared::VarFormat, -) -> shared::Timeline { - const MIN_BLOCK_WIDTH: u32 = 3; - // Courier New, 16px, sync with `label_style` in `pixi_canvas.rs` - const LETTER_WIDTH: f64 = 9.61; - const LETTER_HEIGHT: u32 = 18; - const LABEL_X_PADDING: u32 = 10; - - let Some(last_time) = time_table.last().copied() else { - return shared::Timeline::default(); - }; - - let last_time = last_time as f64; - let screen_width = screen_width as f64; - - let mut x_value_pairs = signal - .iter_changes() - .map(|(index, value)| { - let index = index as usize; - let time = time_table[index] as f64; - let x = time / last_time * screen_width; - (x, value) - }) - .peekable(); - - // @TODO parallelize? - let mut blocks = Vec::new(); - while let Some((block_x, value)) = x_value_pairs.next() { - let next_block_x = if let Some((next_block_x, _)) = x_value_pairs.peek() { - *next_block_x - } else { - screen_width - }; - - let block_width = (next_block_x - block_x) as u32; - if block_width < MIN_BLOCK_WIDTH { - continue; - } - - // @TODO cache? - let value = var_format.format(value); - - let value_width = (value.chars().count() as f64 * LETTER_WIDTH) as u32; - // @TODO Ellipsis instead of hiding? - let label = if (value_width + (2 * LABEL_X_PADDING)) <= block_width { - Some(shared::TimeLineBlockLabel { - text: value, - x: (block_width - value_width) / 2, - y: (block_height - LETTER_HEIGHT) / 2, - }) - } else { - None - }; - - let block = shared::TimelineBlock { - x: block_x as u32, - width: block_width, - height: block_height, - label, - }; - blocks.push(block); - } - - shared::Timeline { blocks } -} diff --git a/shared/src/lib.rs b/shared/src/lib.rs index 21f98e8..1a6d68a 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -3,6 +3,9 @@ use moonlight::*; mod var_format; pub use var_format::VarFormat; +mod signal_to_timeline; +pub use signal_to_timeline::signal_to_timeline; + pub mod wellen_helpers; #[derive(Serialize, Deserialize, Debug, Default)] diff --git a/shared/src/signal_to_timeline.rs b/shared/src/signal_to_timeline.rs new file mode 100644 index 0000000..da61b0c --- /dev/null +++ b/shared/src/signal_to_timeline.rs @@ -0,0 +1,72 @@ +use crate::*; + +pub fn signal_to_timeline( + signal: &wellen::Signal, + time_table: &[wellen::Time], + screen_width: u32, + block_height: u32, + var_format: VarFormat, +) -> Timeline { + const MIN_BLOCK_WIDTH: u32 = 3; + // Courier New, 16px, sync with `label_style` in `pixi_canvas.rs` + const LETTER_WIDTH: f64 = 9.61; + const LETTER_HEIGHT: u32 = 18; + const LABEL_X_PADDING: u32 = 10; + + let Some(last_time) = time_table.last().copied() else { + return Timeline::default(); + }; + + let last_time = last_time as f64; + let screen_width = screen_width as f64; + + let mut x_value_pairs = signal + .iter_changes() + .map(|(index, value)| { + let index = index as usize; + let time = time_table[index] as f64; + let x = time / last_time * screen_width; + (x, value) + }) + .peekable(); + + // @TODO parallelize? + let mut blocks = Vec::new(); + while let Some((block_x, value)) = x_value_pairs.next() { + let next_block_x = if let Some((next_block_x, _)) = x_value_pairs.peek() { + *next_block_x + } else { + screen_width + }; + + let block_width = (next_block_x - block_x) as u32; + if block_width < MIN_BLOCK_WIDTH { + continue; + } + + // @TODO cache? + let value = var_format.format(value); + + let value_width = (value.chars().count() as f64 * LETTER_WIDTH) as u32; + // @TODO Ellipsis instead of hiding? + let label = if (value_width + (2 * LABEL_X_PADDING)) <= block_width { + Some(TimeLineBlockLabel { + text: value, + x: (block_width - value_width) / 2, + y: (block_height - LETTER_HEIGHT) / 2, + }) + } else { + None + }; + + let block = TimelineBlock { + x: block_x as u32, + width: block_width, + height: block_height, + label, + }; + blocks.push(block); + } + + Timeline { blocks } +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 2417b81..d369f09 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -54,7 +54,8 @@ async fn load_signal_and_get_timeline( waveform.load_signals_multi_threaded(&[signal_ref]); let signal = waveform.get_signal(signal_ref).unwrap(); let time_table = waveform.time_table(); - let timeline = signal_to_timeline(signal, time_table, screen_width, block_height, var_format); + let timeline = + shared::signal_to_timeline(signal, time_table, screen_width, block_height, var_format); Ok(serde_json::to_value(timeline).unwrap()) } @@ -88,75 +89,3 @@ pub fn run() { .run(tauri::generate_context!()) .expect("error while running tauri application"); } - -// @TODO keep in sync with the same method in `frontend/src/platform/browser.rs` -fn signal_to_timeline( - signal: &wellen::Signal, - time_table: &[wellen::Time], - screen_width: u32, - block_height: u32, - var_format: shared::VarFormat, -) -> shared::Timeline { - const MIN_BLOCK_WIDTH: u32 = 3; - // Courier New, 16px, sync with `label_style` in `pixi_canvas.rs` - const LETTER_WIDTH: f64 = 9.61; - const LETTER_HEIGHT: u32 = 18; - const LABEL_X_PADDING: u32 = 10; - - let Some(last_time) = time_table.last().copied() else { - return shared::Timeline::default(); - }; - - let last_time = last_time as f64; - let screen_width = screen_width as f64; - - let mut x_value_pairs = signal - .iter_changes() - .map(|(index, value)| { - let index = index as usize; - let time = time_table[index] as f64; - let x = time / last_time * screen_width; - (x, value) - }) - .peekable(); - - // @TODO parallelize? - let mut blocks = Vec::new(); - while let Some((block_x, value)) = x_value_pairs.next() { - let next_block_x = if let Some((next_block_x, _)) = x_value_pairs.peek() { - *next_block_x - } else { - screen_width - }; - - let block_width = (next_block_x - block_x) as u32; - if block_width < MIN_BLOCK_WIDTH { - continue; - } - - // @TODO cache? - let value = var_format.format(value); - - let value_width = (value.chars().count() as f64 * LETTER_WIDTH) as u32; - // @TODO Ellipsis instead of hiding? - let label = if (value_width + (2 * LABEL_X_PADDING)) <= block_width { - Some(shared::TimeLineBlockLabel { - text: value, - x: (block_width - value_width) / 2, - y: (block_height - LETTER_HEIGHT) / 2, - }) - } else { - None - }; - - let block = shared::TimelineBlock { - x: block_x as u32, - width: block_width, - height: block_height, - label, - }; - blocks.push(block); - } - - shared::Timeline { blocks } -}