goud_engine/core/input_manager/
manager.rs1#[cfg(feature = "native")]
4use glfw::{Key, MouseButton};
5use std::collections::{HashMap, HashSet, VecDeque};
6use std::time::{Duration, Instant};
7
8use crate::core::math::Vec2;
9
10use super::types::{BufferedInput, GamepadState, InputBinding};
11
12#[derive(Debug, Clone)]
18pub struct InputManager {
19 pub(super) keys_current: HashSet<Key>,
21 pub(super) mouse_buttons_current: HashSet<MouseButton>,
22 pub(super) gamepad_buttons_current: Vec<HashSet<u32>>,
24 pub(super) mouse_position: Vec2,
25 pub(super) mouse_delta: Vec2,
26
27 pub(super) keys_previous: HashSet<Key>,
29 pub(super) mouse_buttons_previous: HashSet<MouseButton>,
30 pub(super) gamepad_buttons_previous: Vec<HashSet<u32>>,
32
33 pub(super) gamepads: Vec<GamepadState>,
35 pub(super) gamepads_previous: Vec<GamepadState>,
36
37 pub(super) scroll_delta: Vec2,
39
40 pub(super) action_mappings: HashMap<String, Vec<InputBinding>>,
42
43 pub(super) input_buffer: VecDeque<BufferedInput>,
45 pub(super) buffer_duration: Duration,
46 pub(super) last_update: Instant,
47
48 pub(super) analog_deadzone: f32,
50}
51
52impl InputManager {
53 pub fn new() -> Self {
57 Self::with_buffer_duration(Duration::from_millis(200))
58 }
59
60 pub fn with_buffer_duration(buffer_duration: Duration) -> Self {
67 Self {
68 keys_current: HashSet::new(),
69 mouse_buttons_current: HashSet::new(),
70 gamepad_buttons_current: vec![HashSet::new(); 4], mouse_position: Vec2::zero(),
72 mouse_delta: Vec2::zero(),
73 keys_previous: HashSet::new(),
74 mouse_buttons_previous: HashSet::new(),
75 gamepad_buttons_previous: vec![HashSet::new(); 4], gamepads: vec![GamepadState::new(); 4], gamepads_previous: vec![GamepadState::new(); 4],
78 scroll_delta: Vec2::zero(),
79 action_mappings: HashMap::new(),
80 input_buffer: VecDeque::with_capacity(32),
81 buffer_duration,
82 last_update: Instant::now(),
83 analog_deadzone: 0.1, }
85 }
86
87 pub fn update(&mut self) {
92 let now = Instant::now();
93
94 self.keys_previous = self.keys_current.clone();
96 self.mouse_buttons_previous = self.mouse_buttons_current.clone();
97 self.gamepad_buttons_previous = self.gamepad_buttons_current.clone();
98 self.gamepads_previous = self.gamepads.clone();
99
100 self.mouse_delta = Vec2::zero();
102 self.scroll_delta = Vec2::zero();
103
104 self.input_buffer
106 .retain(|input| !input.is_expired(now, self.buffer_duration));
107
108 self.last_update = now;
109 }
110
111 pub fn press_key(&mut self, key: Key) {
115 if !self.keys_current.contains(&key) {
117 self.buffer_input(InputBinding::Key(key));
118 }
119 self.keys_current.insert(key);
120 }
121
122 pub fn release_key(&mut self, key: Key) {
124 self.keys_current.remove(&key);
125 }
126
127 pub fn key_pressed(&self, key: Key) -> bool {
129 self.keys_current.contains(&key)
130 }
131
132 pub fn key_just_pressed(&self, key: Key) -> bool {
136 self.keys_current.contains(&key) && !self.keys_previous.contains(&key)
137 }
138
139 pub fn key_just_released(&self, key: Key) -> bool {
143 !self.keys_current.contains(&key) && self.keys_previous.contains(&key)
144 }
145
146 pub fn keys_pressed(&self) -> impl Iterator<Item = &Key> {
148 self.keys_current.iter()
149 }
150
151 pub fn press_mouse_button(&mut self, button: MouseButton) {
155 if !self.mouse_buttons_current.contains(&button) {
157 self.buffer_input(InputBinding::MouseButton(button));
158 }
159 self.mouse_buttons_current.insert(button);
160 }
161
162 pub fn release_mouse_button(&mut self, button: MouseButton) {
164 self.mouse_buttons_current.remove(&button);
165 }
166
167 pub fn mouse_button_pressed(&self, button: MouseButton) -> bool {
169 self.mouse_buttons_current.contains(&button)
170 }
171
172 pub fn mouse_button_just_pressed(&self, button: MouseButton) -> bool {
174 self.mouse_buttons_current.contains(&button)
175 && !self.mouse_buttons_previous.contains(&button)
176 }
177
178 pub fn mouse_button_just_released(&self, button: MouseButton) -> bool {
180 !self.mouse_buttons_current.contains(&button)
181 && self.mouse_buttons_previous.contains(&button)
182 }
183
184 pub fn mouse_buttons_pressed(&self) -> impl Iterator<Item = &MouseButton> {
186 self.mouse_buttons_current.iter()
187 }
188
189 pub fn set_mouse_position(&mut self, position: Vec2) {
193 self.mouse_delta = position - self.mouse_position;
194 self.mouse_position = position;
195 }
196
197 pub fn mouse_position(&self) -> Vec2 {
199 self.mouse_position
200 }
201
202 pub fn mouse_delta(&self) -> Vec2 {
204 self.mouse_delta
205 }
206
207 pub fn add_scroll_delta(&mut self, delta: Vec2) {
211 self.scroll_delta = self.scroll_delta + delta;
212 }
213
214 pub fn scroll_delta(&self) -> Vec2 {
216 self.scroll_delta
217 }
218
219 pub fn clear(&mut self) {
221 self.keys_current.clear();
222 self.keys_previous.clear();
223 self.mouse_buttons_current.clear();
224 self.mouse_buttons_previous.clear();
225 for buttons in &mut self.gamepad_buttons_current {
226 buttons.clear();
227 }
228 for buttons in &mut self.gamepad_buttons_previous {
229 buttons.clear();
230 }
231 for gamepad in &mut self.gamepads {
233 gamepad.buttons.clear();
234 gamepad.axes.clear();
235 }
237 for gamepad in &mut self.gamepads_previous {
238 gamepad.buttons.clear();
239 gamepad.axes.clear();
240 }
241 self.mouse_delta = Vec2::zero();
242 self.scroll_delta = Vec2::zero();
243 }
244
245 pub(super) fn buffer_input(&mut self, binding: InputBinding) {
247 let now = Instant::now();
248 self.input_buffer
249 .push_back(BufferedInput::new(binding, now));
250
251 while self.input_buffer.len() > 32 {
253 self.input_buffer.pop_front();
254 }
255 }
256}
257
258impl Default for InputManager {
259 fn default() -> Self {
260 Self::new()
261 }
262}