magma_input/
button_map.rs1use std::{collections::HashSet, hash::Hash};
2
3#[derive(Clone, PartialEq, Eq, Debug)]
5pub struct ButtonMap<T: Copy + Eq + Hash> {
6 pressed: HashSet<T>,
7 just_pressed: HashSet<T>,
8 just_released: HashSet<T>,
9}
10
11impl<T: Copy + Eq + Hash> Default for ButtonMap<T> {
12 fn default() -> Self {
13 Self {
14 pressed: HashSet::new(),
15 just_pressed: HashSet::new(),
16 just_released: HashSet::new(),
17 }
18 }
19}
20
21impl<T: Copy + Eq + Hash> ButtonMap<T> {
22 pub fn press(&mut self, input: T) {
24 if self.pressed.insert(input) {
25 self.just_pressed.insert(input);
26 }
27 }
28
29 pub fn release(&mut self, input: T) {
31 if self.pressed.remove(&input) {
32 self.just_released.insert(input);
33 }
34 }
35
36 pub fn release_all(&mut self) {
38 self.just_released.extend(self.pressed.drain());
39 }
40
41 pub fn reset(&mut self) {
43 self.pressed.clear();
44 self.just_pressed.clear();
45 self.just_released.clear();
46 }
47
48 pub fn clear(&mut self) {
50 self.just_pressed.clear();
51 self.just_released.clear();
52 }
53
54 pub fn pressed(&self, input: T) -> bool {
56 self.pressed.contains(&input)
57 }
58
59 pub fn any_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool {
61 inputs.into_iter().any(|t| self.pressed(t))
62 }
63
64 pub fn all_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool {
66 inputs.into_iter().all(|t| self.pressed(t))
67 }
68
69 pub fn just_pressed(&self, input: T) -> bool {
71 self.just_pressed.contains(&input)
72 }
73
74 pub fn any_just_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool {
76 inputs.into_iter().any(|t| self.just_pressed(t))
77 }
78
79 pub fn all_just_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool {
81 inputs.into_iter().all(|t| self.just_pressed(t))
82 }
83
84 pub fn just_released(&self, input: T) -> bool {
86 self.just_released.contains(&input)
87 }
88
89 pub fn any_just_released(&self, inputs: impl IntoIterator<Item = T>) -> bool {
91 inputs.into_iter().any(|t| self.just_released(t))
92 }
93
94 pub fn all_just_released(&self, inputs: impl IntoIterator<Item = T>) -> bool {
96 inputs.into_iter().all(|t| self.just_released(t))
97 }
98
99 pub fn get_pressed(&self) -> impl ExactSizeIterator<Item = &T> {
101 self.pressed.iter()
102 }
103
104 pub fn get_just_pressed(&self) -> impl ExactSizeIterator<Item = &T> {
106 self.just_pressed.iter()
107 }
108
109 pub fn get_just_released(&self) -> impl ExactSizeIterator<Item = &T> {
111 self.just_released.iter()
112 }
113}