1
1
//! Handle user specified rumble request events.
2
- use bevy_ecs:: {
3
- prelude:: { EventReader , Res } ,
4
- system:: NonSendMut ,
5
- } ;
2
+ use bevy_ecs:: prelude:: { EventReader , Res } ;
3
+ use bevy_ecs:: system:: { ResMut , Resource } ;
6
4
use bevy_input:: gamepad:: { GamepadRumbleIntensity , GamepadRumbleRequest } ;
7
5
use bevy_log:: { debug, warn} ;
8
6
use bevy_time:: Time ;
9
- use bevy_utils:: { Duration , HashMap } ;
7
+ use bevy_utils:: { synccell :: SyncCell , Duration , HashMap } ;
10
8
use gilrs:: {
11
9
ff:: { self , BaseEffect , BaseEffectType , Repeat , Replay } ,
12
- GamepadId , Gilrs ,
10
+ GamepadId ,
13
11
} ;
14
12
use thiserror:: Error ;
15
13
16
- use crate :: converter:: convert_gamepad_id;
14
+ use crate :: { converter:: convert_gamepad_id, Gilrs } ;
17
15
18
16
/// A rumble effect that is currently in effect.
19
17
struct RunningRumble {
20
- /// Duration from app startup when this effect will be finished
18
+ /// The time (since app startup) when this effect will be finished.
21
19
deadline : Duration ,
22
- /// A ref-counted handle to the specific force-feedback effect
20
+ /// A ref-counted handle to the specific force-feedback effect.
23
21
///
24
- /// Dropping it will cause the effect to stop
22
+ /// Dropping it will end the effect.
25
23
#[ allow( dead_code) ]
26
- effect : ff:: Effect ,
24
+ effect : SyncCell < ff:: Effect > ,
27
25
}
28
26
29
27
#[ derive( Error , Debug ) ]
@@ -35,7 +33,7 @@ enum RumbleError {
35
33
}
36
34
37
35
/// Contains the gilrs rumble effects that are currently running for each gamepad
38
- #[ derive( Default ) ]
36
+ #[ derive( Resource , Default ) ]
39
37
pub ( crate ) struct RunningRumbleEffects {
40
38
/// If multiple rumbles are running at the same time, their resulting rumble
41
39
/// will be the saturated sum of their strengths up until [`u16::MAX`]
@@ -79,8 +77,8 @@ fn get_base_effects(
79
77
}
80
78
81
79
fn handle_rumble_request (
80
+ gilrs : & mut gilrs:: Gilrs ,
82
81
running_rumbles : & mut RunningRumbleEffects ,
83
- gilrs : & mut Gilrs ,
84
82
rumble : GamepadRumbleRequest ,
85
83
current_time : Duration ,
86
84
) -> Result < ( ) , RumbleError > {
@@ -113,17 +111,20 @@ fn handle_rumble_request(
113
111
114
112
let gamepad_rumbles = running_rumbles. rumbles . entry ( gamepad_id) . or_default ( ) ;
115
113
let deadline = current_time + duration;
116
- gamepad_rumbles. push ( RunningRumble { deadline, effect } ) ;
114
+ gamepad_rumbles. push ( RunningRumble {
115
+ deadline,
116
+ effect : SyncCell :: new ( effect) ,
117
+ } ) ;
117
118
}
118
119
}
119
120
120
121
Ok ( ( ) )
121
122
}
122
123
pub ( crate ) fn play_gilrs_rumble (
123
124
time : Res < Time > ,
124
- mut gilrs : NonSendMut < Gilrs > ,
125
125
mut requests : EventReader < GamepadRumbleRequest > ,
126
- mut running_rumbles : NonSendMut < RunningRumbleEffects > ,
126
+ mut gilrs : ResMut < Gilrs > ,
127
+ mut running_rumbles : ResMut < RunningRumbleEffects > ,
127
128
) {
128
129
let current_time = time. raw_elapsed ( ) ;
129
130
// Remove outdated rumble effects.
@@ -138,7 +139,7 @@ pub(crate) fn play_gilrs_rumble(
138
139
// Add new effects.
139
140
for rumble in requests. read ( ) . cloned ( ) {
140
141
let gamepad = rumble. gamepad ( ) ;
141
- match handle_rumble_request ( & mut running_rumbles , & mut gilrs , rumble, current_time) {
142
+ match handle_rumble_request ( gilrs . get ( ) , & mut running_rumbles , rumble, current_time) {
142
143
Ok ( ( ) ) => { }
143
144
Err ( RumbleError :: GilrsError ( err) ) => {
144
145
if let ff:: Error :: FfNotSupported ( _) = err {
0 commit comments