1
1
use bevy_utils:: HashMap ;
2
2
use std:: hash:: Hash ;
3
3
4
+ /// Stores the position data of input devices of type T
5
+ ///
6
+ /// Values are stored as `f32` values, which range from `min` to `max`.
7
+ /// The valid range is from -1.0 to 1.0, inclusive.
4
8
#[ derive( Debug ) ]
5
9
pub struct Axis < T > {
6
10
axis_data : HashMap < T , f32 > ,
@@ -21,15 +25,82 @@ impl<T> Axis<T>
21
25
where
22
26
T : Copy + Eq + Hash ,
23
27
{
24
- pub fn set ( & mut self , axis : T , value : f32 ) -> Option < f32 > {
25
- self . axis_data . insert ( axis, value)
28
+ pub const MIN : f32 = -1.0 ;
29
+ pub const MAX : f32 = 1.0 ;
30
+
31
+ /// Inserts a position data for an input device,
32
+ /// restricting the position data to an interval `min..=max`.
33
+ ///
34
+ /// If the input device wasn't present before, [None] is returned.
35
+ ///
36
+ /// If the input device was present, the position data is updated, and the old value is returned.
37
+ pub fn set ( & mut self , input_device : T , position_data : f32 ) -> Option < f32 > {
38
+ let new_position_data = position_data. clamp ( Self :: MIN , Self :: MAX ) ;
39
+ self . axis_data . insert ( input_device, new_position_data)
40
+ }
41
+
42
+ /// Returns a position data corresponding to the input device.
43
+ pub fn get ( & self , input_device : T ) -> Option < f32 > {
44
+ self . axis_data . get ( & input_device) . copied ( )
45
+ }
46
+
47
+ /// Removes the position data of the input device,
48
+ /// returning the position data if the input device was previously set.
49
+ pub fn remove ( & mut self , input_device : T ) -> Option < f32 > {
50
+ self . axis_data . remove ( & input_device)
26
51
}
52
+ }
53
+
54
+ #[ cfg( test) ]
55
+ mod tests {
56
+ use crate :: {
57
+ gamepad:: { Gamepad , GamepadButton , GamepadButtonType } ,
58
+ Axis ,
59
+ } ;
60
+
61
+ #[ test]
62
+ fn test_axis_set ( ) {
63
+ let cases = [
64
+ ( -1.5 , Some ( -1.0 ) ) ,
65
+ ( -1.1 , Some ( -1.0 ) ) ,
66
+ ( -1.0 , Some ( -1.0 ) ) ,
67
+ ( -0.9 , Some ( -0.9 ) ) ,
68
+ ( -0.1 , Some ( -0.1 ) ) ,
69
+ ( 0.0 , Some ( 0.0 ) ) ,
70
+ ( 0.1 , Some ( 0.1 ) ) ,
71
+ ( 0.9 , Some ( 0.9 ) ) ,
72
+ ( 1.0 , Some ( 1.0 ) ) ,
73
+ ( 1.1 , Some ( 1.0 ) ) ,
74
+ ( 1.6 , Some ( 1.0 ) ) ,
75
+ ] ;
27
76
28
- pub fn get ( & self , axis : T ) -> Option < f32 > {
29
- self . axis_data . get ( & axis) . copied ( )
77
+ for ( value, expected) in cases {
78
+ let gamepad_button = GamepadButton ( Gamepad ( 1 ) , GamepadButtonType :: RightTrigger ) ;
79
+ let mut axis = Axis :: < GamepadButton > :: default ( ) ;
80
+
81
+ axis. set ( gamepad_button, value) ;
82
+
83
+ let actual = axis. get ( gamepad_button) ;
84
+ assert_eq ! ( expected, actual) ;
85
+ }
30
86
}
31
87
32
- pub fn remove ( & mut self , axis : T ) -> Option < f32 > {
33
- self . axis_data . remove ( & axis)
88
+ #[ test]
89
+ fn test_axis_remove ( ) {
90
+ let cases = [ -1.0 , -0.9 , -0.1 , 0.0 , 0.1 , 0.9 , 1.0 ] ;
91
+
92
+ for value in cases {
93
+ let gamepad_button = GamepadButton ( Gamepad ( 1 ) , GamepadButtonType :: RightTrigger ) ;
94
+ let mut axis = Axis :: < GamepadButton > :: default ( ) ;
95
+
96
+ axis. set ( gamepad_button, value) ;
97
+ assert ! ( axis. get( gamepad_button) . is_some( ) ) ;
98
+
99
+ axis. remove ( gamepad_button) ;
100
+ let actual = axis. get ( gamepad_button) ;
101
+ let expected = None ;
102
+
103
+ assert_eq ! ( expected, actual) ;
104
+ }
34
105
}
35
106
}
0 commit comments