mirror of
https://github.com/hubaldv/bioz-host-rs.git
synced 2026-07-23 16:47:43 +00:00
Updated logger as separate module.
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
49
src/app.rs
49
src/app.rs
@@ -20,7 +20,7 @@ use egui_dock::{DockArea, DockState, Style, TabViewer};
|
||||
use egui_extras::{TableBuilder, Column};
|
||||
|
||||
use crate::state::{AppState, ControlCommand, HardwareConnected, HardwareState, MeasurementDataState, Mode};
|
||||
use crate::logging::LoggingStates;
|
||||
use crate::logging::LoggingState;
|
||||
use crate::signals::LoggingSignal;
|
||||
use crate::icd::{BioImpedanceLeadMode, IcdDftNum, SweepPoints, ElectrodeOptionsWithMultiplexer};
|
||||
|
||||
@@ -52,15 +52,15 @@ pub struct App {
|
||||
tree: DockState<String>,
|
||||
tab_viewer: CustomTabs,
|
||||
// tab_active: TabActive,
|
||||
log_tx: mpsc::Sender<LoggingSignal>,
|
||||
pub gui_logging_state: Arc<Mutex<LoggingStates>>,
|
||||
log_filename: Arc<Mutex<String>>,
|
||||
log_marker_modal: bool,
|
||||
log_marker: String,
|
||||
measurement_data: Arc<MeasurementDataState>,
|
||||
control_tx: mpsc::Sender<ControlCommand>,
|
||||
logging_control_tx: mpsc::Sender<LoggingSignal>,
|
||||
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 {
|
||||
@@ -616,11 +616,13 @@ impl TabViewer for CustomTabs {
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new(log_tx: mpsc::Sender<LoggingSignal>,
|
||||
measurement_data: Arc<MeasurementDataState>,
|
||||
pub fn new(measurement_data: Arc<MeasurementDataState>,
|
||||
control_tx: mpsc::Sender<ControlCommand>,
|
||||
logging_control_tx: mpsc::Sender<LoggingSignal>,
|
||||
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
|
||||
// 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()]),
|
||||
tab_viewer,
|
||||
// tab_active,
|
||||
log_tx,
|
||||
gui_logging_state: Arc::new(Mutex::new(LoggingStates::Idle)),
|
||||
log_filename,
|
||||
log_marker_modal: false,
|
||||
log_marker: String::new(),
|
||||
measurement_data,
|
||||
control_tx,
|
||||
logging_control_tx,
|
||||
app_state_rx,
|
||||
hardware_state_rx,
|
||||
logging_state_rx,
|
||||
};
|
||||
|
||||
// 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:"));
|
||||
|
||||
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() {
|
||||
let signal = match gui_logging_state {
|
||||
LoggingStates::Idle => LoggingSignal::StartFileLogging(self.log_filename.lock().unwrap().clone()),
|
||||
LoggingStates::Starting | LoggingStates::Logging => LoggingSignal::StopFileLogging,
|
||||
LoggingState::Idle => LoggingSignal::StartFileLogging(self.log_filename.lock().unwrap().clone()),
|
||||
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);
|
||||
});
|
||||
};
|
||||
@@ -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));
|
||||
|
||||
if add_clicked || enter_pressed {
|
||||
info!("Adding marker: {}", self.log_marker);
|
||||
self.log_tx.try_send(LoggingSignal::AddMarker(self.log_marker.clone())).unwrap_or_else(|e| {
|
||||
self.logging_control_tx.try_send(LoggingSignal::AddMarker(self.log_marker.clone())).unwrap_or_else(|e| {
|
||||
error!("Failed to send logging marker signal: {:?}", e);
|
||||
});
|
||||
self.log_marker = String::new();
|
||||
@@ -817,7 +818,7 @@ impl eframe::App for App {
|
||||
|
||||
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:");
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
// Enable/disable GUI logging
|
||||
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 {
|
||||
LoggingStates::Starting => {
|
||||
LoggingState::Starting => {
|
||||
// If currently starting, do nothing
|
||||
return;
|
||||
},
|
||||
LoggingStates::Logging => {
|
||||
if let Err(e) = self.log_tx.try_send(LoggingSignal::StopFileLogging) {
|
||||
LoggingState::Logging => {
|
||||
if let Err(e) = self.logging_control_tx.try_send(LoggingSignal::StopFileLogging) {
|
||||
error!("Failed to send logging signal: {:?}", e);
|
||||
}
|
||||
},
|
||||
LoggingStates::Idle => {
|
||||
if let Err(e) = self.log_tx.try_send(LoggingSignal::StartFileLogging(self.log_filename.lock().unwrap().clone())) {
|
||||
LoggingState::Idle => {
|
||||
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);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -14,7 +14,7 @@ use bioz_host_rs::communication::communicate_with_hardware;
|
||||
use tokio::sync::{watch, mpsc};
|
||||
|
||||
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::control::app_control_loop;
|
||||
@@ -25,65 +25,62 @@ async fn main() {
|
||||
log::set_max_level(log::LevelFilter::Info);
|
||||
info!("Starting Bioz Impedance Visualizer...");
|
||||
|
||||
// Enter the runtime so that `tokio::spawn` is available immediately.
|
||||
// let _enter = rt.enter();
|
||||
|
||||
// Init watches for hardware state and app state
|
||||
let (hardware_state_tx, hardware_state_rx) = watch::channel(HardwareState::default());
|
||||
// Init watches for hardware state, app state and logging state
|
||||
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
|
||||
let (hardware_control_tx, hardware_control_rx) = mpsc::channel::<StartStopSignal>(2);
|
||||
// Init control channels to update hardware, app and logging
|
||||
let (app_control_tx, app_control_rx) = mpsc::channel::<ControlCommand>(32);
|
||||
|
||||
// let run_impedancemeter_tx_clone = run_impedancemeter_tx.clone();
|
||||
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;
|
||||
});
|
||||
let (hardware_control_tx, hardware_control_rx) = mpsc::channel::<StartStopSignal>(2);
|
||||
let (logging_control_tx, logging_control_rx) = mpsc::channel::<LoggingSignal>(10);
|
||||
|
||||
// Init measurement data state
|
||||
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 app = App::new(log_tx, measurement_data_clone, app_control_tx_clone, app_state_rx, hardware_state_rx_clone);
|
||||
|
||||
let gui_logging_state_1 = app.gui_logging_state.clone();
|
||||
let gui_logging_state_2 = app.gui_logging_state.clone();
|
||||
|
||||
// Log 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 app_control_tx_clone = app_control_tx.clone();
|
||||
std::thread::spawn(move || {
|
||||
rt.block_on(bioz_host_rs::tcp::tcp_command_server(app_control_tx_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;
|
||||
});
|
||||
|
||||
// Execute the runtime in its own thread.
|
||||
// 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,
|
||||
gui_logging_state_2,
|
||||
log_tx_clone,
|
||||
logging_control_tx_clone,
|
||||
logging_state_rx_clone,
|
||||
));
|
||||
});
|
||||
|
||||
// Start logging loop
|
||||
tokio::spawn(async move { log_data(logging_control_rx, logging_state_tx).await });
|
||||
|
||||
// Start TCP command server in separate thread
|
||||
let rt = Runtime::new().expect("Unable to create Runtime");
|
||||
|
||||
let app_control_tx_clone = app_control_tx.clone();
|
||||
std::thread::spawn(move || {
|
||||
rt.block_on(bioz_host_rs::tcp::tcp_command_server(app_control_tx_clone));
|
||||
});
|
||||
|
||||
// Create the app and run it in the main thread
|
||||
let app = App::new(
|
||||
measurement_data_clone,
|
||||
app_control_tx,
|
||||
logging_control_tx,
|
||||
app_state_rx,
|
||||
hardware_state_rx,
|
||||
logging_state_rx);
|
||||
|
||||
// Run the GUI in the main thread.
|
||||
let mut native_options = NativeOptions::default();
|
||||
native_options.viewport.inner_size = Some(Vec2::new(850.0, 600.0));
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::state::{HardwareState, MeasurementDataState};
|
||||
use crate::icd;
|
||||
use crate::client::WorkbookClient;
|
||||
|
||||
use crate::logging::LoggingStates;
|
||||
use crate::logging::LoggingState;
|
||||
|
||||
use crate::signals::{LoggingSignal, StartStopSignal};
|
||||
|
||||
@@ -27,8 +27,8 @@ pub async fn communicate_with_hardware(
|
||||
hardware_control_tx: Sender<StartStopSignal>,
|
||||
measurement_data: Arc<MeasurementDataState>,
|
||||
hardware_state_tx: watch::Sender<HardwareState>,
|
||||
gui_logging_state: Arc<Mutex<LoggingStates>>,
|
||||
log_tx: Sender<LoggingSignal>,
|
||||
logging_control_tx: Sender<LoggingSignal>,
|
||||
logging_state_rx: watch::Receiver<LoggingState>,
|
||||
) {
|
||||
let data_counter = Arc::new(AtomicU32::new(0));
|
||||
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();
|
||||
|
||||
// Clone log_tx for the task
|
||||
let gui_logging_state_clone = gui_logging_state.clone();
|
||||
let log_tx_clone = log_tx.clone();
|
||||
let logging_control_tx_clone = logging_control_tx.clone();
|
||||
let logging_state_rx_clone = logging_state_rx.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);
|
||||
}
|
||||
// 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();
|
||||
match settings.mode {
|
||||
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);
|
||||
}
|
||||
},
|
||||
@@ -142,8 +142,8 @@ pub async fn communicate_with_hardware(
|
||||
let data_counter_clone_sweep = data_counter_clone.clone();
|
||||
|
||||
// Clone log_tx for the task
|
||||
let gui_logging_state_clone = gui_logging_state.clone();
|
||||
let log_tx_clone = log_tx.clone();
|
||||
let logging_control_tx_clone = logging_control_tx.clone();
|
||||
let logging_state_rx_clone = logging_state_rx.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
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_phases(SweepPoints::Eight, phases.clone());
|
||||
}
|
||||
if *gui_logging_state_clone.lock().unwrap() == LoggingStates::Logging {
|
||||
if let Err(e) = log_tx_clone.send(LoggingSignal::SweepImpedance(SystemTime::now(), SweepPoints::Eight.values().to_vec(), magnitudes.clone(), phases.clone())).await {
|
||||
if *logging_state_rx_clone.borrow() == LoggingState::Logging {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -172,8 +172,8 @@ pub async fn communicate_with_hardware(
|
||||
bode_plot.update_magnitudes(SweepPoints::Eighteen, magnitudes.clone());
|
||||
bode_plot.update_phases(SweepPoints::Eighteen, phases.clone());
|
||||
}
|
||||
if *gui_logging_state_clone.lock().unwrap() == LoggingStates::Logging {
|
||||
if let Err(e) = log_tx_clone.send(LoggingSignal::SweepImpedance(SystemTime::now(), SweepPoints::Eighteen.values().to_vec(), magnitudes.clone(), phases.clone())).await {
|
||||
if *logging_state_rx_clone.borrow() == LoggingState::Logging {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
select! {
|
||||
Some(frequency) = hardware_control_rx.recv() => {
|
||||
@@ -199,8 +199,8 @@ pub async fn communicate_with_hardware(
|
||||
hardware_state_tx.send(hardware_state.clone()).unwrap();
|
||||
|
||||
// When logging add electrode configuration to logging file
|
||||
if *gui_logging_state.lock().unwrap() == LoggingStates::Logging {
|
||||
if let Err(e) = log_tx_clone.send(LoggingSignal::ElectrodeCongiguration(electrode_config)).await {
|
||||
if *logging_state_rx.borrow() == LoggingState::Logging {
|
||||
if let Err(e) = logging_control_tx_clone.try_send(LoggingSignal::ElectrodeCongiguration(electrode_config)) {
|
||||
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
|
||||
if *gui_logging_state.lock().unwrap() == LoggingStates::Logging {
|
||||
if let Err(e) = log_tx_clone.send(LoggingSignal::ElectrodeCongiguration(electrode_config)).await {
|
||||
if *logging_state_rx.borrow() == LoggingState::Logging {
|
||||
if let Err(e) = logging_control_tx_clone.try_send(LoggingSignal::ElectrodeCongiguration(electrode_config)) {
|
||||
error!("Failed to send logging signal: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ use crate::state::Mode;
|
||||
|
||||
pub async fn app_control_loop(mut app_control_rx: mpsc::Receiver<ControlCommand>,
|
||||
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();
|
||||
|
||||
while let Some(cmd) = app_control_rx.recv().await {
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use bioz_icd_rs::ElectrodeConfiguration;
|
||||
use log::info;
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::UNIX_EPOCH;
|
||||
|
||||
use tokio::sync::mpsc::Receiver;
|
||||
use tokio::sync::{mpsc::Receiver, watch::Sender};
|
||||
use tokio::fs::File;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
|
||||
@@ -13,22 +12,28 @@ use rfd::AsyncFileDialog;
|
||||
use crate::signals::LoggingSignal;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum LoggingStates {
|
||||
pub enum LoggingState {
|
||||
Idle,
|
||||
Starting,
|
||||
Logging,
|
||||
}
|
||||
|
||||
impl Default for LoggingState {
|
||||
fn default() -> Self {
|
||||
LoggingState::Idle
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn log_data(
|
||||
mut data: Receiver<LoggingSignal>,
|
||||
gui_logging_state: Arc<Mutex<LoggingStates>>,
|
||||
mut logging_control_rx: Receiver<LoggingSignal>,
|
||||
logging_state_tx: Sender<LoggingState>,
|
||||
) {
|
||||
let mut file: Option<File> = None;
|
||||
let mut logging_marker = String::new();
|
||||
let mut electrode_configuration = String::new();
|
||||
|
||||
loop {
|
||||
match data.recv().await {
|
||||
match logging_control_rx.recv().await {
|
||||
Some(signal) => {
|
||||
match signal {
|
||||
LoggingSignal::SingleImpedance(timestamp, frequency, magnitude, phase) => {
|
||||
@@ -75,7 +80,7 @@ pub async fn log_data(
|
||||
}
|
||||
LoggingSignal::StartFileLogging(filename) => {
|
||||
// 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
|
||||
let folder = match AsyncFileDialog::new()
|
||||
@@ -85,7 +90,7 @@ pub async fn log_data(
|
||||
Some(f) => f,
|
||||
None => {
|
||||
info!("File logging cancelled by user");
|
||||
*gui_logging_state.lock().unwrap() = LoggingStates::Idle;
|
||||
logging_state_tx.send(LoggingState::Idle).unwrap();
|
||||
continue;
|
||||
}
|
||||
};
|
||||
@@ -123,7 +128,7 @@ pub async fn log_data(
|
||||
}
|
||||
|
||||
// Update global logging state
|
||||
*gui_logging_state.lock().unwrap() = LoggingStates::Logging;
|
||||
logging_state_tx.send(LoggingState::Logging).unwrap();
|
||||
}
|
||||
LoggingSignal::StopFileLogging => {
|
||||
if file.is_some() {
|
||||
@@ -131,9 +136,10 @@ pub async fn log_data(
|
||||
file = None;
|
||||
}
|
||||
// Update global logging state
|
||||
*gui_logging_state.lock().unwrap() = LoggingStates::Idle;
|
||||
logging_state_tx.send(LoggingState::Idle).unwrap();
|
||||
}
|
||||
LoggingSignal::AddMarker(marker) => {
|
||||
info!("Adding marker: {}", marker);
|
||||
logging_marker = marker;
|
||||
}
|
||||
LoggingSignal::ElectrodeCongiguration(config) => {
|
||||
|
||||
@@ -2,7 +2,6 @@ use std::sync::{Arc, Mutex};
|
||||
|
||||
use crate::app::TabActive;
|
||||
use crate::icd::{BioImpedanceLeadMode, IcdDftNum, SweepPoints, ElectrodeConfiguration, ElectrodeOptionsWithMultiplexer};
|
||||
use crate::logging::LoggingStates;
|
||||
use crate::plot::{TimeSeriesPlot, BodePlot};
|
||||
|
||||
use atomic_float::AtomicF32;
|
||||
@@ -108,7 +107,6 @@ pub struct AppState {
|
||||
pub electrode_settings: ElectrodeSettings,
|
||||
pub sweep_points: SweepPoints,
|
||||
pub tab_active: TabActive,
|
||||
pub logging: LoggingStates,
|
||||
}
|
||||
|
||||
impl Default for AppState {
|
||||
@@ -121,7 +119,6 @@ impl Default for AppState {
|
||||
electrode_settings: ElectrodeSettings::new(),
|
||||
sweep_points: SweepPoints::Eighteen,
|
||||
tab_active: TabActive::Single,
|
||||
logging: LoggingStates::Idle,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user