11use bevy_utils:: HashMap ;
22use std:: hash:: Hash ;
33
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.
48#[ derive( Debug ) ]
59pub struct Axis < T > {
610 axis_data : HashMap < T , f32 > ,
@@ -21,15 +25,82 @@ impl<T> Axis<T>
2125where
2226 T : Copy + Eq + Hash ,
2327{
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)
2651 }
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+ ] ;
2776
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+ }
3086 }
3187
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+ }
34105 }
35106}
0 commit comments