Skip to content

Commit 6f1108b

Browse files
authored
Merge pull request #340 from CryZe/delayed-gamepad-hook
Delay registering the Gamepad Hook
2 parents 3eadd11 + 122ad92 commit 6f1108b

File tree

2 files changed

+48
-39
lines changed

2 files changed

+48
-39
lines changed

crates/livesplit-hotkey/src/linux/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ impl Hook {
195195
});
196196

197197
Ok(Hook {
198-
sender: sender,
199-
ping: ping,
198+
sender,
199+
ping,
200200
_registration: registration,
201201
join_handle: Some(join_handle),
202202
})

crates/livesplit-hotkey/src/wasm_web/mod.rs

+46-37
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@ use wasm_bindgen::prelude::*;
55
use wasm_bindgen::JsCast;
66
use web_sys::{window, Gamepad, GamepadButton, KeyboardEvent};
77

8-
use std::collections::hash_map::{Entry, HashMap};
9-
use std::sync::{Arc, Mutex};
8+
use std::{
9+
cell::Cell,
10+
collections::hash_map::{Entry, HashMap},
11+
sync::{Arc, Mutex},
12+
};
1013

1114
#[derive(Debug, snafu::Snafu)]
1215
pub enum Error {
@@ -20,8 +23,8 @@ pub type Result<T> = std::result::Result<T, Error>;
2023
pub struct Hook {
2124
hotkeys: Arc<Mutex<HashMap<KeyCode, Box<dyn FnMut() + Send + 'static>>>>,
2225
keyboard_callback: Closure<dyn FnMut(KeyboardEvent)>,
23-
_gamepad_callback: Closure<dyn FnMut()>,
24-
interval_id: i32,
26+
gamepad_callback: Closure<dyn FnMut()>,
27+
interval_id: Cell<Option<i32>>,
2528
}
2629

2730
impl Drop for Hook {
@@ -31,11 +34,37 @@ impl Drop for Hook {
3134
"keypress",
3235
self.keyboard_callback.as_ref().unchecked_ref(),
3336
);
34-
window.clear_interval_with_handle(self.interval_id);
37+
if let Some(interval_id) = self.interval_id.get() {
38+
window.clear_interval_with_handle(interval_id);
39+
}
3540
}
3641
}
3742
}
3843

44+
const TOTAL_BUTTONS: usize = 20;
45+
static GAMEPAD_BUTTONS: [KeyCode; TOTAL_BUTTONS] = [
46+
KeyCode::Gamepad0,
47+
KeyCode::Gamepad1,
48+
KeyCode::Gamepad2,
49+
KeyCode::Gamepad3,
50+
KeyCode::Gamepad4,
51+
KeyCode::Gamepad5,
52+
KeyCode::Gamepad6,
53+
KeyCode::Gamepad7,
54+
KeyCode::Gamepad8,
55+
KeyCode::Gamepad9,
56+
KeyCode::Gamepad10,
57+
KeyCode::Gamepad11,
58+
KeyCode::Gamepad12,
59+
KeyCode::Gamepad13,
60+
KeyCode::Gamepad14,
61+
KeyCode::Gamepad15,
62+
KeyCode::Gamepad16,
63+
KeyCode::Gamepad17,
64+
KeyCode::Gamepad18,
65+
KeyCode::Gamepad19,
66+
];
67+
3968
impl Hook {
4069
pub fn new() -> Result<Self> {
4170
let hotkeys = Arc::new(Mutex::new(HashMap::<
@@ -63,29 +92,6 @@ impl Hook {
6392

6493
let hotkey_map = hotkeys.clone();
6594

66-
const TOTAL_BUTTONS: usize = 20;
67-
static GAMEPAD_BUTTONS: [KeyCode; TOTAL_BUTTONS] = [
68-
KeyCode::Gamepad0,
69-
KeyCode::Gamepad1,
70-
KeyCode::Gamepad2,
71-
KeyCode::Gamepad3,
72-
KeyCode::Gamepad4,
73-
KeyCode::Gamepad5,
74-
KeyCode::Gamepad6,
75-
KeyCode::Gamepad7,
76-
KeyCode::Gamepad8,
77-
KeyCode::Gamepad9,
78-
KeyCode::Gamepad10,
79-
KeyCode::Gamepad11,
80-
KeyCode::Gamepad12,
81-
KeyCode::Gamepad13,
82-
KeyCode::Gamepad14,
83-
KeyCode::Gamepad15,
84-
KeyCode::Gamepad16,
85-
KeyCode::Gamepad17,
86-
KeyCode::Gamepad18,
87-
KeyCode::Gamepad19,
88-
];
8995
let mut states = Vec::new();
9096
let navigator = window.navigator();
9197

@@ -120,18 +126,11 @@ impl Hook {
120126
}
121127
}) as Box<dyn FnMut()>);
122128

123-
let interval_id = window
124-
.set_interval_with_callback_and_timeout_and_arguments_0(
125-
gamepad_callback.as_ref().unchecked_ref(),
126-
1000 / 60,
127-
)
128-
.map_err(|_| Error::FailedToCreateHook)?;
129-
130129
Ok(Hook {
131130
hotkeys,
132131
keyboard_callback,
133-
_gamepad_callback: gamepad_callback,
134-
interval_id,
132+
gamepad_callback,
133+
interval_id: Cell::new(None),
135134
})
136135
}
137136

@@ -140,6 +139,16 @@ impl Hook {
140139
F: FnMut() + Send + 'static,
141140
{
142141
if let Entry::Vacant(vacant) = self.hotkeys.lock().unwrap().entry(hotkey) {
142+
if GAMEPAD_BUTTONS.contains(&hotkey) && self.interval_id.get().is_none() {
143+
let interval_id = window()
144+
.ok_or(Error::FailedToCreateHook)?
145+
.set_interval_with_callback_and_timeout_and_arguments_0(
146+
self.gamepad_callback.as_ref().unchecked_ref(),
147+
1000 / 60,
148+
)
149+
.map_err(|_| Error::FailedToCreateHook)?;
150+
self.interval_id.set(Some(interval_id));
151+
}
143152
vacant.insert(Box::new(callback));
144153
Ok(())
145154
} else {

0 commit comments

Comments
 (0)