163 lines
5.2 KiB
Rust
163 lines
5.2 KiB
Rust
|
use crate::config::save_config;
|
||
|
use crate::ui_code::{AppState, SocketConnectionUpdate};
|
||
|
use crate::JoystickThreadUpdate;
|
||
|
|
||
|
use async_channel::{Receiver, Sender};
|
||
|
use gilrs::{ev::filter::FilterFn, Axis, Button, Event, EventType, Filter, Gilrs, GilrsBuilder};
|
||
|
use std::panic::{self, AssertUnwindSafe};
|
||
|
use std::{
|
||
|
sync::{atomic::AtomicBool, Arc},
|
||
|
time::{Duration, Instant},
|
||
|
};
|
||
|
use websocket::client::{sync::Client, ClientBuilder};
|
||
|
use websocket::Message;
|
||
|
|
||
|
struct UnknownSlayer;
|
||
|
|
||
|
impl FilterFn for UnknownSlayer {
|
||
|
fn filter(&self, ev: Option<Event>, _gilrs: &mut Gilrs) -> Option<Event> {
|
||
|
match ev {
|
||
|
Some(Event {
|
||
|
event: EventType::ButtonPressed(Button::Unknown, ..),
|
||
|
id,
|
||
|
..
|
||
|
})
|
||
|
| Some(Event {
|
||
|
event: EventType::ButtonReleased(Button::Unknown, ..),
|
||
|
id,
|
||
|
..
|
||
|
})
|
||
|
| Some(Event {
|
||
|
event: EventType::AxisChanged(Axis::Unknown, ..),
|
||
|
id,
|
||
|
..
|
||
|
}) => Some(Event::new(id, EventType::Dropped)),
|
||
|
_ => ev,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn joystick_websocket_loop(
|
||
|
tx: Sender<JoystickThreadUpdate>,
|
||
|
do_run: Arc<AtomicBool>,
|
||
|
rx: Receiver<SocketConnectionUpdate>,
|
||
|
) {
|
||
|
let mut gilrs = GilrsBuilder::new().set_update_state(false).build().unwrap();
|
||
|
|
||
|
let mut ip: String;
|
||
|
let mut port: u32;
|
||
|
|
||
|
let mut websocket: Option<Client<websocket::stream::sync::TcpStream>> = None;
|
||
|
|
||
|
let mut curr_x: i32 = 0;
|
||
|
let mut curr_y: i32 = 0;
|
||
|
|
||
|
let mut last_update_time = Instant::now();
|
||
|
|
||
|
loop {
|
||
|
match rx.try_recv() {
|
||
|
Ok(msg) => {
|
||
|
ip = msg.ip;
|
||
|
port = msg.port;
|
||
|
|
||
|
save_config(&AppState {
|
||
|
ip: ip.clone(),
|
||
|
port,
|
||
|
});
|
||
|
|
||
|
println!("ws://{}:{}", ip, port);
|
||
|
|
||
|
if let Some(mut x) = websocket {
|
||
|
println!("closing websocket");
|
||
|
x.send_message(&Message::close()).unwrap();
|
||
|
x.shutdown().unwrap();
|
||
|
websocket = None;
|
||
|
} else {
|
||
|
websocket = {
|
||
|
if let Ok(mut val) =
|
||
|
ClientBuilder::new(format!("ws://{}:{}", ip, port).as_str())
|
||
|
{
|
||
|
if let Ok(val2) = val.connect_insecure() {
|
||
|
Some(val2)
|
||
|
} else {
|
||
|
println!("couldn't connect websocket! : Step 1");
|
||
|
None
|
||
|
}
|
||
|
} else {
|
||
|
println!("couldn't connect websocket! : Step 2");
|
||
|
None
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
Err(async_channel::TryRecvError::Closed) => break,
|
||
|
Err(async_channel::TryRecvError::Empty) => {}
|
||
|
}
|
||
|
|
||
|
match panic::catch_unwind(AssertUnwindSafe(|| {
|
||
|
while let Some(evt) = gilrs.next_event().filter_ev(&UnknownSlayer {}, &mut gilrs) {
|
||
|
match evt.event {
|
||
|
gilrs::EventType::AxisChanged(gilrs::Axis::LeftStickY, val, _) => {
|
||
|
curr_y = (val * 100.0) as i32;
|
||
|
if curr_y > -10 && curr_y < 10 {
|
||
|
curr_y = 0;
|
||
|
}
|
||
|
}
|
||
|
gilrs::EventType::AxisChanged(gilrs::Axis::LeftStickX, val, _) => {
|
||
|
curr_x = (val * 100.0) as i32;
|
||
|
if curr_x > -10 && curr_x < 10 {
|
||
|
curr_x = 0;
|
||
|
}
|
||
|
}
|
||
|
_ => {}
|
||
|
}
|
||
|
}
|
||
|
})) {
|
||
|
Ok(_) => {}
|
||
|
Err(_) => {
|
||
|
println!("panic-causing event captured")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if websocket.is_some()
|
||
|
&& Instant::now().duration_since(last_update_time) >= Duration::from_millis(150)
|
||
|
{
|
||
|
let mut message: String;
|
||
|
if curr_y > 0 {
|
||
|
message = format!("D{}:", curr_y);
|
||
|
} else {
|
||
|
message = format!("U{}:", curr_y.abs());
|
||
|
}
|
||
|
|
||
|
if curr_x > 0 {
|
||
|
message.push_str(&format!("R{}", curr_x));
|
||
|
} else {
|
||
|
message.push_str(&format!("L{}", curr_x.abs()));
|
||
|
}
|
||
|
|
||
|
if let Some(mut websocket_tx) = websocket {
|
||
|
websocket_tx.send_message(&Message::text(message)).unwrap();
|
||
|
websocket = Some(websocket_tx);
|
||
|
}
|
||
|
last_update_time = Instant::now();
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
match tx.try_send(JoystickThreadUpdate {
|
||
|
connected: websocket.is_some(),
|
||
|
x_axis: Some(curr_x.to_string()),
|
||
|
y_axis: Some(curr_y.to_string()),
|
||
|
}) {
|
||
|
Ok(_) => {}
|
||
|
Err(async_channel::TrySendError::Closed(_)) => break,
|
||
|
Err(async_channel::TrySendError::Full(_)) => {}
|
||
|
}
|
||
|
|
||
|
if !do_run.load(std::sync::atomic::Ordering::SeqCst) {
|
||
|
println!("Exiting thread");
|
||
|
break;
|
||
|
}
|
||
|
std::thread::sleep(Duration::from_millis(25));
|
||
|
}
|
||
|
}
|