can_viewer/
state.rs

1//! Application state management.
2
3use crate::config::SessionConfig;
4use dbc_rs::{Dbc, FastDbc};
5use parking_lot::Mutex;
6
7#[cfg(target_os = "linux")]
8use tokio::sync::oneshot;
9
10/// Initial file paths from command line arguments.
11#[derive(Default)]
12pub struct InitialFiles {
13    pub dbc_path: Option<String>,
14    pub mdf4_path: Option<String>,
15}
16
17/// Type alias for the stop channel sender.
18/// Sends a result channel that will receive the finalized file path.
19#[cfg(target_os = "linux")]
20pub type CaptureStopTx = oneshot::Sender<oneshot::Sender<Result<String, String>>>;
21
22/// Global application state shared across Tauri commands.
23pub struct AppState {
24    /// Loaded DBC database for signal decoding.
25    pub dbc: Mutex<Option<Dbc>>,
26
27    /// High-performance DBC wrapper with O(1) message lookup.
28    /// Created alongside dbc for fast decoding in hot paths.
29    pub fast_dbc: Mutex<Option<FastDbc>>,
30
31    /// Path to the currently loaded DBC file.
32    pub dbc_path: Mutex<Option<String>>,
33
34    /// Initial files from command line.
35    pub initial_files: Mutex<InitialFiles>,
36
37    /// Session configuration for persistence.
38    pub session: Mutex<SessionConfig>,
39
40    /// Whether a SocketCAN capture is currently running.
41    #[cfg(target_os = "linux")]
42    pub capture_running: Mutex<bool>,
43
44    /// Channel to signal capture to stop and receive result.
45    #[cfg(target_os = "linux")]
46    pub capture_stop_tx: Mutex<Option<CaptureStopTx>>,
47}
48
49impl AppState {
50    pub fn with_initial_files(initial_files: InitialFiles) -> Self {
51        let session = SessionConfig::load();
52        Self {
53            dbc: Mutex::new(None),
54            fast_dbc: Mutex::new(None),
55            dbc_path: Mutex::new(None),
56            initial_files: Mutex::new(initial_files),
57            session: Mutex::new(session),
58            #[cfg(target_os = "linux")]
59            capture_running: Mutex::new(false),
60            #[cfg(target_os = "linux")]
61            capture_stop_tx: Mutex::new(None),
62        }
63    }
64
65    /// Set the DBC database and create the corresponding FastDbc wrapper.
66    /// This ensures both are always updated atomically.
67    pub fn set_dbc(&self, dbc: Dbc) {
68        let fast_dbc = FastDbc::new(dbc.clone());
69        *self.dbc.lock() = Some(dbc);
70        *self.fast_dbc.lock() = Some(fast_dbc);
71    }
72
73    /// Clear the DBC database and FastDbc wrapper.
74    pub fn clear_dbc(&self) {
75        *self.dbc.lock() = None;
76        *self.fast_dbc.lock() = None;
77    }
78}
79
80impl Default for AppState {
81    fn default() -> Self {
82        let session = SessionConfig::load();
83        Self {
84            dbc: Mutex::new(None),
85            fast_dbc: Mutex::new(None),
86            dbc_path: Mutex::new(None),
87            initial_files: Mutex::new(InitialFiles::default()),
88            session: Mutex::new(session),
89            #[cfg(target_os = "linux")]
90            capture_running: Mutex::new(false),
91            #[cfg(target_os = "linux")]
92            capture_stop_tx: Mutex::new(None),
93        }
94    }
95}