diff --git a/src/gui.rs b/src/gui.rs index 69155b9..984de97 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -1220,6 +1220,18 @@ impl MyApp { egui_logger::logger_ui().show(ui); }); + ctx.input(|i| { + // Check if files were dropped + if let Some(dropped_file) = i.raw.dropped_files.last() { + let path = dropped_file.clone().path.unwrap(); + self.picked_path = path.to_path_buf(); + self.file_opened = true; + if let Err(e) = self.load_tx.send(self.picked_path.clone()) { + log::error!("load_tx thread send failed: {:?}", e); + } + } + }); + match self.file_dialog_state { FileDialogState::Open => { if let Some(path) = self diff --git a/src/io.rs b/src/io.rs index c367334..c05282e 100644 --- a/src/io.rs +++ b/src/io.rs @@ -57,7 +57,7 @@ pub fn open_from_csv( // Parse the remaining columns and populate the dataset for (i, value) in record.iter().skip(1).enumerate() { if let Some(dataset_column) = data.dataset.get_mut(i) { - dataset_column.push(value.parse()?); + dataset_column.push(value.trim().parse().unwrap_or(0.0)); } else { return Err("Unexpected number of data columns in the CSV".into()); } diff --git a/src/main.rs b/src/main.rs index 17d8fd3..9f9a1da 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ extern crate serde; use crate::data::{DataContainer, GuiOutputDataContainer, Packet, SerialDirection}; use crate::gui::{load_gui_settings, GuiCommand, MyApp, RIGHT_PANEL_WIDTH}; use crate::io::{open_from_csv, save_to_csv, FileOptions}; -use crate::serial::{load_serial_settings, serial_thread, Device}; +use crate::serial::{load_serial_settings, serial_devices_thread, serial_thread, Device}; use crossbeam_channel::{select, Receiver, Sender}; use eframe::egui::{vec2, ViewportBuilder, Visuals}; use eframe::{egui, icon_data}; @@ -96,12 +96,7 @@ fn main_thread( sync_tx.send(true).expect("unable to send sync tx"); data.raw_traffic.push(packet.clone()); - if let Ok(mut gui_data) = data_lock.write() { - if let Some(text) = console_text(show_timestamps, show_sent_cmds, &packet) { - // append prints - gui_data.prints.push(text); - } - } + let text = console_text(show_timestamps, show_sent_cmds, &packet); let split_data = split(&packet.payload); if data.dataset.is_empty() || failed_format_counter > 10 { @@ -109,6 +104,10 @@ fn main_thread( data.time = vec![]; data.dataset = vec![vec![]; max(split_data.len(), 1)]; if let Ok(mut gui_data) = data_lock.write() { + // append prints + if let Some(text) = text { + gui_data.prints.push(text); + } gui_data.plots = (0..max(split_data.len(), 1)) .map(|i| (format!("Column {i}"), vec![])) .collect(); @@ -127,6 +126,10 @@ fn main_thread( // appending data for GUI thread if let Ok(mut gui_data) = data_lock.write() { + // append prints + if let Some(text) = text { + gui_data.prints.push(text); + } // append plot-points for ((_label, graph), data_i) in gui_data.plots.iter_mut().zip(&data.dataset) @@ -200,8 +203,6 @@ fn main_thread( gui_data.prints = raw_data; - dbg!(&gui_data.prints); - gui_data.plots = (0..data.dataset.len()) .map(|i| (file_options.names[i].to_string(), vec![])) .collect(); @@ -257,7 +258,7 @@ fn main_thread( } } } - default(Duration::from_millis(10)) => { + default(Duration::from_millis(1)) => { // occasionally push data to GUI } } @@ -287,6 +288,12 @@ fn main() { crossbeam_channel::unbounded(); let (sync_tx, sync_rx): (Sender, Receiver) = crossbeam_channel::unbounded(); + let serial_2_devices_lock = devices_lock.clone(); + + let _serial_devices_thread_handler = thread::spawn(|| { + serial_devices_thread(serial_2_devices_lock); + }); + let serial_device_lock = device_lock.clone(); let serial_devices_lock = devices_lock.clone(); let serial_connected_lock = connected_lock.clone(); diff --git a/src/serial.rs b/src/serial.rs index b0aac54..c908ab3 100644 --- a/src/serial.rs +++ b/src/serial.rs @@ -89,6 +89,15 @@ impl Default for Device { } } +pub fn serial_devices_thread(devices_lock: Arc>>) { + loop { + if let Ok(mut write_guard) = devices_lock.write() { + *write_guard = available_devices(); + } + std::thread::sleep(Duration::from_millis(500)); + } +} + fn serial_write( port: &mut BufReader>, cmd: &[u8], @@ -165,19 +174,17 @@ pub fn serial_thread( .create(); 'connected_loop: loop { - let devices = available_devices(); - if let Ok(mut write_guard) = devices_lock.write() { - *write_guard = devices.clone(); - } - - if disconnected(&device, &devices, &device_lock, &mut last_connected_device) { + if disconnected( + &device, + &device_lock, + &devices_lock, + &mut last_connected_device, + ) { break 'connected_loop; } perform_writes(&mut port, &send_rx, &raw_data_tx, t_zero); perform_reads(&mut port, &raw_data_tx, t_zero); - - //std::thread::sleep(Duration::from_millis(10)); } std::mem::drop(port); } @@ -222,12 +229,12 @@ fn get_device( fn disconnected( device: &Device, - devices: &[String], device_lock: &Arc>, + devices_lock: &Arc>>, last_connected_device: &mut Device, ) -> bool { // disconnection by button press - if let Ok(read_guard) = device_lock.read() { + if let Ok(read_guard) = device_lock.try_read() { if device.name != read_guard.name { *last_connected_device = Device::default(); log::info!("Disconnected from serial port: {}", device.name); @@ -235,15 +242,17 @@ fn disconnected( } } - // other types of disconnection (e.g. unplugging, power down) - if !devices.contains(&device.name) { - if let Ok(mut write_guard) = device_lock.write() { - write_guard.name.clear(); - } - *last_connected_device = device.clone(); - log::error!("Device has disconnected from serial port: {}", device.name); - return true; - }; + if let Ok(devices) = devices_lock.try_read() { + // other types of disconnection (e.g. unplugging, power down) + if !devices.contains(&device.name) { + if let Ok(mut write_guard) = device_lock.try_write() { + write_guard.name.clear(); + } + *last_connected_device = device.clone(); + log::error!("Device has disconnected from serial port: {}", device.name); + return true; + }; + } false } @@ -279,7 +288,15 @@ fn perform_reads( let mut buf = "".to_string(); match serial_read(port, &mut buf) { Ok(_) => { - let delimiter = if buf.contains("\r\n") { "\r\n" } else { "\0\0" }; + let delimiter = if buf.contains("\r\n") { + "\r\n" + } else if buf.contains("\r") { + "\r" + } else if buf.contains("\n") { + "\n" + } else { + "\0\0" + }; buf.split_terminator(delimiter).for_each(|s| { let packet = Packet { relative_time: Instant::now().duration_since(t_zero).as_millis() as f64,