use super::*;
#[derive(Debug)]
pub struct SimpleJoyConDriver {
pub joycon: Arc<Mutex<JoyConDevice>>,
pub rotation: Rotation,
rumble: (Option<Rumble>, Option<Rumble>),
enabled_features: HashSet<JoyConFeature>,
valid_reply: bool,
global_packet_number: GlobalPacketNumber,
}
impl SimpleJoyConDriver {
pub fn new(joycon: &Arc<Mutex<JoyConDevice>>) -> JoyConResult<Self> {
let mut enabled_features = HashSet::new();
enabled_features.insert(JoyConFeature::IMUFeature(IMUConfig::default()));
enabled_features.insert(JoyConFeature::Vibration);
let mut driver = Self {
joycon: Arc::clone(joycon),
rotation: Rotation::Portrait,
rumble: (None, None),
enabled_features,
valid_reply: {
let device = match joycon.lock() {
Ok(j) => j,
Err(e) => e.into_inner(),
}.device_type();
match device {
JoyConDeviceType::ProCon => false,
_ => true,
}
},
global_packet_number: GlobalPacketNumber::default(),
};
let check_reply = {
let device = match joycon.lock() {
Ok(d) => d,
Err(e) => e.into_inner(),
};
match device.device_type() {
JoyConDeviceType::ProCon => false,
_ => true,
}
};
if check_reply {
driver.reset()?;
} else {
let _ = driver.reset();
}
Ok(driver)
}
pub fn joycon(&self) -> MutexGuard<JoyConDevice> {
match self.joycon.lock() {
Ok(joycon) => joycon,
Err(poisoned) => poisoned.into_inner(),
}
}
}
impl JoyConDriver for SimpleJoyConDriver {
fn valid_reply(&self) -> bool {
self.valid_reply
}
fn set_valid_reply(&mut self, valid: bool) {
self.valid_reply = valid;
}
fn write(&self, data: &[u8]) -> JoyConResult<usize> {
let joycon = self.joycon();
Ok(joycon.write(data)?)
}
fn read(&self, buf: &mut [u8]) -> JoyConResult<usize> {
Ok(self.joycon().read(buf)?)
}
fn read_timeout(&self, buf: &mut [u8], timeout: i32) -> JoyConResult<usize> {
Ok(self.joycon().read_timeout(buf,timeout)?)
}
fn global_packet_number(&self) -> u8 {
self.global_packet_number.into()
}
fn increase_global_packet_number(&mut self) {
self.global_packet_number = self.global_packet_number.next();
}
fn set_rumble_status(&mut self, rumble_l_r: (Option<Rumble>, Option<Rumble>)) {
self.rumble = rumble_l_r;
}
fn get_rumble_status(&self) -> (Option<Rumble>, Option<Rumble>) {
self.rumble
}
fn enable_feature(&mut self, feature: JoyConFeature) -> JoyConResult<()> {
match feature {
JoyConFeature::IMUFeature(feature) => {
let data: [u8; 4] = feature.into();
self.send_sub_command(SubCommand::EnableIMU, &[0x01])?;
self.send_sub_command(SubCommand::SetIMUSensitivity, &data)?;
}
JoyConFeature::Vibration => {
self.send_sub_command(SubCommand::EnableVibration, &[0x01])?;
}
}
self.enabled_features.insert(feature);
Ok(())
}
fn enabled_features(&self) -> &HashSet<JoyConFeature> {
&self.enabled_features
}
fn devices(&self) -> Vec<Arc<Mutex<JoyConDevice>>> {
vec![Arc::clone(&self.joycon)]
}
}