1
1
use bevy_utils:: HashSet ;
2
2
use std:: hash:: Hash ;
3
3
4
- /// A "press-able" input of type `T`
4
+ // unused import, but needed for intra doc link to work
5
+ #[ allow( unused_imports) ]
6
+ use bevy_ecs:: schedule:: State ;
7
+
8
+ /// A "press-able" input of type `T`.
9
+ ///
10
+ /// This type can be used as a resource to keep the current state of an input, by reacting to
11
+ /// events from the input. For a given input value:
12
+ ///
13
+ /// * [`Input::pressed`] will return `true` between a press and a release event.
14
+ /// * [`Input::just_pressed`] will return `true` for one frame after a press event.
15
+ /// * [`Input::just_released`] will return `true` for one frame after a release event.
16
+ ///
17
+ /// In case multiple systems are checking for [`Input::just_pressed`] or [`Input::just_released`]
18
+ /// but only one should react, for example in the case of triggering
19
+ /// [`State`] change, you should consider clearing the input state, either by:
20
+ ///
21
+ /// * Using [`Input::just_pressed_and_clear`] or [`Input::just_released_and_clear`] instead.
22
+ /// * Calling [`Input::clear`] or [`Input::reset`] immediately after the state change.
23
+ ///
24
+ /// ## Notes when adding this resource for a new input type
25
+ ///
26
+ /// When adding this resource for a new input type, you should:
27
+ ///
28
+ /// * Call the [`Input::press`] method for each press event.
29
+ /// * Call the [`Input::release`] method for each release event.
30
+ /// * Call the [`Input::clear`] method at each frame start, before processing events.
5
31
#[ derive( Debug ) ]
6
32
pub struct Input < T > {
7
33
pressed : HashSet < T > ,
@@ -23,6 +49,7 @@ impl<T> Input<T>
23
49
where
24
50
T : Copy + Eq + Hash ,
25
51
{
52
+ /// Register a press for input `input`.
26
53
pub fn press ( & mut self , input : T ) {
27
54
if !self . pressed ( input) {
28
55
self . just_pressed . insert ( input) ;
@@ -31,42 +58,65 @@ where
31
58
self . pressed . insert ( input) ;
32
59
}
33
60
61
+ /// Check if `input` has been pressed.
34
62
pub fn pressed ( & self , input : T ) -> bool {
35
63
self . pressed . contains ( & input)
36
64
}
37
65
66
+ /// Register a release for input `input`.
38
67
pub fn release ( & mut self , input : T ) {
39
68
self . pressed . remove ( & input) ;
40
69
self . just_released . insert ( input) ;
41
70
}
42
71
72
+ /// Check if `input` has been just pressed.
43
73
pub fn just_pressed ( & self , input : T ) -> bool {
44
74
self . just_pressed . contains ( & input)
45
75
}
46
76
77
+ /// Clear the "just pressed" state of `input`. Future calls to [`Input::just_pressed`] for the given
78
+ /// input will return false until a new press event occurs.
79
+ /// Returns true if `input` is currently "just pressed"
80
+ pub fn clear_just_pressed ( & mut self , input : T ) -> bool {
81
+ self . just_pressed . remove ( & input)
82
+ }
83
+
84
+ /// Check if `input` has been just released.
47
85
pub fn just_released ( & self , input : T ) -> bool {
48
86
self . just_released . contains ( & input)
49
87
}
50
88
89
+ /// Clear the "just released" state of `input`. Future calls to [`Input::just_released`] for the given
90
+ /// input will return false until a new release event occurs.
91
+ /// Returns true if `input` is currently "just released"
92
+ pub fn clear_just_released ( & mut self , input : T ) -> bool {
93
+ self . just_released . remove ( & input)
94
+ }
95
+
96
+ /// Reset all status for input `input`.
51
97
pub fn reset ( & mut self , input : T ) {
52
98
self . pressed . remove ( & input) ;
53
99
self . just_pressed . remove ( & input) ;
54
100
self . just_released . remove ( & input) ;
55
101
}
56
102
57
- pub fn update ( & mut self ) {
103
+ /// Clear just pressed and just released information.
104
+ pub fn clear ( & mut self ) {
58
105
self . just_pressed . clear ( ) ;
59
106
self . just_released . clear ( ) ;
60
107
}
61
108
109
+ /// List all inputs that are pressed.
62
110
pub fn get_pressed ( & self ) -> impl ExactSizeIterator < Item = & T > {
63
111
self . pressed . iter ( )
64
112
}
65
113
114
+ /// List all inputs that are just pressed.
66
115
pub fn get_just_pressed ( & self ) -> impl ExactSizeIterator < Item = & T > {
67
116
self . just_pressed . iter ( )
68
117
}
69
118
119
+ /// List all inputs that are just released.
70
120
pub fn get_just_released ( & self ) -> impl ExactSizeIterator < Item = & T > {
71
121
self . just_released . iter ( )
72
122
}
@@ -100,8 +150,8 @@ mod test {
100
150
assert ! ( input. pressed( DummyInput :: Input1 ) ) ;
101
151
assert ! ( input. pressed( DummyInput :: Input2 ) ) ;
102
152
103
- // Update the `Input` and check press state
104
- input. update ( ) ;
153
+ // Clear the `input`, removing just pressed and just released
154
+ input. clear ( ) ;
105
155
106
156
// Check if they're marked "just pressed"
107
157
assert ! ( !input. just_pressed( DummyInput :: Input1 ) ) ;
@@ -124,9 +174,8 @@ mod test {
124
174
assert ! ( !input. pressed( DummyInput :: Input1 ) ) ;
125
175
assert ! ( !input. pressed( DummyInput :: Input2 ) ) ;
126
176
127
- // Update the `Input` and check for removal from `just_released`
128
-
129
- input. update ( ) ;
177
+ // Clear the `Input` and check for removal from `just_released`
178
+ input. clear ( ) ;
130
179
131
180
// Check that they're not incorrectly marked as just released
132
181
assert ! ( !input. just_released( DummyInput :: Input1 ) ) ;
0 commit comments