use std::sync::{Arc, Mutex};
use std::time::Instant;
use tokio::sync::RwLock;
use std::collections::HashMap;
pub mod config;
pub mod device;
pub mod hotplug;
pub mod key_parser;
pub mod layer_manager;
pub mod analog_calibration;
pub mod analog_processor;
pub mod macro_engine;
pub mod remap_engine;
pub mod injector;
pub mod ipc;
pub mod security;
pub mod led_controller;
pub mod auto_profile_switcher;
pub mod global_hotkey_manager;
pub mod gamepad_device;
pub use aethermap_common::{DeviceInfo, MacroEntry, Profile};
pub use config::{RemapEntry, RemapConfigError, AutoSwitchRule};
pub use remap_engine::{RemapProfile, RemapTable};
pub use hotplug::{DeviceEvent, DeviceMonitor};
pub use device::{DeviceProfileInfo, GrabbedDevice};
pub use layer_manager::{LayerManager, DeviceLayerState, LayerConfig, LayerMode};
pub use analog_calibration::{AnalogCalibration, DeadzoneShape, SensitivityCurve};
pub use analog_processor::{AnalogProcessor, DeviceAnalogConfig, ResponseCurve};
pub use led_controller::{LedController, LedZone, LedState, LedError, DeviceLedState};
pub use auto_profile_switcher::AutoProfileSwitcher;
pub use global_hotkey_manager::GlobalHotkeyManager;
pub use gamepad_device::{GamepadVirtualDevice, GamepadAxis};
pub struct DaemonState {
pub start_time: Instant,
pub devices: Arc<Mutex<Vec<DeviceInfo>>>,
pub macros: Arc<Mutex<HashMap<String, MacroEntry>>>,
pub profiles: Arc<Mutex<HashMap<String, Profile>>>,
pub macro_engine: Option<Arc<macro_engine::MacroEngine>>,
pub remap_engine: Option<Arc<remap_engine::RemapEngine>>,
pub device_manager: Option<Arc<RwLock<device::DeviceManager>>>,
pub layer_manager: Arc<RwLock<LayerManager>>,
pub analog_processor: Option<Arc<analog_processor::AnalogProcessor>>,
pub led_controller: Option<Arc<led_controller::LedController>>,
pub led_state: Arc<RwLock<HashMap<String, DeviceLedState>>>,
pub hotkey_manager: Option<Arc<tokio::sync::Mutex<global_hotkey_manager::GlobalHotkeyManager>>>,
pub analog_subscribers: Arc<RwLock<HashMap<String, Vec<tokio::sync::mpsc::UnboundedSender<aethermap_common::Response>>>>>,
pub active_recording: Option<(String, String)>, }
impl DaemonState {
pub fn new() -> Self {
Self {
start_time: Instant::now(),
devices: Arc::new(Mutex::new(Vec::new())),
macros: Arc::new(Mutex::new(HashMap::new())),
profiles: Arc::new(Mutex::new(HashMap::new())),
macro_engine: None,
remap_engine: None,
device_manager: None,
layer_manager: Arc::new(RwLock::new(LayerManager::new(None))),
analog_processor: None,
led_controller: None,
led_state: Arc::new(RwLock::new(HashMap::new())),
hotkey_manager: None,
analog_subscribers: Arc::new(RwLock::new(HashMap::new())),
active_recording: None,
}
}
pub async fn set_led_controller(
&mut self,
led_controller: Option<Arc<led_controller::LedController>>,
) {
let mut layer_manager = self.layer_manager.write().await;
*layer_manager = LayerManager::new(led_controller.clone());
self.led_controller = led_controller;
tracing::info!("LED controller configured for layer-aware feedback");
}
pub async fn initialize_led_state(&self, device_id: &str) {
let mut led_state = self.led_state.write().await;
led_state.entry(device_id.to_string())
.or_insert_with(DeviceLedState::default);
}
}