Skip to content

Commit 5c54ea9

Browse files
committed
[arci-gamepad-gilrs] Update send command process
1 parent b9a119e commit 5c54ea9

File tree

1 file changed

+99
-1
lines changed

1 file changed

+99
-1
lines changed

arci-gamepad-gilrs/src/lib.rs

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,15 +278,113 @@ impl GilGamepad {
278278
pub fn new_from_config(config: GilGamepadConfig) -> Self {
279279
Self::new(config.device_id, config.map)
280280
}
281+
282+
/// This is another implementation for send command all the times
283+
pub fn new_to_send_constantly(id: usize, map: Map, time_step: f64, timeout: f64) -> Self {
284+
let (tx, rx) = flume::unbounded();
285+
let is_running = Arc::new(AtomicBool::new(true));
286+
let is_running_cloned = is_running.clone();
287+
std::thread::spawn(move || {
288+
let mut gil = gilrs::Gilrs::new().unwrap();
289+
#[cfg_attr(target_os = "macos", allow(unused_mut))]
290+
let mut selected_gamepad_id = None;
291+
// TODO: On macOS `gamepads()` does not works.
292+
#[cfg(not(target_os = "macos"))]
293+
{
294+
let mut is_found = false;
295+
for (connected_id, gamepad) in gil.gamepads() {
296+
info!("{} is {:?}", gamepad.name(), gamepad.power_info());
297+
if id == Into::<usize>::into(connected_id) {
298+
is_found = true;
299+
selected_gamepad_id = Some(connected_id);
300+
}
301+
}
302+
if !is_found {
303+
panic!("No Gamepad id={id} is found");
304+
}
305+
}
306+
let mut is_connected = true;
307+
tx.send(GamepadEvent::Connected).unwrap();
308+
let mut last_updated_time = std::time::Instant::now();
309+
let mut last_message = GamepadEvent::Disconnected;
310+
while is_running_cloned.load(Ordering::Relaxed) {
311+
if let Some(gamepad_id) = selected_gamepad_id {
312+
let gamepad = gil.gamepad(gamepad_id);
313+
if is_connected && !gamepad.is_connected() {
314+
error!("gamepad [{}] is disconnected", gamepad.name());
315+
is_connected = false;
316+
tx.send(GamepadEvent::Disconnected).unwrap();
317+
} else if !is_connected && gamepad.is_connected() {
318+
info!("gamepad [{}] is connected", gamepad.name());
319+
is_connected = true;
320+
tx.send(GamepadEvent::Connected).unwrap();
321+
}
322+
}
323+
324+
match gil.next_event() {
325+
Some(gilrs::Event {
326+
id: recv_id, event, ..
327+
}) => {
328+
if id == Into::<usize>::into(recv_id) {
329+
if let Some(e) = map.convert_event(event) {
330+
tx.send(e.clone()).unwrap();
331+
last_updated_time = std::time::Instant::now();
332+
last_message = e;
333+
}
334+
}
335+
}
336+
None => {
337+
if timeout.is_normal()
338+
&& timeout.is_sign_positive()
339+
&& last_updated_time.elapsed().as_secs_f64() < timeout
340+
{
341+
tx.send(last_message.clone()).unwrap()
342+
} else {
343+
// Timeout... Pass through...
344+
info!("Command timeout...")
345+
}
346+
}
347+
}
348+
349+
std::thread::sleep(Duration::from_secs_f64(time_step));
350+
}
351+
});
352+
353+
Self { rx, is_running }
354+
}
355+
356+
pub fn new_from_config_to_send_constantly(config: GilGamepadConfig) -> Self {
357+
Self::new_to_send_constantly(
358+
config.device_id,
359+
config.map,
360+
config.time_step,
361+
config.timeout,
362+
)
363+
}
281364
}
282365

283-
#[derive(Debug, Serialize, Deserialize, Clone, Default, JsonSchema)]
366+
#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)]
284367
#[serde(deny_unknown_fields)]
285368
pub struct GilGamepadConfig {
286369
#[serde(default)]
287370
device_id: usize,
288371
#[serde(default)]
289372
map: Map,
373+
#[serde(default)]
374+
time_step: f64,
375+
#[serde(default)]
376+
timeout: f64,
377+
}
378+
379+
impl Default for GilGamepadConfig {
380+
fn default() -> Self {
381+
Self {
382+
device_id: usize::default(),
383+
map: Map::default(),
384+
time_step: 0.01,
385+
timeout: 0.5,
386+
}
387+
}
290388
}
291389

292390
#[async_trait]

0 commit comments

Comments
 (0)