Refactor gamepad code to be sync
This commit is contained in:
parent
9a450cfe9c
commit
efcc13bea7
|
@ -4,11 +4,11 @@ use gilrs::Button::LeftTrigger2;
|
||||||
use gilrs::Button::RightTrigger2;
|
use gilrs::Button::RightTrigger2;
|
||||||
use gilrs::EventType::*;
|
use gilrs::EventType::*;
|
||||||
use gilrs::Gilrs;
|
use gilrs::Gilrs;
|
||||||
|
use std::sync::mpsc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::sync::mpsc;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Axis {
|
pub enum Axis {
|
||||||
|
@ -41,73 +41,70 @@ pub enum GamepadEvent {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct Gamepad {
|
pub struct Gamepad {
|
||||||
speed_setpoint: Mutex<(f32, f32, f32)>,
|
gilrs: Gilrs,
|
||||||
|
// Cached speed setpoint for (X, Y, Positive-Z, Negative-Z)
|
||||||
|
speed_setpoint: (f32, f32, f32, f32),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gamepad {
|
impl Gamepad {
|
||||||
/// Create a new `Gamepad` and spawn the underlying tasks for updating internal setpoints
|
/// Create a new `Gamepad` and spawn the underlying tasks for updating internal setpoints
|
||||||
///
|
///
|
||||||
/// The tasks are terminated on drop.
|
/// The tasks are terminated on drop.
|
||||||
pub async fn new() -> Result<Arc<Self>, gilrs::Error> {
|
pub fn new() -> Result<Self, gilrs::Error> {
|
||||||
let (gamepad_tx, gamepad_rx) = mpsc::channel(8);
|
let gilrs = Gilrs::new().unwrap();
|
||||||
let res = Arc::new(Gamepad {
|
for (_id, gamepad) in gilrs.gamepads() {
|
||||||
speed_setpoint: Mutex::new((0.0, 0.0, 0.0)),
|
println!(
|
||||||
});
|
"Found gamepad {}: {:?}",
|
||||||
tokio::task::spawn_blocking(move || {
|
gamepad.name(),
|
||||||
let mut gilrs = Gilrs::new().unwrap();
|
gamepad.power_info()
|
||||||
for (_id, gamepad) in gilrs.gamepads() {
|
);
|
||||||
println!("{} is {:?}", gamepad.name(), gamepad.power_info());
|
}
|
||||||
}
|
|
||||||
loop {
|
|
||||||
sleep(Duration::from_millis(1));
|
|
||||||
if let Some(event) = gilrs.next_event() {
|
|
||||||
if let Some(internal_event) = Self::map_event(event) {
|
|
||||||
if gamepad_tx.blocking_send(internal_event).is_err() {
|
|
||||||
// receiver dropped
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
tokio::spawn(Self::handle_events(res.clone(), gamepad_rx));
|
Ok(Self {
|
||||||
|
gilrs,
|
||||||
Ok(res)
|
speed_setpoint: (0.0, 0.0, 0.0, 0.0),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the current speed that the user is dialing in on the gamepad
|
fn get_next(&mut self) -> Option<GamepadEvent> {
|
||||||
pub fn speed_setpoint(&self) -> (f32, f32, f32) {
|
self.gilrs
|
||||||
*self.speed_setpoint.lock().unwrap()
|
.next_event()
|
||||||
|
.and_then(|event| Self::map_event(event))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the setpoints in accordance to incoming `GamepadEvent`s
|
// Get all `GamepadEvent`s since the last call
|
||||||
async fn handle_events(self_arc: Arc<Self>, mut events_rx: mpsc::Receiver<GamepadEvent>) {
|
pub fn get_pending(&mut self) -> Vec<GamepadEvent> {
|
||||||
// There is two z-axes that counter each other.
|
(0..).map_while(|_| self.get_next()).collect()
|
||||||
let mut z_positive = 0.0;
|
}
|
||||||
let mut z_negative = 0.0;
|
|
||||||
while let Some(event) = events_rx.recv().await {
|
/// Update the current speed via the movements on the controller and return the current setpoint
|
||||||
|
///
|
||||||
|
/// If you don't want to update, just supply an empty `updates` slice
|
||||||
|
pub fn speed_setpoint(&mut self, updates: &[GamepadEvent]) -> (f32, f32, f32) {
|
||||||
|
for event in updates {
|
||||||
match event {
|
match event {
|
||||||
GamepadEvent::TerminatePressed => break,
|
GamepadEvent::TerminatePressed => break,
|
||||||
GamepadEvent::AxisPosition(axis, value) => {
|
GamepadEvent::AxisPosition(axis, value) => {
|
||||||
// I won't panic if you don't panic!
|
// I won't panic if you don't panic!
|
||||||
let mut speed_setpoint = self_arc.speed_setpoint.lock().unwrap();
|
let mut speed_setpoint = self.speed_setpoint;
|
||||||
match axis {
|
match axis {
|
||||||
Axis::X => speed_setpoint.0 = value,
|
Axis::X => speed_setpoint.0 = *value,
|
||||||
Axis::Y => speed_setpoint.1 = value,
|
Axis::Y => speed_setpoint.1 = *value,
|
||||||
Axis::ZPositive => {
|
Axis::ZPositive => {
|
||||||
z_positive = value;
|
speed_setpoint.2 = *value;
|
||||||
speed_setpoint.2 = z_positive - z_negative;
|
|
||||||
}
|
}
|
||||||
Axis::ZNegative => {
|
Axis::ZNegative => {
|
||||||
z_negative = value;
|
speed_setpoint.3 = *value;
|
||||||
speed_setpoint.2 = z_positive - z_negative;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("Game pad quit!")
|
(
|
||||||
|
self.speed_setpoint.0,
|
||||||
|
self.speed_setpoint.1,
|
||||||
|
self.speed_setpoint.2 - self.speed_setpoint.3,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_event(event: gilrs::Event) -> Option<GamepadEvent> {
|
fn map_event(event: gilrs::Event) -> Option<GamepadEvent> {
|
||||||
|
|
Loading…
Reference in a new issue