use super::ds::*;
use super::robot_base::*;
use wpilib_sys::*;
const RUMBLE_BASE: i32 = 65535;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum JoystickSide {
LeftHand,
RightHand,
}
pub trait JoystickBase {
fn raw_axis(&self, axis: usize) -> Result<f32, JoystickError>;
fn raw_button(&self, button: usize) -> Result<bool, JoystickError>;
fn pov(&self, pov: usize) -> Result<i16, JoystickError>;
fn set_output(&mut self, output_number: i32, value: bool);
fn set_outputs(&mut self, value: i64);
fn set_rumble(&mut self, side: JoystickSide, value: f32);
}
#[derive(Debug)]
pub struct Joystick {
port: usize,
ds: ThreadSafeDs,
outputs: i64,
left_rumble: i32,
right_rumble: i32,
}
impl Joystick {
pub fn new(rbase: &RobotBase, port: usize) -> Joystick {
Self::new_raw_ds(rbase.ds_instance(), port)
}
pub fn new_raw_ds(ds: ThreadSafeDs, port: usize) -> Joystick {
Joystick {
port,
ds,
outputs: 0i64,
left_rumble: 0i32,
right_rumble: 0i32,
}
}
}
impl JoystickBase for Joystick {
fn raw_axis(&self, axis: usize) -> Result<f32, JoystickError> {
let read_lock = self.ds.read().map_err(|_| JoystickError::DsUnreachable)?;
read_lock.joystick_axis(self.port, axis)
}
fn raw_button(&self, button: usize) -> Result<bool, JoystickError> {
let read_lock = self.ds.read().map_err(|_| JoystickError::DsUnreachable)?;
read_lock.joystick_button(self.port, button)
}
fn pov(&self, pov: usize) -> Result<i16, JoystickError> {
let read_lock = self.ds.read().map_err(|_| JoystickError::DsUnreachable)?;
read_lock.joystick_pov(self.port, pov)
}
fn set_output(&mut self, output_number: i32, value: bool) {
let o = output_number - 1i32;
self.outputs = (self.outputs & i64::from(!(1i32 << o))) | ((value as i64) << o);
unsafe {
HAL_SetJoystickOutputs(
self.port as i32,
self.outputs,
self.left_rumble,
self.right_rumble,
);
}
}
fn set_outputs(&mut self, value: i64) {
self.outputs = value;
unsafe {
HAL_SetJoystickOutputs(
self.port as i32,
self.outputs,
self.left_rumble,
self.right_rumble,
);
}
}
fn set_rumble(&mut self, side: JoystickSide, mut value: f32) {
value = if value > 1f32 {
1f32
} else if value < 0f32 {
0f32
} else {
value
};
match side {
JoystickSide::LeftHand => self.left_rumble = (value * RUMBLE_BASE as f32) as i32,
JoystickSide::RightHand => self.right_rumble = (value * RUMBLE_BASE as f32) as i32,
}
unsafe {
HAL_SetJoystickOutputs(
self.port as i32,
self.outputs,
self.left_rumble,
self.right_rumble,
)
};
}
}