use crate::{ converter::{convert_axis, convert_button}, Gilrs, GilrsGamepads, }; use bevy_ecs::event::EventWriter; use bevy_ecs::prelude::Commands; #[cfg(target_arch = "wasm32")] use bevy_ecs::system::NonSendMut; use bevy_ecs::system::ResMut; use bevy_input::gamepad::{ GamepadConnection, GamepadConnectionEvent, RawGamepadAxisChangedEvent, RawGamepadButtonChangedEvent, RawGamepadEvent, }; use gilrs::{ev::filter::axis_dpad_to_button, EventType, Filter}; pub fn gilrs_event_startup_system( mut commands: Commands, #[cfg(target_arch = "wasm32")] mut gilrs: NonSendMut, #[cfg(not(target_arch = "wasm32"))] mut gilrs: ResMut, mut gamepads: ResMut, mut events: EventWriter, ) { for (id, gamepad) in gilrs.0.get().gamepads() { // Create entity and add to mapping let entity = commands.spawn_empty().id(); gamepads.id_to_entity.insert(id, entity); gamepads.entity_to_id.insert(entity, id); events.send(GamepadConnectionEvent { gamepad: entity, connection: GamepadConnection::Connected { name: gamepad.name().to_string(), vendor_id: gamepad.vendor_id(), product_id: gamepad.product_id(), }, }); } } pub fn gilrs_event_system( mut commands: Commands, #[cfg(target_arch = "wasm32")] mut gilrs: NonSendMut, #[cfg(not(target_arch = "wasm32"))] mut gilrs: ResMut, mut gamepads: ResMut, mut events: EventWriter, mut connection_events: EventWriter, mut button_events: EventWriter, mut axis_event: EventWriter, ) { let gilrs = gilrs.0.get(); while let Some(gilrs_event) = gilrs.next_event().filter_ev(&axis_dpad_to_button, gilrs) { gilrs.update(&gilrs_event); match gilrs_event.event { EventType::Connected => { let pad = gilrs.gamepad(gilrs_event.id); let entity = gamepads.get_entity(gilrs_event.id).unwrap_or_else(|| { let entity = commands.spawn_empty().id(); gamepads.id_to_entity.insert(gilrs_event.id, entity); gamepads.entity_to_id.insert(entity, gilrs_event.id); entity }); let event = GamepadConnectionEvent::new( entity, GamepadConnection::Connected { name: pad.name().to_string(), vendor_id: pad.vendor_id(), product_id: pad.product_id(), }, ); events.send(event.clone().into()); connection_events.send(event); } EventType::Disconnected => { let gamepad = gamepads .id_to_entity .get(&gilrs_event.id) .copied() .expect("mapping should exist from connection"); let event = GamepadConnectionEvent::new(gamepad, GamepadConnection::Disconnected); events.send(event.clone().into()); connection_events.send(event); } EventType::ButtonChanged(gilrs_button, raw_value, _) => { let Some(button) = convert_button(gilrs_button) else { continue; }; let gamepad = gamepads .id_to_entity .get(&gilrs_event.id) .copied() .expect("mapping should exist from connection"); events.send(RawGamepadButtonChangedEvent::new(gamepad, button, raw_value).into()); button_events.send(RawGamepadButtonChangedEvent::new( gamepad, button, raw_value, )); } EventType::AxisChanged(gilrs_axis, raw_value, _) => { let Some(axis) = convert_axis(gilrs_axis) else { continue; }; let gamepad = gamepads .id_to_entity .get(&gilrs_event.id) .copied() .expect("mapping should exist from connection"); events.send(RawGamepadAxisChangedEvent::new(gamepad, axis, raw_value).into()); axis_event.send(RawGamepadAxisChangedEvent::new(gamepad, axis, raw_value)); } _ => (), }; } gilrs.inc(); }