use std::sync::{Arc, Mutex};
use super::backend::{MotionBackend, MotionData, TouchpadBackend, TouchpadData, TouchpadFinger};
#[derive(Debug, Default)]
struct DualSenseState {
gyro_pitch: f32,
gyro_yaw: f32,
gyro_roll: f32,
accel_x: f32,
accel_y: f32,
accel_z: f32,
touch1_active: bool,
touch1_x: f32,
touch1_y: f32,
touch1_id: u8,
touch2_active: bool,
touch2_x: f32,
touch2_y: f32,
touch2_id: u8,
connected: bool,
}
pub struct DualSenseBackend {
state: Arc<Mutex<DualSenseState>>,
}
impl DualSenseBackend {
#[cfg(feature = "dualsense")]
#[must_use]
pub fn new() -> Option<Self> {
log::warn!(
"DualSense backend requires global state for 'static callbacks. \
See DualSenseBackend::new() docs for implementation pattern using once_cell."
);
None
}
#[cfg(not(feature = "dualsense"))]
#[must_use]
pub fn new() -> Option<Self> {
None
}
}
impl MotionBackend for DualSenseBackend {
fn poll(&mut self) -> Option<MotionData> {
self.state.lock().ok().map(|s| MotionData {
gyro_pitch: s.gyro_pitch,
gyro_yaw: s.gyro_yaw,
gyro_roll: s.gyro_roll,
accel_x: s.accel_x,
accel_y: s.accel_y,
accel_z: s.accel_z,
})
}
fn is_connected(&self) -> bool {
self.state.lock().map(|s| s.connected).unwrap_or(false)
}
fn name(&self) -> &'static str {
"dualsense"
}
}
impl TouchpadBackend for DualSenseBackend {
fn poll(&mut self) -> Option<TouchpadData> {
self.state.lock().ok().map(|s| TouchpadData {
finger1: TouchpadFinger {
active: s.touch1_active,
x: s.touch1_x,
y: s.touch1_y,
id: s.touch1_id,
},
finger2: TouchpadFinger {
active: s.touch2_active,
x: s.touch2_x,
y: s.touch2_y,
id: s.touch2_id,
},
button_pressed: false,
})
}
fn supports_multitouch(&self) -> bool {
true
}
fn name(&self) -> &'static str {
"dualsense"
}
}