pokeys_thread/
sync.rs

1//! Data synchronization
2
3use crate::error::{Result, ThreadError};
4use crate::state::SharedDeviceState;
5use log::error;
6use std::sync::Arc;
7use std::time::{Duration, Instant};
8
9/// Data synchronization
10pub struct DeviceSync {
11    /// Shared device state
12    shared_state: Arc<SharedDeviceState>,
13    /// Thread ID
14    thread_id: u32,
15    /// Last sync time
16    last_sync: Instant,
17    /// Sync interval
18    sync_interval: Duration,
19}
20
21impl DeviceSync {
22    /// Create a new data synchronization
23    pub fn new(
24        thread_id: u32,
25        shared_state: Arc<SharedDeviceState>,
26        sync_interval_ms: u64,
27    ) -> Self {
28        Self {
29            shared_state,
30            thread_id,
31            last_sync: Instant::now(),
32            sync_interval: Duration::from_millis(sync_interval_ms),
33        }
34    }
35
36    /// Check if it's time to sync
37    pub fn should_sync(&self) -> bool {
38        self.last_sync.elapsed() >= self.sync_interval
39    }
40
41    /// Sync the device state
42    pub fn sync(&mut self, device: &mut pokeys_lib::PoKeysDevice) -> Result<()> {
43        // debug!("Syncing device state for thread {}", self.thread_id);
44
45        // Refresh digital inputs
46        if let Err(e) = device.get_digital_inputs() {
47            error!("Failed to refresh digital inputs: {e}");
48            self.shared_state
49                .set_error(Some(format!("Failed to refresh digital inputs: {e}")));
50            return Err(ThreadError::DeviceError(e));
51        }
52
53        // Refresh analog inputs
54        if let Err(e) = device.read_analog_inputs() {
55            error!("Failed to refresh analog inputs: {e}");
56            self.shared_state
57                .set_error(Some(format!("Failed to refresh analog inputs: {e}")));
58            return Err(ThreadError::DeviceError(e));
59        }
60
61        // Refresh encoder values
62        for i in 0..device.encoders.len() {
63            if let Err(e) = device.get_encoder_value(i as u8) {
64                error!("Failed to refresh encoder {i}: {e}");
65                self.shared_state
66                    .set_error(Some(format!("Failed to refresh encoder {i}: {e}")));
67                // Continue with other encoders even if one fails
68            }
69        }
70
71        // Update the shared state with the refreshed device state and detect changes
72        self.shared_state
73            .update_from_device_with_notifications(device);
74
75        self.last_sync = Instant::now();
76        Ok(())
77    }
78
79    /// Get the shared state
80    pub fn shared_state(&self) -> Arc<SharedDeviceState> {
81        self.shared_state.clone()
82    }
83
84    /// Get the thread ID
85    pub fn thread_id(&self) -> u32 {
86        self.thread_id
87    }
88
89    /// Get the sync interval
90    pub fn sync_interval(&self) -> Duration {
91        self.sync_interval
92    }
93
94    /// Set the sync interval
95    pub fn set_sync_interval(&mut self, sync_interval_ms: u64) {
96        self.sync_interval = Duration::from_millis(sync_interval_ms);
97    }
98}