Updated logger as separate module.

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-04-30 10:15:36 +02:00
parent c35287c02f
commit cd80468f54
6 changed files with 98 additions and 97 deletions

View File

@@ -20,7 +20,7 @@ use egui_dock::{DockArea, DockState, Style, TabViewer};
use egui_extras::{TableBuilder, Column}; use egui_extras::{TableBuilder, Column};
use crate::state::{AppState, ControlCommand, HardwareConnected, HardwareState, MeasurementDataState, Mode}; use crate::state::{AppState, ControlCommand, HardwareConnected, HardwareState, MeasurementDataState, Mode};
use crate::logging::LoggingStates; use crate::logging::LoggingState;
use crate::signals::LoggingSignal; use crate::signals::LoggingSignal;
use crate::icd::{BioImpedanceLeadMode, IcdDftNum, SweepPoints, ElectrodeOptionsWithMultiplexer}; use crate::icd::{BioImpedanceLeadMode, IcdDftNum, SweepPoints, ElectrodeOptionsWithMultiplexer};
@@ -52,15 +52,15 @@ pub struct App {
tree: DockState<String>, tree: DockState<String>,
tab_viewer: CustomTabs, tab_viewer: CustomTabs,
// tab_active: TabActive, // tab_active: TabActive,
log_tx: mpsc::Sender<LoggingSignal>,
pub gui_logging_state: Arc<Mutex<LoggingStates>>,
log_filename: Arc<Mutex<String>>, log_filename: Arc<Mutex<String>>,
log_marker_modal: bool, log_marker_modal: bool,
log_marker: String, log_marker: String,
measurement_data: Arc<MeasurementDataState>, measurement_data: Arc<MeasurementDataState>,
control_tx: mpsc::Sender<ControlCommand>, control_tx: mpsc::Sender<ControlCommand>,
logging_control_tx: mpsc::Sender<LoggingSignal>,
app_state_rx: sync::watch::Receiver<AppState>, app_state_rx: sync::watch::Receiver<AppState>,
hardware_state_rx: sync::watch::Receiver<HardwareState> hardware_state_rx: sync::watch::Receiver<HardwareState>,
logging_state_rx: sync::watch::Receiver<LoggingState>,
} }
struct CustomTabs { struct CustomTabs {
@@ -616,11 +616,13 @@ impl TabViewer for CustomTabs {
} }
impl App { impl App {
pub fn new(log_tx: mpsc::Sender<LoggingSignal>, pub fn new(measurement_data: Arc<MeasurementDataState>,
measurement_data: Arc<MeasurementDataState>,
control_tx: mpsc::Sender<ControlCommand>, control_tx: mpsc::Sender<ControlCommand>,
logging_control_tx: mpsc::Sender<LoggingSignal>,
app_state_rx: watch::Receiver<AppState>, app_state_rx: watch::Receiver<AppState>,
hardware_state_rx: watch::Receiver<HardwareState>) -> Self { hardware_state_rx: watch::Receiver<HardwareState>,
logging_state_rx: watch::Receiver<LoggingState>
) -> Self {
// Step 1: Initialize shared fields first // Step 1: Initialize shared fields first
// let tab_active = app_state_rx.borrow().tab_active; // let tab_active = app_state_rx.borrow().tab_active;
@@ -647,15 +649,15 @@ impl App {
tree: DockState::new(vec!["Single".to_string(), "Sweep".to_string(), "Shortcuts".to_string()]), tree: DockState::new(vec!["Single".to_string(), "Sweep".to_string(), "Shortcuts".to_string()]),
tab_viewer, tab_viewer,
// tab_active, // tab_active,
log_tx,
gui_logging_state: Arc::new(Mutex::new(LoggingStates::Idle)),
log_filename, log_filename,
log_marker_modal: false, log_marker_modal: false,
log_marker: String::new(), log_marker: String::new(),
measurement_data, measurement_data,
control_tx, control_tx,
logging_control_tx,
app_state_rx, app_state_rx,
hardware_state_rx, hardware_state_rx,
logging_state_rx,
}; };
// For testing purposes, populate the Bode plot with a sample low-pass filter response // For testing purposes, populate the Bode plot with a sample low-pass filter response
@@ -745,17 +747,17 @@ impl eframe::App for App {
ui.add_enabled(is_connected, Label::new("Logging:")); ui.add_enabled(is_connected, Label::new("Logging:"));
let gui_logging_state = *self.gui_logging_state.lock().unwrap(); let gui_logging_state = *self.logging_state_rx.borrow();
let mut logging_enabled = !matches!(gui_logging_state, LoggingStates::Idle); let mut logging_enabled = !matches!(gui_logging_state, LoggingState::Idle);
if ui.add_enabled(is_connected, custom_toggle_widget(&mut logging_enabled)).changed() { if ui.add_enabled(is_connected, custom_toggle_widget(&mut logging_enabled)).changed() {
let signal = match gui_logging_state { let signal = match gui_logging_state {
LoggingStates::Idle => LoggingSignal::StartFileLogging(self.log_filename.lock().unwrap().clone()), LoggingState::Idle => LoggingSignal::StartFileLogging(self.log_filename.lock().unwrap().clone()),
LoggingStates::Starting | LoggingStates::Logging => LoggingSignal::StopFileLogging, LoggingState::Starting | LoggingState::Logging => LoggingSignal::StopFileLogging,
}; };
self.log_tx.try_send(signal).unwrap_or_else(|e| { self.logging_control_tx.try_send(signal).unwrap_or_else(|e| {
error!("Failed to send logging toggle signal: {:?}", e); error!("Failed to send logging toggle signal: {:?}", e);
}); });
}; };
@@ -796,8 +798,7 @@ impl eframe::App for App {
let enter_pressed = text_edit_response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)); let enter_pressed = text_edit_response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter));
if add_clicked || enter_pressed { if add_clicked || enter_pressed {
info!("Adding marker: {}", self.log_marker); self.logging_control_tx.try_send(LoggingSignal::AddMarker(self.log_marker.clone())).unwrap_or_else(|e| {
self.log_tx.try_send(LoggingSignal::AddMarker(self.log_marker.clone())).unwrap_or_else(|e| {
error!("Failed to send logging marker signal: {:?}", e); error!("Failed to send logging marker signal: {:?}", e);
}); });
self.log_marker = String::new(); self.log_marker = String::new();
@@ -817,7 +818,7 @@ impl eframe::App for App {
ui.separator(); ui.separator();
ui.add_enabled_ui(gui_logging_state == LoggingStates::Idle, |ui| { ui.add_enabled_ui(gui_logging_state == LoggingState::Idle, |ui| {
ui.label("Log filename:"); ui.label("Log filename:");
TextEdit::singleline(&mut *self.log_filename.lock().unwrap()).desired_width(150.0).id(Id::new("file_name_field")).ui(ui); TextEdit::singleline(&mut *self.log_filename.lock().unwrap()).desired_width(150.0).id(Id::new("file_name_field")).ui(ui);
}); });
@@ -894,25 +895,25 @@ impl eframe::App for App {
} }
// Toggle marker modal // Toggle marker modal
if ctx.input(|i| i.key_pressed(egui::Key::A)) && *self.gui_logging_state.lock().unwrap() == LoggingStates::Logging { if ctx.input(|i| i.key_pressed(egui::Key::A)) && *self.logging_state_rx.borrow() == LoggingState::Logging {
self.log_marker_modal = !self.log_marker_modal; self.log_marker_modal = !self.log_marker_modal;
} }
// Enable/disable GUI logging // Enable/disable GUI logging
if ctx.input(|i| i.key_pressed(egui::Key::L)) { if ctx.input(|i| i.key_pressed(egui::Key::L)) {
let gui_logging_enabled = *self.gui_logging_state.lock().unwrap(); let gui_logging_enabled = *self.logging_state_rx.borrow();
match gui_logging_enabled { match gui_logging_enabled {
LoggingStates::Starting => { LoggingState::Starting => {
// If currently starting, do nothing // If currently starting, do nothing
return; return;
}, },
LoggingStates::Logging => { LoggingState::Logging => {
if let Err(e) = self.log_tx.try_send(LoggingSignal::StopFileLogging) { if let Err(e) = self.logging_control_tx.try_send(LoggingSignal::StopFileLogging) {
error!("Failed to send logging signal: {:?}", e); error!("Failed to send logging signal: {:?}", e);
} }
}, },
LoggingStates::Idle => { LoggingState::Idle => {
if let Err(e) = self.log_tx.try_send(LoggingSignal::StartFileLogging(self.log_filename.lock().unwrap().clone())) { if let Err(e) = self.logging_control_tx.try_send(LoggingSignal::StartFileLogging(self.log_filename.lock().unwrap().clone())) {
error!("Failed to send logging signal: {:?}", e); error!("Failed to send logging signal: {:?}", e);
} }
}, },

View File

@@ -14,7 +14,7 @@ use bioz_host_rs::communication::communicate_with_hardware;
use tokio::sync::{watch, mpsc}; use tokio::sync::{watch, mpsc};
use bioz_host_rs::signals::StartStopSignal; use bioz_host_rs::signals::StartStopSignal;
use bioz_host_rs::logging::log_data; use bioz_host_rs::logging::{LoggingState, log_data};
use bioz_host_rs::state::{AppState, ControlCommand, HardwareState, MeasurementDataState}; use bioz_host_rs::state::{AppState, ControlCommand, HardwareState, MeasurementDataState};
use bioz_host_rs::control::app_control_loop; use bioz_host_rs::control::app_control_loop;
@@ -25,45 +25,46 @@ async fn main() {
log::set_max_level(log::LevelFilter::Info); log::set_max_level(log::LevelFilter::Info);
info!("Starting Bioz Impedance Visualizer..."); info!("Starting Bioz Impedance Visualizer...");
// Enter the runtime so that `tokio::spawn` is available immediately. // Init watches for hardware state, app state and logging state
// let _enter = rt.enter();
// Init watches for hardware state and app state
let (hardware_state_tx, hardware_state_rx) = watch::channel(HardwareState::default());
let (app_state_tx, app_state_rx) = watch::channel(AppState::default()); let (app_state_tx, app_state_rx) = watch::channel(AppState::default());
let (hardware_state_tx, hardware_state_rx) = watch::channel(HardwareState::default());
let (logging_state_tx, logging_state_rx) = watch::channel(LoggingState::default());
// Init control channels to update hardware and app // Init control channels to update hardware, app and logging
let (hardware_control_tx, hardware_control_rx) = mpsc::channel::<StartStopSignal>(2);
let (app_control_tx, app_control_rx) = mpsc::channel::<ControlCommand>(32); let (app_control_tx, app_control_rx) = mpsc::channel::<ControlCommand>(32);
let (hardware_control_tx, hardware_control_rx) = mpsc::channel::<StartStopSignal>(2);
// let run_impedancemeter_tx_clone = run_impedancemeter_tx.clone(); let (logging_control_tx, logging_control_rx) = mpsc::channel::<LoggingSignal>(10);
let hardware_state_rx_clone = hardware_state_rx.clone();
let hardware_control_tx_clone = hardware_control_tx.clone();
let app_control_tx_clone = app_control_tx.clone();
tokio::spawn(async move {
app_control_loop(app_control_rx, app_state_tx, hardware_state_rx, hardware_control_tx_clone).await;
});
// Init measurement data state // Init measurement data state
let measurement_data = Arc::new(MeasurementDataState::default()); let measurement_data = Arc::new(MeasurementDataState::default());
// Logging
let (log_tx, log_rx) = mpsc::channel::<LoggingSignal>(10);
let log_tx_clone = log_tx.clone();
let measurement_data_clone = measurement_data.clone(); let measurement_data_clone = measurement_data.clone();
// Start control loop
let hardware_control_tx_clone = hardware_control_tx.clone();
let hardware_state_rx_clone = hardware_state_rx.clone();
tokio::spawn(async move {
app_control_loop(app_control_rx, app_state_tx, hardware_control_tx_clone, hardware_state_rx_clone).await;
});
let app = App::new(log_tx, measurement_data_clone, app_control_tx_clone, app_state_rx, hardware_state_rx_clone); // Start hardware communication loop in separate thread
let rt = Runtime::new().expect("Unable to create Runtime");
let logging_control_tx_clone = logging_control_tx.clone();
let logging_state_rx_clone = logging_state_rx.clone();
std::thread::spawn(move || {
rt.block_on(communicate_with_hardware(
hardware_control_rx,
hardware_control_tx,
measurement_data,
hardware_state_tx,
logging_control_tx_clone,
logging_state_rx_clone,
));
});
let gui_logging_state_1 = app.gui_logging_state.clone(); // Start logging loop
let gui_logging_state_2 = app.gui_logging_state.clone(); tokio::spawn(async move { log_data(logging_control_rx, logging_state_tx).await });
// Log thread // Start TCP command server in separate thread
tokio::spawn(async move { log_data(log_rx, gui_logging_state_1).await });
// TCP command server in separate thread
let rt = Runtime::new().expect("Unable to create Runtime"); let rt = Runtime::new().expect("Unable to create Runtime");
let app_control_tx_clone = app_control_tx.clone(); let app_control_tx_clone = app_control_tx.clone();
@@ -71,18 +72,14 @@ async fn main() {
rt.block_on(bioz_host_rs::tcp::tcp_command_server(app_control_tx_clone)); rt.block_on(bioz_host_rs::tcp::tcp_command_server(app_control_tx_clone));
}); });
// Execute the runtime in its own thread. // Create the app and run it in the main thread
let rt = Runtime::new().expect("Unable to create Runtime"); let app = App::new(
std::thread::spawn(move || { measurement_data_clone,
rt.block_on(communicate_with_hardware( app_control_tx,
hardware_control_rx, logging_control_tx,
hardware_control_tx, app_state_rx,
measurement_data, hardware_state_rx,
hardware_state_tx, logging_state_rx);
gui_logging_state_2,
log_tx_clone,
));
});
// Run the GUI in the main thread. // Run the GUI in the main thread.
let mut native_options = NativeOptions::default(); let mut native_options = NativeOptions::default();

View File

@@ -16,7 +16,7 @@ use crate::state::{HardwareState, MeasurementDataState};
use crate::icd; use crate::icd;
use crate::client::WorkbookClient; use crate::client::WorkbookClient;
use crate::logging::LoggingStates; use crate::logging::LoggingState;
use crate::signals::{LoggingSignal, StartStopSignal}; use crate::signals::{LoggingSignal, StartStopSignal};
@@ -27,8 +27,8 @@ pub async fn communicate_with_hardware(
hardware_control_tx: Sender<StartStopSignal>, hardware_control_tx: Sender<StartStopSignal>,
measurement_data: Arc<MeasurementDataState>, measurement_data: Arc<MeasurementDataState>,
hardware_state_tx: watch::Sender<HardwareState>, hardware_state_tx: watch::Sender<HardwareState>,
gui_logging_state: Arc<Mutex<LoggingStates>>, logging_control_tx: Sender<LoggingSignal>,
log_tx: Sender<LoggingSignal>, logging_state_rx: watch::Receiver<LoggingState>,
) { ) {
let data_counter = Arc::new(AtomicU32::new(0)); let data_counter = Arc::new(AtomicU32::new(0));
let data_counter_clone = data_counter.clone(); let data_counter_clone = data_counter.clone();
@@ -89,8 +89,8 @@ pub async fn communicate_with_hardware(
let data_counter_clone_single = data_counter_clone.clone(); let data_counter_clone_single = data_counter_clone.clone();
// Clone log_tx for the task // Clone log_tx for the task
let gui_logging_state_clone = gui_logging_state.clone(); let logging_control_tx_clone = logging_control_tx.clone();
let log_tx_clone = log_tx.clone(); let logging_state_rx_clone = logging_state_rx.clone();
let settings_clone = settings.clone(); let settings_clone = settings.clone();
@@ -111,11 +111,11 @@ pub async fn communicate_with_hardware(
data_counter_clone_single.fetch_add(1, Ordering::Relaxed); data_counter_clone_single.fetch_add(1, Ordering::Relaxed);
} }
// Send logging signal // Send logging signal
if *gui_logging_state_clone.lock().unwrap() == LoggingStates::Logging { if *logging_state_rx_clone.borrow() == LoggingState::Logging {
let settings = *settings_clone.lock().unwrap(); let settings = *settings_clone.lock().unwrap();
match settings.mode { match settings.mode {
Some(StartStopSignal::StartSingle(freq, _, _, _)) => { Some(StartStopSignal::StartSingle(freq, _, _, _)) => {
if let Err(e) = log_tx_clone.try_send(LoggingSignal::SingleImpedance(SystemTime::now(), freq, val.magnitude, val.phase)) { if let Err(e) = logging_control_tx_clone.try_send(LoggingSignal::SingleImpedance(SystemTime::now(), freq, val.magnitude, val.phase)) {
error!("Failed to send logging signal: {:?}", e); error!("Failed to send logging signal: {:?}", e);
} }
}, },
@@ -142,8 +142,8 @@ pub async fn communicate_with_hardware(
let data_counter_clone_sweep = data_counter_clone.clone(); let data_counter_clone_sweep = data_counter_clone.clone();
// Clone log_tx for the task // Clone log_tx for the task
let gui_logging_state_clone = gui_logging_state.clone(); let logging_control_tx_clone = logging_control_tx.clone();
let log_tx_clone = log_tx.clone(); let logging_state_rx_clone = logging_state_rx.clone();
tokio::spawn(async move { tokio::spawn(async move {
while let Ok(val) = sweep_impedance_sub.recv().await { while let Ok(val) = sweep_impedance_sub.recv().await {
@@ -158,8 +158,8 @@ pub async fn communicate_with_hardware(
bode_plot.update_magnitudes(SweepPoints::Eight, magnitudes.clone()); bode_plot.update_magnitudes(SweepPoints::Eight, magnitudes.clone());
bode_plot.update_phases(SweepPoints::Eight, phases.clone()); bode_plot.update_phases(SweepPoints::Eight, phases.clone());
} }
if *gui_logging_state_clone.lock().unwrap() == LoggingStates::Logging { if *logging_state_rx_clone.borrow() == LoggingState::Logging {
if let Err(e) = log_tx_clone.send(LoggingSignal::SweepImpedance(SystemTime::now(), SweepPoints::Eight.values().to_vec(), magnitudes.clone(), phases.clone())).await { if let Err(e) = logging_control_tx_clone.try_send(LoggingSignal::SweepImpedance(SystemTime::now(), SweepPoints::Eight.values().to_vec(), magnitudes.clone(), phases.clone())) {
error!("Failed to send logging signal: {:?}", e); error!("Failed to send logging signal: {:?}", e);
} }
} }
@@ -172,8 +172,8 @@ pub async fn communicate_with_hardware(
bode_plot.update_magnitudes(SweepPoints::Eighteen, magnitudes.clone()); bode_plot.update_magnitudes(SweepPoints::Eighteen, magnitudes.clone());
bode_plot.update_phases(SweepPoints::Eighteen, phases.clone()); bode_plot.update_phases(SweepPoints::Eighteen, phases.clone());
} }
if *gui_logging_state_clone.lock().unwrap() == LoggingStates::Logging { if *logging_state_rx_clone.borrow() == LoggingState::Logging {
if let Err(e) = log_tx_clone.send(LoggingSignal::SweepImpedance(SystemTime::now(), SweepPoints::Eighteen.values().to_vec(), magnitudes.clone(), phases.clone())).await { if let Err(e) = logging_control_tx_clone.try_send(LoggingSignal::SweepImpedance(SystemTime::now(), SweepPoints::Eighteen.values().to_vec(), magnitudes.clone(), phases.clone())) {
error!("Failed to send logging signal: {:?}", e); error!("Failed to send logging signal: {:?}", e);
} }
} }
@@ -184,7 +184,7 @@ pub async fn communicate_with_hardware(
} }
}); });
let log_tx_clone = log_tx.clone(); let logging_control_tx_clone = logging_control_tx.clone();
loop { loop {
select! { select! {
Some(frequency) = hardware_control_rx.recv() => { Some(frequency) = hardware_control_rx.recv() => {
@@ -199,8 +199,8 @@ pub async fn communicate_with_hardware(
hardware_state_tx.send(hardware_state.clone()).unwrap(); hardware_state_tx.send(hardware_state.clone()).unwrap();
// When logging add electrode configuration to logging file // When logging add electrode configuration to logging file
if *gui_logging_state.lock().unwrap() == LoggingStates::Logging { if *logging_state_rx.borrow() == LoggingState::Logging {
if let Err(e) = log_tx_clone.send(LoggingSignal::ElectrodeCongiguration(electrode_config)).await { if let Err(e) = logging_control_tx_clone.try_send(LoggingSignal::ElectrodeCongiguration(electrode_config)) {
error!("Failed to send logging signal: {:?}", e); error!("Failed to send logging signal: {:?}", e);
} }
} }
@@ -238,8 +238,8 @@ pub async fn communicate_with_hardware(
} }
// When logging add electrode configuration to logging file // When logging add electrode configuration to logging file
if *gui_logging_state.lock().unwrap() == LoggingStates::Logging { if *logging_state_rx.borrow() == LoggingState::Logging {
if let Err(e) = log_tx_clone.send(LoggingSignal::ElectrodeCongiguration(electrode_config)).await { if let Err(e) = logging_control_tx_clone.try_send(LoggingSignal::ElectrodeCongiguration(electrode_config)) {
error!("Failed to send logging signal: {:?}", e); error!("Failed to send logging signal: {:?}", e);
} }
} }

View File

@@ -6,8 +6,8 @@ use crate::state::Mode;
pub async fn app_control_loop(mut app_control_rx: mpsc::Receiver<ControlCommand>, pub async fn app_control_loop(mut app_control_rx: mpsc::Receiver<ControlCommand>,
app_state_tx: watch::Sender<AppState>, app_state_tx: watch::Sender<AppState>,
hardware_state_rx: watch::Receiver<HardwareState>, hardware_control_tx: mpsc::Sender<StartStopSignal>,
hardware_control_tx: mpsc::Sender<StartStopSignal>) { hardware_state_rx: watch::Receiver<HardwareState>) {
let mut state = AppState::default(); let mut state = AppState::default();
while let Some(cmd) = app_control_rx.recv().await { while let Some(cmd) = app_control_rx.recv().await {

View File

@@ -1,10 +1,9 @@
use bioz_icd_rs::ElectrodeConfiguration; use bioz_icd_rs::ElectrodeConfiguration;
use log::info; use log::info;
use std::sync::{Arc, Mutex};
use std::time::UNIX_EPOCH; use std::time::UNIX_EPOCH;
use tokio::sync::mpsc::Receiver; use tokio::sync::{mpsc::Receiver, watch::Sender};
use tokio::fs::File; use tokio::fs::File;
use tokio::io::AsyncWriteExt; use tokio::io::AsyncWriteExt;
@@ -13,22 +12,28 @@ use rfd::AsyncFileDialog;
use crate::signals::LoggingSignal; use crate::signals::LoggingSignal;
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LoggingStates { pub enum LoggingState {
Idle, Idle,
Starting, Starting,
Logging, Logging,
} }
impl Default for LoggingState {
fn default() -> Self {
LoggingState::Idle
}
}
pub async fn log_data( pub async fn log_data(
mut data: Receiver<LoggingSignal>, mut logging_control_rx: Receiver<LoggingSignal>,
gui_logging_state: Arc<Mutex<LoggingStates>>, logging_state_tx: Sender<LoggingState>,
) { ) {
let mut file: Option<File> = None; let mut file: Option<File> = None;
let mut logging_marker = String::new(); let mut logging_marker = String::new();
let mut electrode_configuration = String::new(); let mut electrode_configuration = String::new();
loop { loop {
match data.recv().await { match logging_control_rx.recv().await {
Some(signal) => { Some(signal) => {
match signal { match signal {
LoggingSignal::SingleImpedance(timestamp, frequency, magnitude, phase) => { LoggingSignal::SingleImpedance(timestamp, frequency, magnitude, phase) => {
@@ -75,7 +80,7 @@ pub async fn log_data(
} }
LoggingSignal::StartFileLogging(filename) => { LoggingSignal::StartFileLogging(filename) => {
// Update global logging state // Update global logging state
*gui_logging_state.lock().unwrap() = LoggingStates::Starting; logging_state_tx.send(LoggingState::Starting).unwrap();
// Open a folder picker for the user // Open a folder picker for the user
let folder = match AsyncFileDialog::new() let folder = match AsyncFileDialog::new()
@@ -85,7 +90,7 @@ pub async fn log_data(
Some(f) => f, Some(f) => f,
None => { None => {
info!("File logging cancelled by user"); info!("File logging cancelled by user");
*gui_logging_state.lock().unwrap() = LoggingStates::Idle; logging_state_tx.send(LoggingState::Idle).unwrap();
continue; continue;
} }
}; };
@@ -123,7 +128,7 @@ pub async fn log_data(
} }
// Update global logging state // Update global logging state
*gui_logging_state.lock().unwrap() = LoggingStates::Logging; logging_state_tx.send(LoggingState::Logging).unwrap();
} }
LoggingSignal::StopFileLogging => { LoggingSignal::StopFileLogging => {
if file.is_some() { if file.is_some() {
@@ -131,9 +136,10 @@ pub async fn log_data(
file = None; file = None;
} }
// Update global logging state // Update global logging state
*gui_logging_state.lock().unwrap() = LoggingStates::Idle; logging_state_tx.send(LoggingState::Idle).unwrap();
} }
LoggingSignal::AddMarker(marker) => { LoggingSignal::AddMarker(marker) => {
info!("Adding marker: {}", marker);
logging_marker = marker; logging_marker = marker;
} }
LoggingSignal::ElectrodeCongiguration(config) => { LoggingSignal::ElectrodeCongiguration(config) => {

View File

@@ -2,7 +2,6 @@ use std::sync::{Arc, Mutex};
use crate::app::TabActive; use crate::app::TabActive;
use crate::icd::{BioImpedanceLeadMode, IcdDftNum, SweepPoints, ElectrodeConfiguration, ElectrodeOptionsWithMultiplexer}; use crate::icd::{BioImpedanceLeadMode, IcdDftNum, SweepPoints, ElectrodeConfiguration, ElectrodeOptionsWithMultiplexer};
use crate::logging::LoggingStates;
use crate::plot::{TimeSeriesPlot, BodePlot}; use crate::plot::{TimeSeriesPlot, BodePlot};
use atomic_float::AtomicF32; use atomic_float::AtomicF32;
@@ -108,7 +107,6 @@ pub struct AppState {
pub electrode_settings: ElectrodeSettings, pub electrode_settings: ElectrodeSettings,
pub sweep_points: SweepPoints, pub sweep_points: SweepPoints,
pub tab_active: TabActive, pub tab_active: TabActive,
pub logging: LoggingStates,
} }
impl Default for AppState { impl Default for AppState {
@@ -121,7 +119,6 @@ impl Default for AppState {
electrode_settings: ElectrodeSettings::new(), electrode_settings: ElectrodeSettings::new(),
sweep_points: SweepPoints::Eighteen, sweep_points: SweepPoints::Eighteen,
tab_active: TabActive::Single, tab_active: TabActive::Single,
logging: LoggingStates::Idle,
} }
} }
} }