From 67eecd9bb2d9cb7d53b18c24d8e17a9da0fd2d09 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sat, 24 Feb 2024 06:17:44 -0800 Subject: [PATCH 1/8] Make Gilrs a normal resource on non-Wasm targets --- crates/bevy_gilrs/src/gilrs_system.rs | 22 ++++++++++++++++------ crates/bevy_gilrs/src/lib.rs | 13 ++++++++++--- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/crates/bevy_gilrs/src/gilrs_system.rs b/crates/bevy_gilrs/src/gilrs_system.rs index 7849bc1c80430..9a44b55276eaa 100644 --- a/crates/bevy_gilrs/src/gilrs_system.rs +++ b/crates/bevy_gilrs/src/gilrs_system.rs @@ -1,6 +1,13 @@ -use crate::converter::{convert_axis, convert_button, convert_gamepad_id}; +use crate::{ + converter::{convert_axis, convert_button, convert_gamepad_id}, + Gilrs, +}; use bevy_ecs::event::EventWriter; -use bevy_ecs::system::{NonSend, NonSendMut, Res, ResMut}; +#[cfg(target_arch = "wasm32")] +use bevy_ecs::system::NonSendMut; +use bevy_ecs::system::Res; +#[cfg(not(target_arch = "wasm32"))] +use bevy_ecs::system::ResMut; use bevy_input::gamepad::{ GamepadAxisChangedEvent, GamepadButtonChangedEvent, GamepadConnection, GamepadConnectionEvent, GamepadSettings, @@ -8,13 +15,14 @@ use bevy_input::gamepad::{ use bevy_input::gamepad::{GamepadEvent, GamepadInfo}; use bevy_input::prelude::{GamepadAxis, GamepadButton}; use bevy_input::Axis; -use gilrs::{ev::filter::axis_dpad_to_button, EventType, Filter, Gilrs}; +use gilrs::{ev::filter::axis_dpad_to_button, EventType, Filter}; pub fn gilrs_event_startup_system( - gilrs: NonSend, + #[cfg(target_arch = "wasm32")] mut gilrs: NonSendMut, + #[cfg(not(target_arch = "wasm32"))] mut gilrs: ResMut, mut connection_events: EventWriter, ) { - for (id, gamepad) in gilrs.gamepads() { + for (id, gamepad) in gilrs.0.get().gamepads() { let info = GamepadInfo { name: gamepad.name().into(), }; @@ -27,12 +35,14 @@ pub fn gilrs_event_startup_system( } pub fn gilrs_event_system( - mut gilrs: NonSendMut, + #[cfg(target_arch = "wasm32")] mut gilrs: NonSendMut, + #[cfg(not(target_arch = "wasm32"))] mut gilrs: ResMut, mut events: EventWriter, mut gamepad_buttons: ResMut>, gamepad_axis: Res>, gamepad_settings: Res, ) { + let mut gilrs = gilrs.0.get(); while let Some(gilrs_event) = gilrs .next_event() .filter_ev(&axis_dpad_to_button, &mut gilrs) diff --git a/crates/bevy_gilrs/src/lib.rs b/crates/bevy_gilrs/src/lib.rs index b48256b8db826..0197ca75b5bc7 100644 --- a/crates/bevy_gilrs/src/lib.rs +++ b/crates/bevy_gilrs/src/lib.rs @@ -10,11 +10,14 @@ mod rumble; use bevy_app::{App, Plugin, PostUpdate, PreStartup, PreUpdate}; use bevy_ecs::prelude::*; use bevy_input::InputSystem; -use bevy_utils::tracing::error; +use bevy_utils::{synccell::SyncCell, tracing::error}; use gilrs::GilrsBuilder; use gilrs_system::{gilrs_event_startup_system, gilrs_event_system}; use rumble::{play_gilrs_rumble, RunningRumbleEffects}; +#[cfg_attr(not(target_arch = "wasm32"), derive(Resource))] +pub(crate) struct Gilrs(pub SyncCell); + /// Plugin that provides gamepad handling to an [`App`]. #[derive(Default)] pub struct GilrsPlugin; @@ -31,8 +34,12 @@ impl Plugin for GilrsPlugin { .build() { Ok(gilrs) => { - app.insert_non_send_resource(gilrs) - .init_non_send_resource::() + #[cfg(target_arch = "wasm32")] + app.insert_non_send_resource(gilrs); + #[cfg(not(target_arch = "wasm32"))] + app.insert_resource(Gilrs(SyncCell::new(gilrs))); + + app.init_non_send_resource::() .add_systems(PreStartup, gilrs_event_startup_system) .add_systems(PreUpdate, gilrs_event_system.before(InputSystem)) .add_systems(PostUpdate, play_gilrs_rumble.in_set(RumbleSystem)); From b2bf360f1972f2b892626f0f5355c8a55f83a37e Mon Sep 17 00:00:00 2001 From: james7132 Date: Sat, 24 Feb 2024 06:27:09 -0800 Subject: [PATCH 2/8] Formatting and clippy --- crates/bevy_gilrs/src/gilrs_system.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/bevy_gilrs/src/gilrs_system.rs b/crates/bevy_gilrs/src/gilrs_system.rs index 9a44b55276eaa..5039f4006cf9f 100644 --- a/crates/bevy_gilrs/src/gilrs_system.rs +++ b/crates/bevy_gilrs/src/gilrs_system.rs @@ -42,11 +42,8 @@ pub fn gilrs_event_system( gamepad_axis: Res>, gamepad_settings: Res, ) { - let mut gilrs = gilrs.0.get(); - while let Some(gilrs_event) = gilrs - .next_event() - .filter_ev(&axis_dpad_to_button, &mut gilrs) - { + let gilrs = gilrs.0.get(); + while let Some(gilrs_event) = gilrs.next_event().filter_ev(&axis_dpad_to_button, gilrs) { gilrs.update(&gilrs_event); let gamepad = convert_gamepad_id(gilrs_event.id); From 8f703a016e449e26b965654c631c8aefe52dfef1 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sat, 24 Feb 2024 06:54:23 -0800 Subject: [PATCH 3/8] Add missed system --- crates/bevy_gilrs/src/rumble.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/crates/bevy_gilrs/src/rumble.rs b/crates/bevy_gilrs/src/rumble.rs index 2b1eb68aedbf2..ad5e27d4a2137 100644 --- a/crates/bevy_gilrs/src/rumble.rs +++ b/crates/bevy_gilrs/src/rumble.rs @@ -1,15 +1,17 @@ //! Handle user specified rumble request events. -use bevy_ecs::{ - prelude::{EventReader, Res}, - system::NonSendMut, -}; +use crate::Gilrs; +#[cfg(not(target_arch = "wasm32"))] +use bevy_ecs::prelude::ResMut; +use bevy_ecs::prelude::{EventReader, Res}; +#[cfg(target_arch = "wasm32")] +use bevy_ecs::system::NonSendMut; use bevy_input::gamepad::{GamepadRumbleIntensity, GamepadRumbleRequest}; use bevy_log::{debug, warn}; use bevy_time::{Real, Time}; use bevy_utils::{Duration, HashMap}; use gilrs::{ ff::{self, BaseEffect, BaseEffectType, Repeat, Replay}, - GamepadId, Gilrs, + GamepadId, }; use thiserror::Error; @@ -80,7 +82,7 @@ fn get_base_effects( fn handle_rumble_request( running_rumbles: &mut RunningRumbleEffects, - gilrs: &mut Gilrs, + gilrs: &mut gilrs::Gilrs, rumble: GamepadRumbleRequest, current_time: Duration, ) -> Result<(), RumbleError> { @@ -121,10 +123,12 @@ fn handle_rumble_request( } pub(crate) fn play_gilrs_rumble( time: Res>, - mut gilrs: NonSendMut, + #[cfg(target_arch = "wasm32")] mut gilrs: NonSendMut, + #[cfg(not(target_arch = "wasm32"))] mut gilrs: ResMut, mut requests: EventReader, mut running_rumbles: NonSendMut, ) { + let gilrs = gilrs.0.get(); let current_time = time.elapsed(); // Remove outdated rumble effects. for rumbles in running_rumbles.rumbles.values_mut() { @@ -138,7 +142,7 @@ pub(crate) fn play_gilrs_rumble( // Add new effects. for rumble in requests.read().cloned() { let gamepad = rumble.gamepad(); - match handle_rumble_request(&mut running_rumbles, &mut gilrs, rumble, current_time) { + match handle_rumble_request(&mut running_rumbles, gilrs, rumble, current_time) { Ok(()) => {} Err(RumbleError::GilrsError(err)) => { if let ff::Error::FfNotSupported(_) = err { From 8ca809e78311bcc390c8c26e0c23c3abcffe6623 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sat, 24 Feb 2024 13:12:30 -0800 Subject: [PATCH 4/8] Make RunningRumbleEffects a Send Resource too --- crates/bevy_gilrs/src/rumble.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/crates/bevy_gilrs/src/rumble.rs b/crates/bevy_gilrs/src/rumble.rs index ad5e27d4a2137..c982a52ce2fa5 100644 --- a/crates/bevy_gilrs/src/rumble.rs +++ b/crates/bevy_gilrs/src/rumble.rs @@ -1,14 +1,12 @@ //! Handle user specified rumble request events. use crate::Gilrs; -#[cfg(not(target_arch = "wasm32"))] -use bevy_ecs::prelude::ResMut; -use bevy_ecs::prelude::{EventReader, Res}; +use bevy_ecs::prelude::{EventReader, Res, ResMut, Resource}; #[cfg(target_arch = "wasm32")] use bevy_ecs::system::NonSendMut; use bevy_input::gamepad::{GamepadRumbleIntensity, GamepadRumbleRequest}; use bevy_log::{debug, warn}; use bevy_time::{Real, Time}; -use bevy_utils::{Duration, HashMap}; +use bevy_utils::{synccell::SyncCell, Duration, HashMap}; use gilrs::{ ff::{self, BaseEffect, BaseEffectType, Repeat, Replay}, GamepadId, @@ -25,7 +23,7 @@ struct RunningRumble { /// /// Dropping it will cause the effect to stop #[allow(dead_code)] - effect: ff::Effect, + effect: SyncCell, } #[derive(Error, Debug)] @@ -37,7 +35,7 @@ enum RumbleError { } /// Contains the gilrs rumble effects that are currently running for each gamepad -#[derive(Default)] +#[derive(Default, Resource)] pub(crate) struct RunningRumbleEffects { /// If multiple rumbles are running at the same time, their resulting rumble /// will be the saturated sum of their strengths up until [`u16::MAX`] @@ -115,7 +113,10 @@ fn handle_rumble_request( let gamepad_rumbles = running_rumbles.rumbles.entry(gamepad_id).or_default(); let deadline = current_time + duration; - gamepad_rumbles.push(RunningRumble { deadline, effect }); + gamepad_rumbles.push(RunningRumble { + deadline, + effect: SyncCell::new(effect), + }); } } @@ -126,7 +127,7 @@ pub(crate) fn play_gilrs_rumble( #[cfg(target_arch = "wasm32")] mut gilrs: NonSendMut, #[cfg(not(target_arch = "wasm32"))] mut gilrs: ResMut, mut requests: EventReader, - mut running_rumbles: NonSendMut, + mut running_rumbles: ResMut, ) { let gilrs = gilrs.0.get(); let current_time = time.elapsed(); From 5d37781722befa6b1d7ba1840130ebba1c78e35e Mon Sep 17 00:00:00 2001 From: james7132 Date: Sat, 24 Feb 2024 14:17:19 -0800 Subject: [PATCH 5/8] Properly initialize the rumble effects --- crates/bevy_gilrs/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_gilrs/src/lib.rs b/crates/bevy_gilrs/src/lib.rs index 0197ca75b5bc7..69a5b9a6e1576 100644 --- a/crates/bevy_gilrs/src/lib.rs +++ b/crates/bevy_gilrs/src/lib.rs @@ -39,7 +39,7 @@ impl Plugin for GilrsPlugin { #[cfg(not(target_arch = "wasm32"))] app.insert_resource(Gilrs(SyncCell::new(gilrs))); - app.init_non_send_resource::() + app.init_resource::() .add_systems(PreStartup, gilrs_event_startup_system) .add_systems(PreUpdate, gilrs_event_system.before(InputSystem)) .add_systems(PostUpdate, play_gilrs_rumble.in_set(RumbleSystem)); From 71522fbc4430aea1aac064bdeb5533312e29c6c1 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sun, 25 Feb 2024 14:35:46 -0800 Subject: [PATCH 6/8] Fix Wasm --- crates/bevy_gilrs/src/gilrs_system.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/bevy_gilrs/src/gilrs_system.rs b/crates/bevy_gilrs/src/gilrs_system.rs index 5039f4006cf9f..e0e111cb4d027 100644 --- a/crates/bevy_gilrs/src/gilrs_system.rs +++ b/crates/bevy_gilrs/src/gilrs_system.rs @@ -5,9 +5,7 @@ use crate::{ use bevy_ecs::event::EventWriter; #[cfg(target_arch = "wasm32")] use bevy_ecs::system::NonSendMut; -use bevy_ecs::system::Res; -#[cfg(not(target_arch = "wasm32"))] -use bevy_ecs::system::ResMut; +use bevy_ecs::system::{Res, ResMut}; use bevy_input::gamepad::{ GamepadAxisChangedEvent, GamepadButtonChangedEvent, GamepadConnection, GamepadConnectionEvent, GamepadSettings, From 110d0c507c82e9afdb4674662aee3fb01e6f4555 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sun, 25 Feb 2024 15:18:20 -0800 Subject: [PATCH 7/8] Don't inject the raw gilrs value on WASM --- crates/bevy_gilrs/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_gilrs/src/lib.rs b/crates/bevy_gilrs/src/lib.rs index 69a5b9a6e1576..b58e346a59144 100644 --- a/crates/bevy_gilrs/src/lib.rs +++ b/crates/bevy_gilrs/src/lib.rs @@ -35,7 +35,7 @@ impl Plugin for GilrsPlugin { { Ok(gilrs) => { #[cfg(target_arch = "wasm32")] - app.insert_non_send_resource(gilrs); + app.insert_resource(Gilrs(SyncCell::new(gilrs))); #[cfg(not(target_arch = "wasm32"))] app.insert_resource(Gilrs(SyncCell::new(gilrs))); From 34423b7e56a8ec3df1b71c94d32264fd52b0f903 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sun, 25 Feb 2024 16:11:37 -0800 Subject: [PATCH 8/8] Fix wasm (again) --- crates/bevy_gilrs/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_gilrs/src/lib.rs b/crates/bevy_gilrs/src/lib.rs index b58e346a59144..dad8efe744a05 100644 --- a/crates/bevy_gilrs/src/lib.rs +++ b/crates/bevy_gilrs/src/lib.rs @@ -35,7 +35,7 @@ impl Plugin for GilrsPlugin { { Ok(gilrs) => { #[cfg(target_arch = "wasm32")] - app.insert_resource(Gilrs(SyncCell::new(gilrs))); + app.insert_non_send_resource(Gilrs(SyncCell::new(gilrs))); #[cfg(not(target_arch = "wasm32"))] app.insert_resource(Gilrs(SyncCell::new(gilrs)));