Compare commits
2 commits
423ef593de
...
8572d89103
Author | SHA1 | Date | |
---|---|---|---|
|
8572d89103 | ||
|
bab184f140 |
5 changed files with 238 additions and 64 deletions
96
Cargo.lock
generated
96
Cargo.lock
generated
|
@ -328,6 +328,15 @@ dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deranged"
|
||||||
|
version = "0.3.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||||
|
dependencies = [
|
||||||
|
"powerfmt",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
@ -885,7 +894,7 @@ dependencies = [
|
||||||
"log 0.3.9",
|
"log 0.3.9",
|
||||||
"mime",
|
"mime",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"time",
|
"time 0.1.45",
|
||||||
"traitobject",
|
"traitobject",
|
||||||
"typeable",
|
"typeable",
|
||||||
"unicase",
|
"unicase",
|
||||||
|
@ -966,7 +975,9 @@ dependencies = [
|
||||||
"config",
|
"config",
|
||||||
"gilrs",
|
"gilrs",
|
||||||
"gtk4",
|
"gtk4",
|
||||||
|
"log 0.4.21",
|
||||||
"serde",
|
"serde",
|
||||||
|
"simplelog",
|
||||||
"toml",
|
"toml",
|
||||||
"websocket",
|
"websocket",
|
||||||
]
|
]
|
||||||
|
@ -1198,6 +1209,12 @@ dependencies = [
|
||||||
"minimal-lexical",
|
"minimal-lexical",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-conv"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
|
@ -1208,6 +1225,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_threads"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.19.0"
|
version = "1.19.0"
|
||||||
|
@ -1405,6 +1431,12 @@ version = "0.3.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "powerfmt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
version = "3.1.0"
|
version = "3.1.0"
|
||||||
|
@ -1764,6 +1796,17 @@ dependencies = [
|
||||||
"digest 0.10.7",
|
"digest 0.10.7",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simplelog"
|
||||||
|
version = "0.12.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "16257adbfaef1ee58b1363bdc0664c9b8e1e30aed86049635fb5f147d065a9c0"
|
||||||
|
dependencies = [
|
||||||
|
"log 0.4.21",
|
||||||
|
"termcolor",
|
||||||
|
"time 0.3.34",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slab"
|
name = "slab"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
@ -1841,6 +1884,15 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "termcolor"
|
||||||
|
version = "1.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.58"
|
version = "1.0.58"
|
||||||
|
@ -1872,6 +1924,39 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749"
|
||||||
|
dependencies = [
|
||||||
|
"deranged",
|
||||||
|
"itoa",
|
||||||
|
"libc",
|
||||||
|
"num-conv",
|
||||||
|
"num_threads",
|
||||||
|
"powerfmt",
|
||||||
|
"serde",
|
||||||
|
"time-core",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-core"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
|
||||||
|
dependencies = [
|
||||||
|
"num-conv",
|
||||||
|
"time-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tiny-keccak"
|
name = "tiny-keccak"
|
||||||
version = "2.0.2"
|
version = "2.0.2"
|
||||||
|
@ -2279,6 +2364,15 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||||
|
dependencies = [
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|
|
@ -10,6 +10,8 @@ async-channel = "2.2.0"
|
||||||
config = "0.14.0"
|
config = "0.14.0"
|
||||||
gilrs = "0.10.6"
|
gilrs = "0.10.6"
|
||||||
gtk = { version = "0.8.1", package = "gtk4", features = ["v4_12"] }
|
gtk = { version = "0.8.1", package = "gtk4", features = ["v4_12"] }
|
||||||
|
log = "0.4.21"
|
||||||
serde = { version = "1.0.197", features = ["derive"] }
|
serde = { version = "1.0.197", features = ["derive"] }
|
||||||
|
simplelog = "0.12.2"
|
||||||
toml = "0.8.12"
|
toml = "0.8.12"
|
||||||
websocket = "0.27.0"
|
websocket = "0.27.0"
|
||||||
|
|
|
@ -4,16 +4,74 @@ use crate::JoystickThreadUpdate;
|
||||||
|
|
||||||
use async_channel::{Receiver, Sender};
|
use async_channel::{Receiver, Sender};
|
||||||
use gilrs::{ev::filter::FilterFn, Axis, Button, Event, EventType, Filter, Gilrs, GilrsBuilder};
|
use gilrs::{ev::filter::FilterFn, Axis, Button, Event, EventType, Filter, Gilrs, GilrsBuilder};
|
||||||
use std::panic::{self, AssertUnwindSafe};
|
|
||||||
use std::{
|
use std::{
|
||||||
sync::{atomic::AtomicBool, Arc},
|
sync::{atomic::AtomicBool, Arc},
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
|
panic::{self, AssertUnwindSafe},
|
||||||
|
net::TcpStream,
|
||||||
};
|
};
|
||||||
use websocket::client::{sync::Client, ClientBuilder};
|
use websocket::client::{sync::Client, ClientBuilder};
|
||||||
use websocket::Message;
|
use websocket::Message;
|
||||||
|
use log::{info, error};
|
||||||
|
|
||||||
|
static MAX_RETRY_ATTEMPTS: u32 = 10;
|
||||||
|
|
||||||
|
struct SocketState {
|
||||||
|
pub ip: String,
|
||||||
|
pub port: i32,
|
||||||
|
pub socket: Option<Client<TcpStream>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SocketState {
|
||||||
|
fn is_connected(&self) -> bool {
|
||||||
|
self.socket.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn close_websocket(&mut self) {
|
||||||
|
if let Some(ref mut x) = self.socket {
|
||||||
|
info!("closing websocket");
|
||||||
|
x.send_message(&Message::close()).unwrap();
|
||||||
|
x.shutdown().unwrap();
|
||||||
|
self.socket = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reconnect_websocket(&mut self) -> bool {
|
||||||
|
if self.ip.is_empty() {
|
||||||
|
self.socket = None;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(mut val) = ClientBuilder::new(format!("ws://{}:{}", &self.ip, self.port).as_str())
|
||||||
|
{
|
||||||
|
if let Ok(val2) = val.connect_insecure() {
|
||||||
|
self.socket = Some(val2);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
error!("couldn't connect websocket! : Step 1");
|
||||||
|
self.socket = None;
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error!("couldn't connect websocket! : Step 2");
|
||||||
|
self.socket = None;
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct JTState {
|
||||||
|
pub socket: SocketState,
|
||||||
|
pub try_reconnect: bool,
|
||||||
|
pub retry_attempts: u32,
|
||||||
|
|
||||||
|
pub curr_x: i32,
|
||||||
|
pub curr_y: i32,
|
||||||
|
|
||||||
|
pub last_update_time: Instant,
|
||||||
|
}
|
||||||
|
|
||||||
struct UnknownSlayer;
|
struct UnknownSlayer;
|
||||||
|
|
||||||
impl FilterFn for UnknownSlayer {
|
impl FilterFn for UnknownSlayer {
|
||||||
fn filter(&self, ev: Option<Event>, _gilrs: &mut Gilrs) -> Option<Event> {
|
fn filter(&self, ev: Option<Event>, _gilrs: &mut Gilrs) -> Option<Event> {
|
||||||
match ev {
|
match ev {
|
||||||
|
@ -44,69 +102,77 @@ pub fn joystick_websocket_loop(
|
||||||
) {
|
) {
|
||||||
let mut gilrs = GilrsBuilder::new().set_update_state(false).build().unwrap();
|
let mut gilrs = GilrsBuilder::new().set_update_state(false).build().unwrap();
|
||||||
|
|
||||||
let mut ip: String;
|
let mut state = JTState {
|
||||||
let mut port: u32;
|
socket: SocketState {
|
||||||
|
ip: String::new(),
|
||||||
|
port: 0,
|
||||||
|
socket: None,
|
||||||
|
},
|
||||||
|
try_reconnect: false,
|
||||||
|
retry_attempts: 0,
|
||||||
|
|
||||||
let mut websocket: Option<Client<websocket::stream::sync::TcpStream>> = None;
|
curr_x: 0,
|
||||||
|
curr_y: 0,
|
||||||
|
|
||||||
let mut curr_x: i32 = 0;
|
last_update_time: Instant::now(),
|
||||||
let mut curr_y: i32 = 0;
|
};
|
||||||
|
|
||||||
let mut last_update_time = Instant::now();
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match rx.try_recv() {
|
match rx.try_recv() {
|
||||||
Ok(msg) => {
|
Ok(msg) => {
|
||||||
ip = msg.ip;
|
state.socket.ip = msg.ip;
|
||||||
port = msg.port;
|
state.socket.port = msg.port as i32;
|
||||||
|
|
||||||
save_config(&AppState {
|
save_config(&AppState {
|
||||||
ip: ip.clone(),
|
ip: state.socket.ip.clone(),
|
||||||
port,
|
port: state.socket.port as u32,
|
||||||
});
|
});
|
||||||
|
|
||||||
println!("ws://{}:{}", ip, port);
|
info!("Connecting to: ws://{}:{}", state.socket.ip, state.socket.port);
|
||||||
|
|
||||||
if let Some(mut x) = websocket {
|
if msg.start_websocket {
|
||||||
println!("closing websocket");
|
if !state.socket.is_connected() {
|
||||||
x.send_message(&Message::close()).unwrap();
|
state.socket.reconnect_websocket();
|
||||||
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 {
|
} else if state.socket.is_connected() {
|
||||||
println!("couldn't connect websocket! : Step 2");
|
state.socket.close_websocket();
|
||||||
None
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(async_channel::TryRecvError::Closed) => break,
|
Err(async_channel::TryRecvError::Closed) => break,
|
||||||
Err(async_channel::TryRecvError::Empty) => {}
|
Err(async_channel::TryRecvError::Empty) => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if state.try_reconnect {
|
||||||
|
if state.retry_attempts > MAX_RETRY_ATTEMPTS {
|
||||||
|
state.try_reconnect = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if state.socket.is_connected() {
|
||||||
|
state.try_reconnect = false;
|
||||||
|
} else if state.socket.reconnect_websocket() {
|
||||||
|
state.try_reconnect = false;
|
||||||
|
state.retry_attempts = 0;
|
||||||
|
} else {
|
||||||
|
state.retry_attempts += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// catch unwind because some buttons on the joystick will panic the gilrs object
|
||||||
match panic::catch_unwind(AssertUnwindSafe(|| {
|
match panic::catch_unwind(AssertUnwindSafe(|| {
|
||||||
|
// get the next event, and if it is an axis we are interested in, update the
|
||||||
|
// corresponding variable
|
||||||
while let Some(evt) = gilrs.next_event().filter_ev(&UnknownSlayer {}, &mut gilrs) {
|
while let Some(evt) = gilrs.next_event().filter_ev(&UnknownSlayer {}, &mut gilrs) {
|
||||||
match evt.event {
|
match evt.event {
|
||||||
gilrs::EventType::AxisChanged(gilrs::Axis::LeftStickY, val, _) => {
|
gilrs::EventType::AxisChanged(gilrs::Axis::LeftStickY, val, _) => {
|
||||||
curr_y = (val * 100.0) as i32;
|
state.curr_y = (val * 100.0) as i32;
|
||||||
if curr_y > -10 && curr_y < 10 {
|
if state.curr_y > -10 && state.curr_y < 10 {
|
||||||
curr_y = 0;
|
state.curr_y = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gilrs::EventType::AxisChanged(gilrs::Axis::LeftStickX, val, _) => {
|
gilrs::EventType::AxisChanged(gilrs::Axis::LeftStickX, val, _) => {
|
||||||
curr_x = (val * 100.0) as i32;
|
state.curr_x = (val * 100.0) as i32;
|
||||||
if curr_x > -10 && curr_x < 10 {
|
if state.curr_x > -10 && state.curr_x < 10 {
|
||||||
curr_x = 0;
|
state.curr_x = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -115,38 +181,40 @@ pub fn joystick_websocket_loop(
|
||||||
})) {
|
})) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
println!("panic-causing event captured")
|
info!("panic-causing event captured in gilrs event handler")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if websocket.is_some()
|
if state.socket.is_connected()
|
||||||
&& Instant::now().duration_since(last_update_time) >= Duration::from_millis(150)
|
&& Instant::now().duration_since(state.last_update_time) >= Duration::from_millis(150)
|
||||||
{
|
{
|
||||||
let mut message: String;
|
let mut message: String;
|
||||||
if curr_y > 0 {
|
if state.curr_y > 0 {
|
||||||
message = format!("D{}:", curr_y);
|
message = format!("D{}:", state.curr_y);
|
||||||
} else {
|
} else {
|
||||||
message = format!("U{}:", curr_y.abs());
|
message = format!("U{}:", state.curr_y.abs());
|
||||||
}
|
}
|
||||||
|
|
||||||
if curr_x > 0 {
|
if state.curr_x > 0 {
|
||||||
message.push_str(&format!("R{}", curr_x));
|
message.push_str(&format!("R{}", state.curr_x));
|
||||||
} else {
|
} else {
|
||||||
message.push_str(&format!("L{}", curr_x.abs()));
|
message.push_str(&format!("L{}", state.curr_x.abs()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(mut websocket_tx) = websocket {
|
if let Some(ref mut websocket_tx) = state.socket.socket {
|
||||||
websocket_tx.send_message(&Message::text(message)).unwrap();
|
if websocket_tx.send_message(&Message::text(message)).is_ok() {
|
||||||
websocket = Some(websocket_tx);
|
} else {
|
||||||
|
state.socket.close_websocket();
|
||||||
}
|
}
|
||||||
last_update_time = Instant::now();
|
}
|
||||||
|
state.last_update_time = Instant::now();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
match tx.try_send(JoystickThreadUpdate {
|
match tx.try_send(JoystickThreadUpdate {
|
||||||
connected: websocket.is_some(),
|
connected: state.socket.is_connected(),
|
||||||
x_axis: Some(curr_x.to_string()),
|
x_axis: Some(state.curr_x.to_string()),
|
||||||
y_axis: Some(curr_y.to_string()),
|
y_axis: Some(state.curr_y.to_string()),
|
||||||
}) {
|
}) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(async_channel::TrySendError::Closed(_)) => break,
|
Err(async_channel::TrySendError::Closed(_)) => break,
|
||||||
|
@ -154,7 +222,7 @@ pub fn joystick_websocket_loop(
|
||||||
}
|
}
|
||||||
|
|
||||||
if !do_run.load(std::sync::atomic::Ordering::SeqCst) {
|
if !do_run.load(std::sync::atomic::Ordering::SeqCst) {
|
||||||
println!("Exiting thread");
|
info!("Exiting joystick thread");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::thread::sleep(Duration::from_millis(25));
|
std::thread::sleep(Duration::from_millis(25));
|
||||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -1,6 +1,8 @@
|
||||||
use gtk::gdk::Display;
|
use gtk::gdk::Display;
|
||||||
use gtk::{glib, Application};
|
use gtk::{glib, Application};
|
||||||
use gtk::{prelude::*, CssProvider};
|
use gtk::{prelude::*, CssProvider};
|
||||||
|
use log::info;
|
||||||
|
use simplelog::SimpleLogger;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
|
@ -17,6 +19,13 @@ pub struct JoystickThreadUpdate {
|
||||||
fn main() -> glib::ExitCode {
|
fn main() -> glib::ExitCode {
|
||||||
env::set_var("gtk_csd", "0");
|
env::set_var("gtk_csd", "0");
|
||||||
|
|
||||||
|
match SimpleLogger::init(simplelog::LevelFilter::Debug, simplelog::Config::default()) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
println!("Failed to init the simplelogger!: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create a new application
|
// Create a new application
|
||||||
let app = Application::builder().application_id(APP_ID).build();
|
let app = Application::builder().application_id(APP_ID).build();
|
||||||
|
|
||||||
|
@ -27,7 +36,7 @@ fn main() -> glib::ExitCode {
|
||||||
// Run the application
|
// Run the application
|
||||||
let exit_code = app.run();
|
let exit_code = app.run();
|
||||||
|
|
||||||
println!("Closing down");
|
info!("Closing down");
|
||||||
|
|
||||||
exit_code
|
exit_code
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use gtk::{glib, prelude::*, Box, Entry, Label, ListBox};
|
use gtk::{glib, prelude::*, Box, Entry, Label, ListBox};
|
||||||
use gtk::{Application, ApplicationWindow, Button};
|
use gtk::{Application, ApplicationWindow, Button};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::{Arc, atomic::AtomicBool};
|
||||||
use std::sync::Arc;
|
use log::error;
|
||||||
|
|
||||||
use crate::config::load_config;
|
use crate::config::load_config;
|
||||||
use crate::{joystick_loop, JoystickThreadUpdate};
|
use crate::{joystick_loop, JoystickThreadUpdate};
|
||||||
|
@ -10,6 +10,7 @@ use crate::{joystick_loop, JoystickThreadUpdate};
|
||||||
pub struct SocketConnectionUpdate {
|
pub struct SocketConnectionUpdate {
|
||||||
pub ip: String,
|
pub ip: String,
|
||||||
pub port: u32,
|
pub port: u32,
|
||||||
|
pub start_websocket: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
|
@ -92,10 +93,11 @@ pub fn build_ui(app: &Application) {
|
||||||
match tx2.try_send(SocketConnectionUpdate {
|
match tx2.try_send(SocketConnectionUpdate {
|
||||||
ip: ip_text.to_string(),
|
ip: ip_text.to_string(),
|
||||||
port: val,
|
port: val,
|
||||||
|
start_websocket: ip_entry.get_sensitive(),
|
||||||
}) {
|
}) {
|
||||||
Ok(_) => { }
|
Ok(_) => { }
|
||||||
Err(async_channel::TrySendError::Closed(_)) => {panic!("Joystick thread was closed. Unrecoverable")}
|
Err(async_channel::TrySendError::Closed(_)) => {panic!("Joystick thread was closed. Unrecoverable")}
|
||||||
Err(e) => {println!("There was an error: {e}")}
|
Err(e) => {error!("There was an error: {e}")}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +105,6 @@ pub fn build_ui(app: &Application) {
|
||||||
|
|
||||||
glib::spawn_future_local(
|
glib::spawn_future_local(
|
||||||
glib::clone!(@weak axis_label, @weak button, @weak conn_status_label, @weak ip_entry, @weak port_entry, @strong rx => async move {
|
glib::clone!(@weak axis_label, @weak button, @weak conn_status_label, @weak ip_entry, @weak port_entry, @strong rx => async move {
|
||||||
println!("Hello from spawn future local");
|
|
||||||
while let Ok(msg) = rx.recv().await {
|
while let Ok(msg) = rx.recv().await {
|
||||||
axis_label.set_text(
|
axis_label.set_text(
|
||||||
format!("X: {:>4} Y: {:>4}", msg.x_axis.unwrap_or("0".to_string()), msg.y_axis.unwrap_or("0".to_string())).as_str()
|
format!("X: {:>4} Y: {:>4}", msg.x_axis.unwrap_or("0".to_string()), msg.y_axis.unwrap_or("0".to_string())).as_str()
|
||||||
|
|
Loading…
Reference in a new issue