bevy_input/
button_input.rs1use bevy_ecs::system::Resource;
4use bevy_utils::HashSet;
5use core::hash::Hash;
6#[cfg(feature = "bevy_reflect")]
7use {
8 bevy_ecs::reflect::ReflectResource,
9 bevy_reflect::{std_traits::ReflectDefault, Reflect},
10};
11
12#[derive(Debug, Clone, Resource)]
124#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Default, Resource))]
125pub struct ButtonInput<T: Copy + Eq + Hash + Send + Sync + 'static> {
126 pressed: HashSet<T>,
128 just_pressed: HashSet<T>,
130 just_released: HashSet<T>,
132}
133
134impl<T: Copy + Eq + Hash + Send + Sync + 'static> Default for ButtonInput<T> {
135 fn default() -> Self {
136 Self {
137 pressed: Default::default(),
138 just_pressed: Default::default(),
139 just_released: Default::default(),
140 }
141 }
142}
143
144impl<T> ButtonInput<T>
145where
146 T: Copy + Eq + Hash + Send + Sync + 'static,
147{
148 pub fn press(&mut self, input: T) {
150 if self.pressed.insert(input) {
152 self.just_pressed.insert(input);
153 }
154 }
155
156 pub fn pressed(&self, input: T) -> bool {
158 self.pressed.contains(&input)
159 }
160
161 pub fn any_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool {
163 inputs.into_iter().any(|it| self.pressed(it))
164 }
165
166 pub fn all_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool {
168 inputs.into_iter().all(|it| self.pressed(it))
169 }
170
171 pub fn release(&mut self, input: T) {
173 if self.pressed.remove(&input) {
175 self.just_released.insert(input);
176 }
177 }
178
179 pub fn release_all(&mut self) {
181 self.just_released.extend(self.pressed.drain());
183 }
184
185 pub fn just_pressed(&self, input: T) -> bool {
189 self.just_pressed.contains(&input)
190 }
191
192 pub fn any_just_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool {
194 inputs.into_iter().any(|it| self.just_pressed(it))
195 }
196
197 pub fn clear_just_pressed(&mut self, input: T) -> bool {
201 self.just_pressed.remove(&input)
202 }
203
204 pub fn just_released(&self, input: T) -> bool {
208 self.just_released.contains(&input)
209 }
210
211 pub fn any_just_released(&self, inputs: impl IntoIterator<Item = T>) -> bool {
213 inputs.into_iter().any(|input| self.just_released(input))
214 }
215
216 pub fn all_just_released(&self, inputs: impl IntoIterator<Item = T>) -> bool {
218 inputs.into_iter().all(|input| self.just_released(input))
219 }
220
221 pub fn all_just_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool {
223 inputs.into_iter().all(|input| self.just_pressed(input))
224 }
225
226 pub fn clear_just_released(&mut self, input: T) -> bool {
230 self.just_released.remove(&input)
231 }
232
233 pub fn reset(&mut self, input: T) {
235 self.pressed.remove(&input);
236 self.just_pressed.remove(&input);
237 self.just_released.remove(&input);
238 }
239
240 pub fn reset_all(&mut self) {
244 self.pressed.clear();
245 self.just_pressed.clear();
246 self.just_released.clear();
247 }
248
249 pub fn clear(&mut self) {
253 self.just_pressed.clear();
254 self.just_released.clear();
255 }
256
257 pub fn get_pressed(&self) -> impl ExactSizeIterator<Item = &T> {
259 self.pressed.iter()
260 }
261
262 pub fn get_just_pressed(&self) -> impl ExactSizeIterator<Item = &T> {
266 self.just_pressed.iter()
267 }
268
269 pub fn get_just_released(&self) -> impl ExactSizeIterator<Item = &T> {
273 self.just_released.iter()
274 }
275}
276
277#[cfg(test)]
278mod test {
279 use crate::ButtonInput;
280
281 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
283 enum DummyInput {
284 Input1,
285 Input2,
286 }
287
288 #[test]
289 fn test_press() {
290 let mut input = ButtonInput::default();
291 assert!(!input.pressed.contains(&DummyInput::Input1));
292 assert!(!input.just_pressed.contains(&DummyInput::Input1));
293 input.press(DummyInput::Input1);
294 assert!(input.just_pressed.contains(&DummyInput::Input1));
295 assert!(input.pressed.contains(&DummyInput::Input1));
296 }
297
298 #[test]
299 fn test_pressed() {
300 let mut input = ButtonInput::default();
301 assert!(!input.pressed(DummyInput::Input1));
302 input.press(DummyInput::Input1);
303 assert!(input.pressed(DummyInput::Input1));
304 }
305
306 #[test]
307 fn test_any_pressed() {
308 let mut input = ButtonInput::default();
309 assert!(!input.any_pressed([DummyInput::Input1]));
310 assert!(!input.any_pressed([DummyInput::Input2]));
311 assert!(!input.any_pressed([DummyInput::Input1, DummyInput::Input2]));
312 input.press(DummyInput::Input1);
313 assert!(input.any_pressed([DummyInput::Input1]));
314 assert!(!input.any_pressed([DummyInput::Input2]));
315 assert!(input.any_pressed([DummyInput::Input1, DummyInput::Input2]));
316 }
317
318 #[test]
319 fn test_all_pressed() {
320 let mut input = ButtonInput::default();
321 assert!(!input.all_pressed([DummyInput::Input1]));
322 assert!(!input.all_pressed([DummyInput::Input2]));
323 assert!(!input.all_pressed([DummyInput::Input1, DummyInput::Input2]));
324 input.press(DummyInput::Input1);
325 assert!(input.all_pressed([DummyInput::Input1]));
326 assert!(!input.all_pressed([DummyInput::Input1, DummyInput::Input2]));
327 input.press(DummyInput::Input2);
328 assert!(input.all_pressed([DummyInput::Input1, DummyInput::Input2]));
329 }
330
331 #[test]
332 fn test_release() {
333 let mut input = ButtonInput::default();
334 input.press(DummyInput::Input1);
335 assert!(input.pressed.contains(&DummyInput::Input1));
336 assert!(!input.just_released.contains(&DummyInput::Input1));
337 input.release(DummyInput::Input1);
338 assert!(!input.pressed.contains(&DummyInput::Input1));
339 assert!(input.just_released.contains(&DummyInput::Input1));
340 }
341
342 #[test]
343 fn test_release_all() {
344 let mut input = ButtonInput::default();
345 input.press(DummyInput::Input1);
346 input.press(DummyInput::Input2);
347 input.release_all();
348 assert!(input.pressed.is_empty());
349 assert!(input.just_released.contains(&DummyInput::Input1));
350 assert!(input.just_released.contains(&DummyInput::Input2));
351 }
352
353 #[test]
354 fn test_just_pressed() {
355 let mut input = ButtonInput::default();
356 assert!(!input.just_pressed(DummyInput::Input1));
357 input.press(DummyInput::Input1);
358 assert!(input.just_pressed(DummyInput::Input1));
359 }
360
361 #[test]
362 fn test_any_just_pressed() {
363 let mut input = ButtonInput::default();
364 assert!(!input.any_just_pressed([DummyInput::Input1]));
365 assert!(!input.any_just_pressed([DummyInput::Input2]));
366 assert!(!input.any_just_pressed([DummyInput::Input1, DummyInput::Input2]));
367 input.press(DummyInput::Input1);
368 assert!(input.any_just_pressed([DummyInput::Input1]));
369 assert!(!input.any_just_pressed([DummyInput::Input2]));
370 assert!(input.any_just_pressed([DummyInput::Input1, DummyInput::Input2]));
371 }
372
373 #[test]
374 fn test_clear_just_pressed() {
375 let mut input = ButtonInput::default();
376 input.press(DummyInput::Input1);
377 assert!(input.just_pressed(DummyInput::Input1));
378 input.clear_just_pressed(DummyInput::Input1);
379 assert!(!input.just_pressed(DummyInput::Input1));
380 }
381
382 #[test]
383 fn test_just_released() {
384 let mut input = ButtonInput::default();
385 input.press(DummyInput::Input1);
386 assert!(!input.just_released(DummyInput::Input1));
387 input.release(DummyInput::Input1);
388 assert!(input.just_released(DummyInput::Input1));
389 }
390
391 #[test]
392 fn test_any_just_released() {
393 let mut input = ButtonInput::default();
394 input.press(DummyInput::Input1);
395 assert!(!input.any_just_released([DummyInput::Input1]));
396 assert!(!input.any_just_released([DummyInput::Input2]));
397 assert!(!input.any_just_released([DummyInput::Input1, DummyInput::Input2]));
398 input.release(DummyInput::Input1);
399 assert!(input.any_just_released([DummyInput::Input1]));
400 assert!(!input.any_just_released([DummyInput::Input2]));
401 assert!(input.any_just_released([DummyInput::Input1, DummyInput::Input2]));
402 }
403
404 #[test]
405 fn test_clear_just_released() {
406 let mut input = ButtonInput::default();
407 input.press(DummyInput::Input1);
408 input.release(DummyInput::Input1);
409 assert!(input.just_released(DummyInput::Input1));
410 input.clear_just_released(DummyInput::Input1);
411 assert!(!input.just_released(DummyInput::Input1));
412 }
413
414 #[test]
415 fn test_reset() {
416 let mut input = ButtonInput::default();
417
418 input.press(DummyInput::Input1);
420 assert!(input.pressed(DummyInput::Input1));
421 assert!(input.just_pressed(DummyInput::Input1));
422 assert!(!input.just_released(DummyInput::Input1));
423 input.reset(DummyInput::Input1);
424 assert!(!input.pressed(DummyInput::Input1));
425 assert!(!input.just_pressed(DummyInput::Input1));
426 assert!(!input.just_released(DummyInput::Input1));
427
428 input.press(DummyInput::Input1);
430 input.release(DummyInput::Input1);
431 assert!(!input.pressed(DummyInput::Input1));
432 assert!(input.just_pressed(DummyInput::Input1));
433 assert!(input.just_released(DummyInput::Input1));
434 input.reset(DummyInput::Input1);
435 assert!(!input.pressed(DummyInput::Input1));
436 assert!(!input.just_pressed(DummyInput::Input1));
437 assert!(!input.just_released(DummyInput::Input1));
438 }
439
440 #[test]
441 fn test_reset_all() {
442 let mut input = ButtonInput::default();
443
444 input.press(DummyInput::Input1);
445 input.press(DummyInput::Input2);
446 input.release(DummyInput::Input2);
447 assert!(input.pressed.contains(&DummyInput::Input1));
448 assert!(input.just_pressed.contains(&DummyInput::Input1));
449 assert!(input.just_released.contains(&DummyInput::Input2));
450 input.reset_all();
451 assert!(input.pressed.is_empty());
452 assert!(input.just_pressed.is_empty());
453 assert!(input.just_released.is_empty());
454 }
455
456 #[test]
457 fn test_clear() {
458 let mut input = ButtonInput::default();
459
460 input.press(DummyInput::Input1);
462 assert!(input.pressed(DummyInput::Input1));
463 assert!(input.just_pressed(DummyInput::Input1));
464 assert!(!input.just_released(DummyInput::Input1));
465 input.clear();
466 assert!(input.pressed(DummyInput::Input1));
467 assert!(!input.just_pressed(DummyInput::Input1));
468 assert!(!input.just_released(DummyInput::Input1));
469
470 input.press(DummyInput::Input1);
472 input.release(DummyInput::Input1);
473 assert!(!input.pressed(DummyInput::Input1));
474 assert!(!input.just_pressed(DummyInput::Input1));
475 assert!(input.just_released(DummyInput::Input1));
476 input.clear();
477 assert!(!input.pressed(DummyInput::Input1));
478 assert!(!input.just_pressed(DummyInput::Input1));
479 assert!(!input.just_released(DummyInput::Input1));
480 }
481
482 #[test]
483 fn test_get_pressed() {
484 let mut input = ButtonInput::default();
485 input.press(DummyInput::Input1);
486 input.press(DummyInput::Input2);
487 let pressed = input.get_pressed();
488 assert_eq!(pressed.len(), 2);
489 for pressed_input in pressed {
490 assert!(input.pressed.contains(pressed_input));
491 }
492 }
493
494 #[test]
495 fn test_get_just_pressed() {
496 let mut input = ButtonInput::default();
497 input.press(DummyInput::Input1);
498 input.press(DummyInput::Input2);
499 let just_pressed = input.get_just_pressed();
500 assert_eq!(just_pressed.len(), 2);
501 for just_pressed_input in just_pressed {
502 assert!(input.just_pressed.contains(just_pressed_input));
503 }
504 }
505
506 #[test]
507 fn test_get_just_released() {
508 let mut input = ButtonInput::default();
509 input.press(DummyInput::Input1);
510 input.press(DummyInput::Input2);
511 input.release(DummyInput::Input1);
512 input.release(DummyInput::Input2);
513 let just_released = input.get_just_released();
514 assert_eq!(just_released.len(), 2);
515 for just_released_input in just_released {
516 assert!(input.just_released.contains(just_released_input));
517 }
518 }
519
520 #[test]
521 fn test_general_input_handling() {
522 let mut input = ButtonInput::default();
523
524 input.press(DummyInput::Input1);
526 input.press(DummyInput::Input2);
527
528 assert!(input.just_pressed(DummyInput::Input1));
530 assert!(input.just_pressed(DummyInput::Input2));
531
532 assert!(input.pressed(DummyInput::Input1));
534 assert!(input.pressed(DummyInput::Input2));
535
536 input.clear();
538
539 assert!(!input.just_pressed(DummyInput::Input1));
541 assert!(!input.just_pressed(DummyInput::Input2));
542
543 assert!(input.pressed(DummyInput::Input1));
545 assert!(input.pressed(DummyInput::Input2));
546
547 input.release(DummyInput::Input1);
549 input.release(DummyInput::Input2);
550
551 assert!(input.just_released(DummyInput::Input1));
553 assert!(input.just_released(DummyInput::Input2));
554
555 assert!(!input.pressed(DummyInput::Input1));
557 assert!(!input.pressed(DummyInput::Input2));
558
559 input.clear();
561
562 assert!(!input.just_released(DummyInput::Input1));
564 assert!(!input.just_released(DummyInput::Input2));
565
566 let mut input = ButtonInput::default();
568
569 input.press(DummyInput::Input1);
570 input.release(DummyInput::Input2);
571
572 input.reset(DummyInput::Input1);
574 input.reset(DummyInput::Input2);
575
576 assert!(!input.just_pressed(DummyInput::Input1));
577 assert!(!input.pressed(DummyInput::Input1));
578 assert!(!input.just_released(DummyInput::Input2));
579 }
580}