1#[cfg(feature = "native")]
77use glfw::{GamepadAxis, Key, MouseButton};
78use std::collections::{HashMap, HashSet, VecDeque};
79use std::time::{Duration, Instant};
80
81use crate::core::math::Vec2;
82
83#[derive(Debug, Clone)]
87struct GamepadState {
88 buttons: HashSet<u32>,
90 axes: HashMap<GamepadAxis, f32>,
92 connected: bool,
94 vibration: f32,
96}
97
98impl GamepadState {
99 fn new() -> Self {
100 Self {
101 buttons: HashSet::new(),
102 axes: HashMap::new(),
103 connected: false,
104 vibration: 0.0,
105 }
106 }
107
108 #[allow(dead_code)]
109 fn is_empty(&self) -> bool {
110 self.buttons.is_empty() && self.axes.is_empty()
111 }
112}
113
114#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
119pub enum InputBinding {
120 Key(Key),
122 MouseButton(MouseButton),
124 GamepadButton {
126 gamepad_id: usize,
128 button: u32,
130 },
131}
132
133impl InputBinding {
134 pub fn is_pressed(&self, input: &InputManager) -> bool {
136 match self {
137 InputBinding::Key(key) => input.key_pressed(*key),
138 InputBinding::MouseButton(button) => input.mouse_button_pressed(*button),
139 InputBinding::GamepadButton { gamepad_id, button } => {
140 input.gamepad_button_pressed(*gamepad_id, *button)
141 }
142 }
143 }
144
145 pub fn is_just_pressed(&self, input: &InputManager) -> bool {
147 match self {
148 InputBinding::Key(key) => input.key_just_pressed(*key),
149 InputBinding::MouseButton(button) => input.mouse_button_just_pressed(*button),
150 InputBinding::GamepadButton { gamepad_id, button } => {
151 input.gamepad_button_just_pressed(*gamepad_id, *button)
152 }
153 }
154 }
155
156 pub fn is_just_released(&self, input: &InputManager) -> bool {
158 match self {
159 InputBinding::Key(key) => input.key_just_released(*key),
160 InputBinding::MouseButton(button) => input.mouse_button_just_released(*button),
161 InputBinding::GamepadButton { gamepad_id, button } => {
162 input.gamepad_button_just_released(*gamepad_id, *button)
163 }
164 }
165 }
166}
167
168impl std::fmt::Display for InputBinding {
169 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
170 match self {
171 InputBinding::Key(key) => write!(f, "Key({:?})", key),
172 InputBinding::MouseButton(button) => write!(f, "MouseButton({:?})", button),
173 InputBinding::GamepadButton { gamepad_id, button } => {
174 write!(
175 f,
176 "GamepadButton(gamepad={}, button={})",
177 gamepad_id, button
178 )
179 }
180 }
181 }
182}
183
184#[derive(Debug, Clone)]
188struct BufferedInput {
189 binding: InputBinding,
191 timestamp: Instant,
193}
194
195impl BufferedInput {
196 fn new(binding: InputBinding, timestamp: Instant) -> Self {
198 Self { binding, timestamp }
199 }
200
201 fn age(&self, now: Instant) -> f32 {
203 now.duration_since(self.timestamp).as_secs_f32()
204 }
205
206 fn is_expired(&self, now: Instant, buffer_duration: Duration) -> bool {
208 now.duration_since(self.timestamp) > buffer_duration
209 }
210}
211
212#[derive(Debug, Clone)]
218pub struct InputManager {
219 keys_current: HashSet<Key>,
221 mouse_buttons_current: HashSet<MouseButton>,
222 gamepad_buttons_current: Vec<HashSet<u32>>, mouse_position: Vec2,
224 mouse_delta: Vec2,
225
226 keys_previous: HashSet<Key>,
228 mouse_buttons_previous: HashSet<MouseButton>,
229 gamepad_buttons_previous: Vec<HashSet<u32>>, gamepads: Vec<GamepadState>,
233 gamepads_previous: Vec<GamepadState>,
234
235 scroll_delta: Vec2,
237
238 action_mappings: HashMap<String, Vec<InputBinding>>,
240
241 input_buffer: VecDeque<BufferedInput>,
243 buffer_duration: Duration,
244 last_update: Instant,
245
246 analog_deadzone: f32,
248}
249
250impl InputManager {
251 pub fn new() -> Self {
255 Self::with_buffer_duration(Duration::from_millis(200))
256 }
257
258 pub fn with_buffer_duration(buffer_duration: Duration) -> Self {
265 Self {
266 keys_current: HashSet::new(),
267 mouse_buttons_current: HashSet::new(),
268 gamepad_buttons_current: vec![HashSet::new(); 4], mouse_position: Vec2::zero(),
270 mouse_delta: Vec2::zero(),
271 keys_previous: HashSet::new(),
272 mouse_buttons_previous: HashSet::new(),
273 gamepad_buttons_previous: vec![HashSet::new(); 4], gamepads: vec![GamepadState::new(); 4], gamepads_previous: vec![GamepadState::new(); 4],
276 scroll_delta: Vec2::zero(),
277 action_mappings: HashMap::new(),
278 input_buffer: VecDeque::with_capacity(32),
279 buffer_duration,
280 last_update: Instant::now(),
281 analog_deadzone: 0.1, }
283 }
284
285 pub fn update(&mut self) {
290 let now = Instant::now();
291
292 self.keys_previous = self.keys_current.clone();
294 self.mouse_buttons_previous = self.mouse_buttons_current.clone();
295 self.gamepad_buttons_previous = self.gamepad_buttons_current.clone();
296 self.gamepads_previous = self.gamepads.clone();
297
298 self.mouse_delta = Vec2::zero();
300 self.scroll_delta = Vec2::zero();
301
302 self.input_buffer
304 .retain(|input| !input.is_expired(now, self.buffer_duration));
305
306 self.last_update = now;
307 }
308
309 pub fn press_key(&mut self, key: Key) {
313 if !self.keys_current.contains(&key) {
315 self.buffer_input(InputBinding::Key(key));
316 }
317 self.keys_current.insert(key);
318 }
319
320 pub fn release_key(&mut self, key: Key) {
322 self.keys_current.remove(&key);
323 }
324
325 pub fn key_pressed(&self, key: Key) -> bool {
327 self.keys_current.contains(&key)
328 }
329
330 pub fn key_just_pressed(&self, key: Key) -> bool {
334 self.keys_current.contains(&key) && !self.keys_previous.contains(&key)
335 }
336
337 pub fn key_just_released(&self, key: Key) -> bool {
341 !self.keys_current.contains(&key) && self.keys_previous.contains(&key)
342 }
343
344 pub fn keys_pressed(&self) -> impl Iterator<Item = &Key> {
346 self.keys_current.iter()
347 }
348
349 pub fn press_mouse_button(&mut self, button: MouseButton) {
353 if !self.mouse_buttons_current.contains(&button) {
355 self.buffer_input(InputBinding::MouseButton(button));
356 }
357 self.mouse_buttons_current.insert(button);
358 }
359
360 pub fn release_mouse_button(&mut self, button: MouseButton) {
362 self.mouse_buttons_current.remove(&button);
363 }
364
365 pub fn mouse_button_pressed(&self, button: MouseButton) -> bool {
367 self.mouse_buttons_current.contains(&button)
368 }
369
370 pub fn mouse_button_just_pressed(&self, button: MouseButton) -> bool {
372 self.mouse_buttons_current.contains(&button)
373 && !self.mouse_buttons_previous.contains(&button)
374 }
375
376 pub fn mouse_button_just_released(&self, button: MouseButton) -> bool {
378 !self.mouse_buttons_current.contains(&button)
379 && self.mouse_buttons_previous.contains(&button)
380 }
381
382 pub fn mouse_buttons_pressed(&self) -> impl Iterator<Item = &MouseButton> {
384 self.mouse_buttons_current.iter()
385 }
386
387 pub fn set_mouse_position(&mut self, position: Vec2) {
391 self.mouse_delta = position - self.mouse_position;
392 self.mouse_position = position;
393 }
394
395 pub fn mouse_position(&self) -> Vec2 {
397 self.mouse_position
398 }
399
400 pub fn mouse_delta(&self) -> Vec2 {
402 self.mouse_delta
403 }
404
405 pub fn add_scroll_delta(&mut self, delta: Vec2) {
409 self.scroll_delta = self.scroll_delta + delta;
410 }
411
412 pub fn scroll_delta(&self) -> Vec2 {
414 self.scroll_delta
415 }
416
417 pub fn press_gamepad_button(&mut self, gamepad_id: usize, button: u32) {
424 self.ensure_gamepad_capacity(gamepad_id);
425
426 let is_new = !self.gamepad_buttons_current[gamepad_id].contains(&button);
428 if is_new {
429 self.buffer_input(InputBinding::GamepadButton { gamepad_id, button });
430 }
431
432 self.gamepad_buttons_current[gamepad_id].insert(button);
433 }
434
435 pub fn release_gamepad_button(&mut self, gamepad_id: usize, button: u32) {
440 self.ensure_gamepad_capacity(gamepad_id);
441 self.gamepad_buttons_current[gamepad_id].remove(&button);
442 }
443
444 pub fn gamepad_button_pressed(&self, gamepad_id: usize, button: u32) -> bool {
448 self.gamepad_buttons_current
449 .get(gamepad_id)
450 .is_some_and(|buttons| buttons.contains(&button))
451 }
452
453 pub fn gamepad_button_just_pressed(&self, gamepad_id: usize, button: u32) -> bool {
455 let current = self
456 .gamepad_buttons_current
457 .get(gamepad_id)
458 .is_some_and(|buttons| buttons.contains(&button));
459 let previous = self
460 .gamepad_buttons_previous
461 .get(gamepad_id)
462 .is_some_and(|buttons| buttons.contains(&button));
463 current && !previous
464 }
465
466 pub fn gamepad_button_just_released(&self, gamepad_id: usize, button: u32) -> bool {
468 let current = self
469 .gamepad_buttons_current
470 .get(gamepad_id)
471 .is_some_and(|buttons| buttons.contains(&button));
472 let previous = self
473 .gamepad_buttons_previous
474 .get(gamepad_id)
475 .is_some_and(|buttons| buttons.contains(&button));
476 !current && previous
477 }
478
479 fn ensure_gamepad_capacity(&mut self, gamepad_id: usize) {
481 while self.gamepad_buttons_current.len() <= gamepad_id {
482 self.gamepad_buttons_current.push(HashSet::new());
483 }
484 while self.gamepad_buttons_previous.len() <= gamepad_id {
485 self.gamepad_buttons_previous.push(HashSet::new());
486 }
487 while self.gamepads.len() <= gamepad_id {
488 self.gamepads.push(GamepadState::new());
489 }
490 while self.gamepads_previous.len() <= gamepad_id {
491 self.gamepads_previous.push(GamepadState::new());
492 }
493 }
494
495 pub fn set_gamepad_axis(&mut self, gamepad_id: usize, axis: GamepadAxis, value: f32) {
501 self.ensure_gamepad_capacity(gamepad_id);
502
503 let deadzone_value = if value.abs() < self.analog_deadzone {
505 0.0
506 } else {
507 value
508 };
509
510 self.gamepads[gamepad_id].axes.insert(axis, deadzone_value);
511 }
512
513 pub fn gamepad_axis(&self, gamepad_id: usize, axis: GamepadAxis) -> f32 {
517 self.gamepads
518 .get(gamepad_id)
519 .and_then(|gamepad| gamepad.axes.get(&axis).copied())
520 .unwrap_or(0.0)
521 }
522
523 pub fn gamepad_left_stick(&self, gamepad_id: usize) -> Vec2 {
527 Vec2::new(
528 self.gamepad_axis(gamepad_id, GamepadAxis::AxisLeftX),
529 self.gamepad_axis(gamepad_id, GamepadAxis::AxisLeftY),
530 )
531 }
532
533 pub fn gamepad_right_stick(&self, gamepad_id: usize) -> Vec2 {
537 Vec2::new(
538 self.gamepad_axis(gamepad_id, GamepadAxis::AxisRightX),
539 self.gamepad_axis(gamepad_id, GamepadAxis::AxisRightY),
540 )
541 }
542
543 pub fn gamepad_left_trigger(&self, gamepad_id: usize) -> f32 {
547 (self.gamepad_axis(gamepad_id, GamepadAxis::AxisLeftTrigger) + 1.0) * 0.5
549 }
550
551 pub fn gamepad_right_trigger(&self, gamepad_id: usize) -> f32 {
555 (self.gamepad_axis(gamepad_id, GamepadAxis::AxisRightTrigger) + 1.0) * 0.5
557 }
558
559 pub fn set_gamepad_connected(&mut self, gamepad_id: usize, connected: bool) {
563 self.ensure_gamepad_capacity(gamepad_id);
564 self.gamepads[gamepad_id].connected = connected;
565 }
566
567 pub fn is_gamepad_connected(&self, gamepad_id: usize) -> bool {
569 self.gamepads
570 .get(gamepad_id)
571 .map(|gamepad| gamepad.connected)
572 .unwrap_or(false)
573 }
574
575 pub fn connected_gamepad_count(&self) -> usize {
577 self.gamepads
578 .iter()
579 .filter(|gamepad| gamepad.connected)
580 .count()
581 }
582
583 pub fn connected_gamepads(&self) -> impl Iterator<Item = usize> + '_ {
585 self.gamepads
586 .iter()
587 .enumerate()
588 .filter_map(|(id, gamepad)| if gamepad.connected { Some(id) } else { None })
589 }
590
591 pub fn set_gamepad_vibration(&mut self, gamepad_id: usize, intensity: f32) {
598 self.ensure_gamepad_capacity(gamepad_id);
599 self.gamepads[gamepad_id].vibration = intensity.clamp(0.0, 1.0);
600 }
601
602 pub fn gamepad_vibration(&self, gamepad_id: usize) -> f32 {
604 self.gamepads
605 .get(gamepad_id)
606 .map(|gamepad| gamepad.vibration)
607 .unwrap_or(0.0)
608 }
609
610 pub fn stop_gamepad_vibration(&mut self, gamepad_id: usize) {
612 self.set_gamepad_vibration(gamepad_id, 0.0);
613 }
614
615 pub fn stop_all_vibration(&mut self) {
617 for gamepad in &mut self.gamepads {
618 gamepad.vibration = 0.0;
619 }
620 }
621
622 pub fn analog_deadzone(&self) -> f32 {
628 self.analog_deadzone
629 }
630
631 pub fn set_analog_deadzone(&mut self, deadzone: f32) {
636 self.analog_deadzone = deadzone.clamp(0.0, 1.0);
637 }
638
639 fn buffer_input(&mut self, binding: InputBinding) {
643 let now = Instant::now();
644 self.input_buffer
645 .push_back(BufferedInput::new(binding, now));
646
647 while self.input_buffer.len() > 32 {
649 self.input_buffer.pop_front();
650 }
651 }
652
653 pub fn buffer_duration(&self) -> Duration {
655 self.buffer_duration
656 }
657
658 pub fn set_buffer_duration(&mut self, duration: Duration) {
662 self.buffer_duration = duration;
663 }
664
665 pub fn buffer_size(&self) -> usize {
667 self.input_buffer.len()
668 }
669
670 pub fn clear_buffer(&mut self) {
674 self.input_buffer.clear();
675 }
676
677 pub fn sequence_detected(&self, sequence: &[InputBinding]) -> bool {
703 if sequence.is_empty() || self.input_buffer.is_empty() {
704 return false;
705 }
706
707 let now = Instant::now();
708 let mut seq_index = 0;
709
710 for buffered in &self.input_buffer {
712 if buffered.is_expired(now, self.buffer_duration) {
714 continue;
715 }
716
717 if buffered.binding == sequence[seq_index] {
719 seq_index += 1;
720
721 if seq_index == sequence.len() {
723 return true;
724 }
725 }
726 }
727
728 false
729 }
730
731 pub fn consume_sequence(&mut self, sequence: &[InputBinding]) -> bool {
737 if self.sequence_detected(sequence) {
738 self.clear_buffer();
739 true
740 } else {
741 false
742 }
743 }
744
745 pub fn time_since_last_input(&self) -> Option<f32> {
749 self.input_buffer
750 .back()
751 .map(|input| input.age(Instant::now()))
752 }
753
754 pub fn buffered_inputs(&self) -> impl Iterator<Item = (InputBinding, f32)> + '_ {
758 let now = Instant::now();
759 self.input_buffer
760 .iter()
761 .map(move |input| (input.binding, input.age(now)))
762 }
763
764 pub fn clear(&mut self) {
766 self.keys_current.clear();
767 self.keys_previous.clear();
768 self.mouse_buttons_current.clear();
769 self.mouse_buttons_previous.clear();
770 for buttons in &mut self.gamepad_buttons_current {
771 buttons.clear();
772 }
773 for buttons in &mut self.gamepad_buttons_previous {
774 buttons.clear();
775 }
776 for gamepad in &mut self.gamepads {
778 gamepad.buttons.clear();
779 gamepad.axes.clear();
780 }
782 for gamepad in &mut self.gamepads_previous {
783 gamepad.buttons.clear();
784 gamepad.axes.clear();
785 }
786 self.mouse_delta = Vec2::zero();
787 self.scroll_delta = Vec2::zero();
788 }
789
790 pub fn map_action(&mut self, action: impl Into<String>, binding: InputBinding) {
808 self.action_mappings
809 .entry(action.into())
810 .or_default()
811 .push(binding);
812 }
813
814 pub fn unmap_action(&mut self, action: &str, binding: InputBinding) -> bool {
818 if let Some(bindings) = self.action_mappings.get_mut(action) {
819 if let Some(pos) = bindings.iter().position(|b| *b == binding) {
820 bindings.remove(pos);
821 return true;
822 }
823 }
824 false
825 }
826
827 pub fn clear_action(&mut self, action: &str) -> bool {
831 self.action_mappings.remove(action).is_some()
832 }
833
834 pub fn clear_all_actions(&mut self) {
836 self.action_mappings.clear();
837 }
838
839 pub fn get_action_bindings(&self, action: &str) -> &[InputBinding] {
843 self.action_mappings
844 .get(action)
845 .map(|v| v.as_slice())
846 .unwrap_or(&[])
847 }
848
849 pub fn has_action(&self, action: &str) -> bool {
851 self.action_mappings.contains_key(action)
852 }
853
854 pub fn action_names(&self) -> impl Iterator<Item = &str> {
856 self.action_mappings.keys().map(|s| s.as_str())
857 }
858
859 pub fn action_count(&self) -> usize {
861 self.action_mappings.len()
862 }
863
864 pub fn action_pressed(&self, action: &str) -> bool {
868 self.action_mappings
869 .get(action)
870 .is_some_and(|bindings| bindings.iter().any(|b| b.is_pressed(self)))
871 }
872
873 pub fn action_just_pressed(&self, action: &str) -> bool {
877 self.action_mappings
878 .get(action)
879 .is_some_and(|bindings| bindings.iter().any(|b| b.is_just_pressed(self)))
880 }
881
882 pub fn action_just_released(&self, action: &str) -> bool {
886 self.action_mappings
887 .get(action)
888 .is_some_and(|bindings| bindings.iter().any(|b| b.is_just_released(self)))
889 }
890
891 pub fn action_strength(&self, action: &str) -> f32 {
896 if self.action_pressed(action) {
897 1.0
898 } else {
899 0.0
900 }
901 }
902}
903
904impl Default for InputManager {
905 fn default() -> Self {
906 Self::new()
907 }
908}
909
910#[cfg(test)]
911mod tests {
912 use super::*;
913
914 #[test]
915 fn test_new_input_manager() {
916 let input = InputManager::new();
917 assert!(!input.key_pressed(Key::A));
918 assert!(!input.mouse_button_pressed(MouseButton::Button1));
919 assert_eq!(input.mouse_position(), Vec2::zero());
920 assert_eq!(input.mouse_delta(), Vec2::zero());
921 }
922
923 #[test]
924 fn test_default() {
925 let input = InputManager::default();
926 assert!(!input.key_pressed(Key::W));
927 }
928
929 #[test]
932 fn test_key_pressed() {
933 let mut input = InputManager::new();
934 assert!(!input.key_pressed(Key::A));
935
936 input.press_key(Key::A);
937 assert!(input.key_pressed(Key::A));
938
939 input.release_key(Key::A);
940 assert!(!input.key_pressed(Key::A));
941 }
942
943 #[test]
944 fn test_key_just_pressed() {
945 let mut input = InputManager::new();
946
947 input.press_key(Key::Space);
949 assert!(input.key_just_pressed(Key::Space)); input.update();
953 assert!(!input.key_just_pressed(Key::Space)); input.release_key(Key::Space);
957 input.update();
958 input.press_key(Key::Space);
959 assert!(input.key_just_pressed(Key::Space)); }
961
962 #[test]
963 fn test_key_just_released() {
964 let mut input = InputManager::new();
965
966 input.press_key(Key::W);
968 input.update(); input.release_key(Key::W);
972 assert!(input.key_just_released(Key::W));
973
974 input.update();
976 assert!(!input.key_just_released(Key::W)); }
978
979 #[test]
980 fn test_keys_pressed_iterator() {
981 let mut input = InputManager::new();
982 input.press_key(Key::A);
983 input.press_key(Key::B);
984 input.press_key(Key::C);
985
986 let pressed_keys: Vec<_> = input.keys_pressed().collect();
987 assert_eq!(pressed_keys.len(), 3);
988 assert!(pressed_keys.contains(&&Key::A));
989 assert!(pressed_keys.contains(&&Key::B));
990 assert!(pressed_keys.contains(&&Key::C));
991 }
992
993 #[test]
996 fn test_mouse_button_pressed() {
997 let mut input = InputManager::new();
998 assert!(!input.mouse_button_pressed(MouseButton::Button1));
999
1000 input.press_mouse_button(MouseButton::Button1);
1001 assert!(input.mouse_button_pressed(MouseButton::Button1));
1002
1003 input.release_mouse_button(MouseButton::Button1);
1004 assert!(!input.mouse_button_pressed(MouseButton::Button1));
1005 }
1006
1007 #[test]
1008 fn test_mouse_button_just_pressed() {
1009 let mut input = InputManager::new();
1010
1011 input.press_mouse_button(MouseButton::Button2);
1012 assert!(input.mouse_button_just_pressed(MouseButton::Button2));
1013
1014 input.update();
1015 assert!(!input.mouse_button_just_pressed(MouseButton::Button2));
1016 }
1017
1018 #[test]
1019 fn test_mouse_button_just_released() {
1020 let mut input = InputManager::new();
1021
1022 input.press_mouse_button(MouseButton::Button1);
1023 input.update();
1024 input.release_mouse_button(MouseButton::Button1);
1025 assert!(input.mouse_button_just_released(MouseButton::Button1));
1026
1027 input.update();
1028 assert!(!input.mouse_button_just_released(MouseButton::Button1));
1029 }
1030
1031 #[test]
1032 fn test_mouse_buttons_pressed_iterator() {
1033 let mut input = InputManager::new();
1034 input.press_mouse_button(MouseButton::Button1);
1035 input.press_mouse_button(MouseButton::Button2);
1036
1037 let pressed_buttons: Vec<_> = input.mouse_buttons_pressed().collect();
1038 assert_eq!(pressed_buttons.len(), 2);
1039 }
1040
1041 #[test]
1044 fn test_mouse_position() {
1045 let mut input = InputManager::new();
1046 assert_eq!(input.mouse_position(), Vec2::zero());
1047
1048 let pos = Vec2::new(100.0, 200.0);
1049 input.set_mouse_position(pos);
1050 assert_eq!(input.mouse_position(), pos);
1051 }
1052
1053 #[test]
1054 fn test_mouse_delta() {
1055 let mut input = InputManager::new();
1056
1057 input.set_mouse_position(Vec2::new(100.0, 100.0));
1059 assert_eq!(input.mouse_delta(), Vec2::new(100.0, 100.0)); input.set_mouse_position(Vec2::new(150.0, 120.0));
1063 assert_eq!(input.mouse_delta(), Vec2::new(50.0, 20.0)); }
1065
1066 #[test]
1067 fn test_mouse_delta_reset_on_update() {
1068 let mut input = InputManager::new();
1069
1070 input.set_mouse_position(Vec2::new(100.0, 100.0));
1071 assert_ne!(input.mouse_delta(), Vec2::zero());
1072
1073 input.update(); assert_eq!(input.mouse_delta(), Vec2::zero());
1075 }
1076
1077 #[test]
1080 fn test_scroll_delta() {
1081 let mut input = InputManager::new();
1082 assert_eq!(input.scroll_delta(), Vec2::zero());
1083
1084 input.add_scroll_delta(Vec2::new(0.0, 1.0));
1085 assert_eq!(input.scroll_delta(), Vec2::new(0.0, 1.0));
1086
1087 input.add_scroll_delta(Vec2::new(0.0, 2.0));
1088 assert_eq!(input.scroll_delta(), Vec2::new(0.0, 3.0)); }
1090
1091 #[test]
1092 fn test_scroll_delta_reset_on_update() {
1093 let mut input = InputManager::new();
1094
1095 input.add_scroll_delta(Vec2::new(0.0, 5.0));
1096 input.update();
1097 assert_eq!(input.scroll_delta(), Vec2::zero());
1098 }
1099
1100 #[test]
1103 fn test_gamepad_button_pressed() {
1104 let mut input = InputManager::new();
1105
1106 input.press_gamepad_button(0, 1);
1107 assert!(input.gamepad_button_pressed(0, 1));
1108 assert!(!input.gamepad_button_pressed(0, 2));
1109 assert!(!input.gamepad_button_pressed(1, 1)); input.release_gamepad_button(0, 1);
1112 assert!(!input.gamepad_button_pressed(0, 1));
1113 }
1114
1115 #[test]
1116 fn test_gamepad_button_just_pressed() {
1117 let mut input = InputManager::new();
1118
1119 input.press_gamepad_button(0, 5);
1120 assert!(input.gamepad_button_just_pressed(0, 5));
1121
1122 input.update();
1123 assert!(!input.gamepad_button_just_pressed(0, 5));
1124 }
1125
1126 #[test]
1127 fn test_gamepad_button_just_released() {
1128 let mut input = InputManager::new();
1129
1130 input.press_gamepad_button(1, 3);
1131 input.update();
1132 input.release_gamepad_button(1, 3);
1133 assert!(input.gamepad_button_just_released(1, 3));
1134
1135 input.update();
1136 assert!(!input.gamepad_button_just_released(1, 3));
1137 }
1138
1139 #[test]
1140 fn test_gamepad_multiple_gamepads() {
1141 let mut input = InputManager::new();
1142
1143 input.press_gamepad_button(0, 1);
1144 input.press_gamepad_button(1, 1);
1145 input.press_gamepad_button(2, 2);
1146
1147 assert!(input.gamepad_button_pressed(0, 1));
1148 assert!(input.gamepad_button_pressed(1, 1));
1149 assert!(input.gamepad_button_pressed(2, 2));
1150 assert!(!input.gamepad_button_pressed(2, 1));
1151 }
1152
1153 #[test]
1154 fn test_gamepad_capacity_expansion() {
1155 let mut input = InputManager::new();
1156
1157 input.press_gamepad_button(5, 1);
1159 assert!(input.gamepad_button_pressed(5, 1));
1160 }
1161
1162 #[test]
1165 fn test_clear() {
1166 let mut input = InputManager::new();
1167
1168 input.press_key(Key::A);
1170 input.press_mouse_button(MouseButton::Button1);
1171 input.set_mouse_position(Vec2::new(100.0, 100.0));
1172 input.add_scroll_delta(Vec2::new(0.0, 1.0));
1173 input.press_gamepad_button(0, 5);
1174
1175 input.clear();
1177
1178 assert!(!input.key_pressed(Key::A));
1180 assert!(!input.mouse_button_pressed(MouseButton::Button1));
1181 assert_eq!(input.mouse_delta(), Vec2::zero());
1182 assert_eq!(input.scroll_delta(), Vec2::zero());
1183 assert!(!input.gamepad_button_pressed(0, 5));
1184 }
1185
1186 #[test]
1189 fn test_update_copies_state() {
1190 let mut input = InputManager::new();
1191
1192 input.press_key(Key::Space);
1193 assert!(input.key_just_pressed(Key::Space));
1194
1195 input.update();
1196 assert!(!input.key_just_pressed(Key::Space)); assert!(input.key_pressed(Key::Space)); }
1199
1200 #[test]
1201 fn test_clone() {
1202 let mut input = InputManager::new();
1203 input.press_key(Key::A);
1204
1205 let cloned = input.clone();
1206 assert!(cloned.key_pressed(Key::A));
1207 }
1208
1209 #[test]
1210 fn test_debug() {
1211 let input = InputManager::new();
1212 let debug_str = format!("{:?}", input);
1213 assert!(debug_str.contains("InputManager"));
1214 }
1215
1216 #[test]
1219 fn test_input_binding_key() {
1220 let mut input = InputManager::new();
1221 let binding = InputBinding::Key(Key::A);
1222
1223 assert!(!binding.is_pressed(&input));
1224 assert!(!binding.is_just_pressed(&input));
1225
1226 input.press_key(Key::A);
1227 assert!(binding.is_pressed(&input));
1228 assert!(binding.is_just_pressed(&input));
1229
1230 input.update();
1231 assert!(binding.is_pressed(&input));
1232 assert!(!binding.is_just_pressed(&input));
1233
1234 input.release_key(Key::A);
1235 assert!(!binding.is_pressed(&input));
1236 assert!(binding.is_just_released(&input));
1237 }
1238
1239 #[test]
1240 fn test_input_binding_mouse_button() {
1241 let mut input = InputManager::new();
1242 let binding = InputBinding::MouseButton(MouseButton::Button1);
1243
1244 assert!(!binding.is_pressed(&input));
1245
1246 input.press_mouse_button(MouseButton::Button1);
1247 assert!(binding.is_pressed(&input));
1248 assert!(binding.is_just_pressed(&input));
1249 }
1250
1251 #[test]
1252 fn test_input_binding_gamepad_button() {
1253 let mut input = InputManager::new();
1254 let binding = InputBinding::GamepadButton {
1255 gamepad_id: 0,
1256 button: 5,
1257 };
1258
1259 assert!(!binding.is_pressed(&input));
1260
1261 input.press_gamepad_button(0, 5);
1262 assert!(binding.is_pressed(&input));
1263 assert!(binding.is_just_pressed(&input));
1264 }
1265
1266 #[test]
1267 fn test_input_binding_display() {
1268 let key_binding = InputBinding::Key(Key::Space);
1269 let mouse_binding = InputBinding::MouseButton(MouseButton::Button1);
1270 let gamepad_binding = InputBinding::GamepadButton {
1271 gamepad_id: 2,
1272 button: 10,
1273 };
1274
1275 let key_str = format!("{}", key_binding);
1276 let mouse_str = format!("{}", mouse_binding);
1277 let gamepad_str = format!("{}", gamepad_binding);
1278
1279 assert!(key_str.contains("Key"));
1280 assert!(mouse_str.contains("MouseButton"));
1281 assert!(gamepad_str.contains("GamepadButton"));
1282 assert!(gamepad_str.contains("gamepad=2"));
1283 assert!(gamepad_str.contains("button=10"));
1284 }
1285
1286 #[test]
1287 fn test_input_binding_eq() {
1288 let binding1 = InputBinding::Key(Key::A);
1289 let binding2 = InputBinding::Key(Key::A);
1290 let binding3 = InputBinding::Key(Key::B);
1291
1292 assert_eq!(binding1, binding2);
1293 assert_ne!(binding1, binding3);
1294 }
1295
1296 #[test]
1297 fn test_input_binding_hash() {
1298 use std::collections::HashSet;
1299
1300 let mut set = HashSet::new();
1301 set.insert(InputBinding::Key(Key::A));
1302 set.insert(InputBinding::Key(Key::A)); set.insert(InputBinding::Key(Key::B));
1304
1305 assert_eq!(set.len(), 2); }
1307
1308 #[test]
1311 fn test_map_action_basic() {
1312 let mut input = InputManager::new();
1313
1314 input.map_action("Jump", InputBinding::Key(Key::Space));
1315 assert!(input.has_action("Jump"));
1316 assert_eq!(input.get_action_bindings("Jump").len(), 1);
1317 }
1318
1319 #[test]
1320 fn test_map_action_multiple_bindings() {
1321 let mut input = InputManager::new();
1322
1323 input.map_action("Jump", InputBinding::Key(Key::Space));
1324 input.map_action("Jump", InputBinding::Key(Key::W));
1325 input.map_action(
1326 "Jump",
1327 InputBinding::GamepadButton {
1328 gamepad_id: 0,
1329 button: 0,
1330 },
1331 );
1332
1333 let bindings = input.get_action_bindings("Jump");
1334 assert_eq!(bindings.len(), 3);
1335 }
1336
1337 #[test]
1338 fn test_unmap_action() {
1339 let mut input = InputManager::new();
1340 let binding = InputBinding::Key(Key::Space);
1341
1342 input.map_action("Jump", binding);
1343 assert_eq!(input.get_action_bindings("Jump").len(), 1);
1344
1345 assert!(input.unmap_action("Jump", binding));
1346 assert_eq!(input.get_action_bindings("Jump").len(), 0);
1347
1348 assert!(!input.unmap_action("Jump", binding));
1350 }
1351
1352 #[test]
1353 fn test_clear_action() {
1354 let mut input = InputManager::new();
1355
1356 input.map_action("Jump", InputBinding::Key(Key::Space));
1357 input.map_action("Jump", InputBinding::Key(Key::W));
1358
1359 assert!(input.clear_action("Jump"));
1360 assert!(!input.has_action("Jump"));
1361
1362 assert!(!input.clear_action("Jump"));
1364 }
1365
1366 #[test]
1367 fn test_clear_all_actions() {
1368 let mut input = InputManager::new();
1369
1370 input.map_action("Jump", InputBinding::Key(Key::Space));
1371 input.map_action("Attack", InputBinding::Key(Key::E));
1372 input.map_action("Defend", InputBinding::Key(Key::Q));
1373
1374 assert_eq!(input.action_count(), 3);
1375
1376 input.clear_all_actions();
1377 assert_eq!(input.action_count(), 0);
1378 assert!(!input.has_action("Jump"));
1379 assert!(!input.has_action("Attack"));
1380 assert!(!input.has_action("Defend"));
1381 }
1382
1383 #[test]
1384 fn test_get_action_bindings_nonexistent() {
1385 let input = InputManager::new();
1386 let bindings = input.get_action_bindings("NonExistent");
1387 assert_eq!(bindings.len(), 0);
1388 }
1389
1390 #[test]
1391 fn test_has_action() {
1392 let mut input = InputManager::new();
1393
1394 assert!(!input.has_action("Jump"));
1395
1396 input.map_action("Jump", InputBinding::Key(Key::Space));
1397 assert!(input.has_action("Jump"));
1398 }
1399
1400 #[test]
1401 fn test_action_names() {
1402 let mut input = InputManager::new();
1403
1404 input.map_action("Jump", InputBinding::Key(Key::Space));
1405 input.map_action("Attack", InputBinding::Key(Key::E));
1406
1407 let names: Vec<_> = input.action_names().collect();
1408 assert_eq!(names.len(), 2);
1409 assert!(names.contains(&"Jump"));
1410 assert!(names.contains(&"Attack"));
1411 }
1412
1413 #[test]
1414 fn test_action_count() {
1415 let mut input = InputManager::new();
1416
1417 assert_eq!(input.action_count(), 0);
1418
1419 input.map_action("Jump", InputBinding::Key(Key::Space));
1420 assert_eq!(input.action_count(), 1);
1421
1422 input.map_action("Attack", InputBinding::Key(Key::E));
1423 assert_eq!(input.action_count(), 2);
1424 }
1425
1426 #[test]
1427 fn test_action_pressed() {
1428 let mut input = InputManager::new();
1429
1430 input.map_action("Jump", InputBinding::Key(Key::Space));
1431 input.map_action("Jump", InputBinding::Key(Key::W));
1432
1433 assert!(!input.action_pressed("Jump"));
1435
1436 input.press_key(Key::Space);
1438 assert!(input.action_pressed("Jump"));
1439
1440 input.release_key(Key::Space);
1442 input.press_key(Key::W);
1443 assert!(input.action_pressed("Jump"));
1444
1445 input.press_key(Key::Space);
1447 assert!(input.action_pressed("Jump"));
1448
1449 input.release_key(Key::Space);
1451 input.release_key(Key::W);
1452 assert!(!input.action_pressed("Jump"));
1453 }
1454
1455 #[test]
1456 fn test_action_pressed_nonexistent() {
1457 let input = InputManager::new();
1458 assert!(!input.action_pressed("NonExistent"));
1459 }
1460
1461 #[test]
1462 fn test_action_just_pressed() {
1463 let mut input = InputManager::new();
1464
1465 input.map_action("Jump", InputBinding::Key(Key::Space));
1466
1467 input.press_key(Key::Space);
1469 assert!(input.action_just_pressed("Jump"));
1470
1471 input.update();
1473 assert!(!input.action_just_pressed("Jump")); }
1475
1476 #[test]
1477 fn test_action_just_released() {
1478 let mut input = InputManager::new();
1479
1480 input.map_action("Jump", InputBinding::Key(Key::Space));
1481
1482 input.press_key(Key::Space);
1484 input.update();
1485
1486 input.release_key(Key::Space);
1488 assert!(input.action_just_released("Jump"));
1489
1490 input.update();
1492 assert!(!input.action_just_released("Jump"));
1493 }
1494
1495 #[test]
1496 fn test_action_strength() {
1497 let mut input = InputManager::new();
1498
1499 input.map_action("Jump", InputBinding::Key(Key::Space));
1500
1501 assert_eq!(input.action_strength("Jump"), 0.0);
1503
1504 input.press_key(Key::Space);
1506 assert_eq!(input.action_strength("Jump"), 1.0);
1507 }
1508
1509 #[test]
1510 fn test_action_strength_nonexistent() {
1511 let input = InputManager::new();
1512 assert_eq!(input.action_strength("NonExistent"), 0.0);
1513 }
1514
1515 #[test]
1516 fn test_action_multiple_input_types() {
1517 let mut input = InputManager::new();
1518
1519 input.map_action("Fire", InputBinding::Key(Key::Space));
1521 input.map_action("Fire", InputBinding::MouseButton(MouseButton::Button1));
1522 input.map_action(
1523 "Fire",
1524 InputBinding::GamepadButton {
1525 gamepad_id: 0,
1526 button: 0,
1527 },
1528 );
1529
1530 input.press_key(Key::Space);
1532 assert!(input.action_pressed("Fire"));
1533 input.release_key(Key::Space);
1534 assert!(!input.action_pressed("Fire"));
1535
1536 input.press_mouse_button(MouseButton::Button1);
1538 assert!(input.action_pressed("Fire"));
1539 input.release_mouse_button(MouseButton::Button1);
1540 assert!(!input.action_pressed("Fire"));
1541
1542 input.press_gamepad_button(0, 0);
1544 assert!(input.action_pressed("Fire"));
1545 }
1546
1547 #[test]
1548 fn test_action_mapping_string_ownership() {
1549 let mut input = InputManager::new();
1550
1551 input.map_action("Jump", InputBinding::Key(Key::Space));
1553 assert!(input.has_action("Jump"));
1554
1555 let action_name = String::from("Attack");
1557 input.map_action(action_name.clone(), InputBinding::Key(Key::E));
1558 assert!(input.has_action(&action_name));
1559 }
1560
1561 #[test]
1562 fn test_action_mapping_persistence_across_update() {
1563 let mut input = InputManager::new();
1564
1565 input.map_action("Jump", InputBinding::Key(Key::Space));
1566
1567 input.update();
1569 assert!(input.has_action("Jump"));
1570
1571 input.update();
1572 assert!(input.has_action("Jump"));
1573 }
1574
1575 #[test]
1576 fn test_action_mapping_persistence_across_clear() {
1577 let mut input = InputManager::new();
1578
1579 input.map_action("Jump", InputBinding::Key(Key::Space));
1580
1581 input.clear();
1583 assert!(input.has_action("Jump"));
1584 }
1585
1586 #[test]
1589 fn test_with_buffer_duration() {
1590 let duration = Duration::from_millis(500);
1591 let input = InputManager::with_buffer_duration(duration);
1592 assert_eq!(input.buffer_duration(), duration);
1593 }
1594
1595 #[test]
1596 fn test_set_buffer_duration() {
1597 let mut input = InputManager::new();
1598 let new_duration = Duration::from_millis(300);
1599
1600 input.set_buffer_duration(new_duration);
1601 assert_eq!(input.buffer_duration(), new_duration);
1602 }
1603
1604 #[test]
1605 fn test_buffer_size() {
1606 let mut input = InputManager::new();
1607 assert_eq!(input.buffer_size(), 0);
1608
1609 input.press_key(Key::A);
1610 assert_eq!(input.buffer_size(), 1);
1611
1612 input.press_key(Key::B);
1613 assert_eq!(input.buffer_size(), 2);
1614 }
1615
1616 #[test]
1617 fn test_clear_buffer() {
1618 let mut input = InputManager::new();
1619
1620 input.press_key(Key::A);
1621 input.press_key(Key::B);
1622 assert_eq!(input.buffer_size(), 2);
1623
1624 input.clear_buffer();
1625 assert_eq!(input.buffer_size(), 0);
1626 }
1627
1628 #[test]
1629 fn test_buffer_only_new_presses() {
1630 let mut input = InputManager::new();
1631
1632 input.press_key(Key::A);
1634 assert_eq!(input.buffer_size(), 1);
1635
1636 input.press_key(Key::A);
1638 assert_eq!(input.buffer_size(), 1);
1639
1640 input.release_key(Key::A);
1642 input.press_key(Key::A);
1643 assert_eq!(input.buffer_size(), 2);
1644 }
1645
1646 #[test]
1647 fn test_sequence_detected_basic() {
1648 let mut input = InputManager::new();
1649
1650 input.press_key(Key::A);
1652 input.press_key(Key::B);
1653 input.press_key(Key::C);
1654
1655 let sequence = vec![
1656 InputBinding::Key(Key::A),
1657 InputBinding::Key(Key::B),
1658 InputBinding::Key(Key::C),
1659 ];
1660
1661 assert!(input.sequence_detected(&sequence));
1662 }
1663
1664 #[test]
1665 fn test_sequence_detected_wrong_order() {
1666 let mut input = InputManager::new();
1667
1668 input.press_key(Key::A);
1670 input.press_key(Key::C);
1671 input.press_key(Key::B);
1672
1673 let sequence = vec![
1674 InputBinding::Key(Key::A),
1675 InputBinding::Key(Key::B),
1676 InputBinding::Key(Key::C),
1677 ];
1678
1679 assert!(!input.sequence_detected(&sequence));
1680 }
1681
1682 #[test]
1683 fn test_sequence_detected_partial() {
1684 let mut input = InputManager::new();
1685
1686 input.press_key(Key::A);
1688 input.press_key(Key::B);
1689
1690 let sequence = vec![
1691 InputBinding::Key(Key::A),
1692 InputBinding::Key(Key::B),
1693 InputBinding::Key(Key::C),
1694 ];
1695
1696 assert!(!input.sequence_detected(&sequence));
1697 }
1698
1699 #[test]
1700 fn test_sequence_detected_empty() {
1701 let input = InputManager::new();
1702
1703 assert!(!input.sequence_detected(&[]));
1705 }
1706
1707 #[test]
1708 fn test_sequence_detected_with_extra_inputs() {
1709 let mut input = InputManager::new();
1710
1711 input.press_key(Key::A);
1713 input.press_key(Key::X); input.press_key(Key::B);
1715 input.press_key(Key::Y); input.press_key(Key::C);
1717
1718 let sequence = vec![
1719 InputBinding::Key(Key::A),
1720 InputBinding::Key(Key::B),
1721 InputBinding::Key(Key::C),
1722 ];
1723
1724 assert!(input.sequence_detected(&sequence));
1726 }
1727
1728 #[test]
1729 fn test_consume_sequence() {
1730 let mut input = InputManager::new();
1731
1732 input.press_key(Key::A);
1733 input.press_key(Key::B);
1734
1735 let sequence = vec![InputBinding::Key(Key::A), InputBinding::Key(Key::B)];
1736
1737 assert!(input.consume_sequence(&sequence));
1739 assert_eq!(input.buffer_size(), 0); assert!(!input.consume_sequence(&sequence));
1743 }
1744
1745 #[test]
1746 fn test_consume_sequence_not_detected() {
1747 let mut input = InputManager::new();
1748
1749 input.press_key(Key::A);
1750
1751 let sequence = vec![InputBinding::Key(Key::A), InputBinding::Key(Key::B)];
1752
1753 assert!(!input.consume_sequence(&sequence));
1755 assert_eq!(input.buffer_size(), 1); }
1757
1758 #[test]
1759 fn test_time_since_last_input() {
1760 let mut input = InputManager::new();
1761
1762 assert!(input.time_since_last_input().is_none());
1764
1765 input.press_key(Key::A);
1766
1767 let time = input.time_since_last_input();
1769 assert!(time.is_some());
1770 assert!(time.unwrap() < 0.1); }
1772
1773 #[test]
1774 fn test_buffered_inputs_iterator() {
1775 let mut input = InputManager::new();
1776
1777 input.press_key(Key::A);
1778 input.press_key(Key::B);
1779 input.press_key(Key::C);
1780
1781 let buffered: Vec<_> = input.buffered_inputs().collect();
1782 assert_eq!(buffered.len(), 3);
1783
1784 assert_eq!(buffered[0].0, InputBinding::Key(Key::A));
1786 assert_eq!(buffered[1].0, InputBinding::Key(Key::B));
1787 assert_eq!(buffered[2].0, InputBinding::Key(Key::C));
1788
1789 assert!(buffered[0].1 < 0.1);
1791 assert!(buffered[1].1 < 0.1);
1792 assert!(buffered[2].1 < 0.1);
1793 }
1794
1795 #[test]
1796 fn test_buffer_expiration() {
1797 use std::thread;
1798
1799 let mut input = InputManager::with_buffer_duration(Duration::from_millis(50));
1800
1801 input.press_key(Key::A);
1802 assert_eq!(input.buffer_size(), 1);
1803
1804 thread::sleep(Duration::from_millis(60));
1806
1807 input.update();
1809 assert_eq!(input.buffer_size(), 0);
1810 }
1811
1812 #[test]
1813 fn test_buffer_max_size() {
1814 let mut input = InputManager::new();
1815
1816 for i in 0..40 {
1818 input.press_key(Key::A);
1819 input.release_key(Key::A);
1820 }
1821
1822 assert!(input.buffer_size() <= 32);
1824 }
1825
1826 #[test]
1827 fn test_sequence_mixed_input_types() {
1828 let mut input = InputManager::new();
1829
1830 input.press_key(Key::A);
1832 input.press_mouse_button(MouseButton::Button1);
1833 input.press_gamepad_button(0, 5);
1834
1835 let sequence = vec![
1836 InputBinding::Key(Key::A),
1837 InputBinding::MouseButton(MouseButton::Button1),
1838 InputBinding::GamepadButton {
1839 gamepad_id: 0,
1840 button: 5,
1841 },
1842 ];
1843
1844 assert!(input.sequence_detected(&sequence));
1845 }
1846
1847 #[test]
1848 fn test_fighting_game_combo() {
1849 let mut input = InputManager::new();
1850
1851 input.press_key(Key::Down);
1853 input.release_key(Key::Down); input.press_key(Key::Down); input.press_key(Key::Right);
1856 input.press_key(Key::Space);
1857
1858 let hadouken = vec![
1859 InputBinding::Key(Key::Down),
1860 InputBinding::Key(Key::Down),
1861 InputBinding::Key(Key::Right),
1862 InputBinding::Key(Key::Space),
1863 ];
1864
1865 assert!(input.sequence_detected(&hadouken));
1866 }
1867
1868 #[test]
1869 fn test_sequence_persistence_across_update() {
1870 let mut input = InputManager::new();
1871
1872 input.press_key(Key::A);
1873 input.press_key(Key::B);
1874
1875 input.update();
1877
1878 let sequence = vec![InputBinding::Key(Key::A), InputBinding::Key(Key::B)];
1879 assert!(input.sequence_detected(&sequence));
1880 }
1881
1882 #[test]
1883 fn test_buffer_not_cleared_by_state_clear() {
1884 let mut input = InputManager::new();
1885
1886 input.press_key(Key::A);
1887 assert_eq!(input.buffer_size(), 1);
1888
1889 input.clear();
1891 assert_eq!(input.buffer_size(), 1);
1892 }
1893
1894 #[test]
1895 fn test_double_tap_detection() {
1896 let mut input = InputManager::new();
1897
1898 input.press_key(Key::W);
1900 input.release_key(Key::W);
1901 input.press_key(Key::W);
1902
1903 let double_tap = vec![InputBinding::Key(Key::W), InputBinding::Key(Key::W)];
1904
1905 assert!(input.sequence_detected(&double_tap));
1906 }
1907
1908 #[test]
1911 fn test_gamepad_axis_basic() {
1912 let mut input = InputManager::new();
1913
1914 assert_eq!(input.gamepad_axis(0, GamepadAxis::AxisLeftX), 0.0);
1916
1917 input.set_gamepad_axis(0, GamepadAxis::AxisLeftX, 0.5);
1919 assert_eq!(input.gamepad_axis(0, GamepadAxis::AxisLeftX), 0.5);
1920
1921 input.set_gamepad_axis(0, GamepadAxis::AxisLeftY, -0.75);
1923 assert_eq!(input.gamepad_axis(0, GamepadAxis::AxisLeftY), -0.75);
1924 }
1925
1926 #[test]
1927 fn test_gamepad_axis_deadzone() {
1928 let mut input = InputManager::new();
1929
1930 assert_eq!(input.analog_deadzone(), 0.1);
1932
1933 input.set_gamepad_axis(0, GamepadAxis::AxisLeftX, 0.05);
1935 assert_eq!(input.gamepad_axis(0, GamepadAxis::AxisLeftX), 0.0);
1936
1937 input.set_gamepad_axis(0, GamepadAxis::AxisLeftX, 0.15);
1939 assert_eq!(input.gamepad_axis(0, GamepadAxis::AxisLeftX), 0.15);
1940 }
1941
1942 #[test]
1943 fn test_set_analog_deadzone() {
1944 let mut input = InputManager::new();
1945
1946 input.set_analog_deadzone(0.2);
1948 assert_eq!(input.analog_deadzone(), 0.2);
1949
1950 input.set_gamepad_axis(0, GamepadAxis::AxisLeftX, 0.15);
1952 assert_eq!(input.gamepad_axis(0, GamepadAxis::AxisLeftX), 0.0);
1953
1954 input.set_gamepad_axis(0, GamepadAxis::AxisLeftX, 0.25);
1956 assert_eq!(input.gamepad_axis(0, GamepadAxis::AxisLeftX), 0.25);
1957 }
1958
1959 #[test]
1960 fn test_gamepad_left_stick() {
1961 let mut input = InputManager::new();
1962
1963 assert_eq!(input.gamepad_left_stick(0), Vec2::zero());
1965
1966 input.set_gamepad_axis(0, GamepadAxis::AxisLeftX, 0.8);
1968 input.set_gamepad_axis(0, GamepadAxis::AxisLeftY, -0.6);
1969
1970 let stick = input.gamepad_left_stick(0);
1971 assert_eq!(stick.x, 0.8);
1972 assert_eq!(stick.y, -0.6);
1973 }
1974
1975 #[test]
1976 fn test_gamepad_right_stick() {
1977 let mut input = InputManager::new();
1978
1979 input.set_gamepad_axis(0, GamepadAxis::AxisRightX, -0.5);
1981 input.set_gamepad_axis(0, GamepadAxis::AxisRightY, 0.3);
1982
1983 let stick = input.gamepad_right_stick(0);
1984 assert_eq!(stick.x, -0.5);
1985 assert_eq!(stick.y, 0.3);
1986 }
1987
1988 #[test]
1989 fn test_gamepad_triggers() {
1990 let mut input = InputManager::new();
1991
1992 input.set_gamepad_axis(0, GamepadAxis::AxisLeftTrigger, -1.0);
1995 assert_eq!(input.gamepad_left_trigger(0), 0.0);
1996
1997 input.set_gamepad_axis(0, GamepadAxis::AxisLeftTrigger, 1.0);
1998 assert_eq!(input.gamepad_left_trigger(0), 1.0);
1999
2000 input.set_gamepad_axis(0, GamepadAxis::AxisLeftTrigger, 0.0);
2002 assert_eq!(input.gamepad_left_trigger(0), 0.5);
2003
2004 input.set_gamepad_axis(0, GamepadAxis::AxisRightTrigger, 0.5);
2006 assert_eq!(input.gamepad_right_trigger(0), 0.75);
2007 }
2008
2009 #[test]
2010 fn test_gamepad_axis_nonexistent_gamepad() {
2011 let input = InputManager::new();
2012
2013 assert_eq!(input.gamepad_axis(10, GamepadAxis::AxisLeftX), 0.0);
2015 assert_eq!(input.gamepad_left_stick(10), Vec2::zero());
2016
2017 assert_eq!(input.gamepad_left_trigger(10), 0.5);
2020 assert_eq!(input.gamepad_right_trigger(10), 0.5);
2021 }
2022
2023 #[test]
2026 fn test_gamepad_connection() {
2027 let mut input = InputManager::new();
2028
2029 assert!(!input.is_gamepad_connected(0));
2031 assert_eq!(input.connected_gamepad_count(), 0);
2032
2033 input.set_gamepad_connected(0, true);
2035 assert!(input.is_gamepad_connected(0));
2036 assert_eq!(input.connected_gamepad_count(), 1);
2037
2038 input.set_gamepad_connected(1, true);
2040 assert!(input.is_gamepad_connected(1));
2041 assert_eq!(input.connected_gamepad_count(), 2);
2042
2043 input.set_gamepad_connected(0, false);
2045 assert!(!input.is_gamepad_connected(0));
2046 assert!(input.is_gamepad_connected(1));
2047 assert_eq!(input.connected_gamepad_count(), 1);
2048 }
2049
2050 #[test]
2051 fn test_connected_gamepads_iterator() {
2052 let mut input = InputManager::new();
2053
2054 input.set_gamepad_connected(0, true);
2055 input.set_gamepad_connected(2, true);
2056 input.set_gamepad_connected(4, true);
2057
2058 let connected: Vec<_> = input.connected_gamepads().collect();
2059 assert_eq!(connected.len(), 3);
2060 assert!(connected.contains(&0));
2061 assert!(connected.contains(&2));
2062 assert!(connected.contains(&4));
2063 }
2064
2065 #[test]
2066 fn test_gamepad_connection_nonexistent() {
2067 let input = InputManager::new();
2068
2069 assert!(!input.is_gamepad_connected(10));
2071 }
2072
2073 #[test]
2076 fn test_gamepad_vibration() {
2077 let mut input = InputManager::new();
2078
2079 assert_eq!(input.gamepad_vibration(0), 0.0);
2081
2082 input.set_gamepad_vibration(0, 0.75);
2084 assert_eq!(input.gamepad_vibration(0), 0.75);
2085
2086 input.set_gamepad_vibration(0, 1.5);
2088 assert_eq!(input.gamepad_vibration(0), 1.0);
2089
2090 input.set_gamepad_vibration(0, -0.5);
2091 assert_eq!(input.gamepad_vibration(0), 0.0);
2092 }
2093
2094 #[test]
2095 fn test_stop_gamepad_vibration() {
2096 let mut input = InputManager::new();
2097
2098 input.set_gamepad_vibration(0, 0.8);
2099 assert_eq!(input.gamepad_vibration(0), 0.8);
2100
2101 input.stop_gamepad_vibration(0);
2102 assert_eq!(input.gamepad_vibration(0), 0.0);
2103 }
2104
2105 #[test]
2106 fn test_stop_all_vibration() {
2107 let mut input = InputManager::new();
2108
2109 input.set_gamepad_vibration(0, 0.5);
2110 input.set_gamepad_vibration(1, 0.7);
2111 input.set_gamepad_vibration(2, 0.9);
2112
2113 input.stop_all_vibration();
2114
2115 assert_eq!(input.gamepad_vibration(0), 0.0);
2116 assert_eq!(input.gamepad_vibration(1), 0.0);
2117 assert_eq!(input.gamepad_vibration(2), 0.0);
2118 }
2119
2120 #[test]
2123 fn test_gamepad_state_clear_preserves_connection() {
2124 let mut input = InputManager::new();
2125
2126 input.set_gamepad_connected(0, true);
2128 input.set_gamepad_axis(0, GamepadAxis::AxisLeftX, 0.5);
2129 input.press_gamepad_button(0, 1);
2130 input.set_gamepad_vibration(0, 0.8);
2131
2132 input.clear();
2134
2135 assert!(input.is_gamepad_connected(0)); assert_eq!(input.gamepad_vibration(0), 0.8); assert_eq!(input.gamepad_axis(0, GamepadAxis::AxisLeftX), 0.0); assert!(!input.gamepad_button_pressed(0, 1)); }
2140
2141 #[test]
2142 fn test_gamepad_multiple_gamepads_axes() {
2143 let mut input = InputManager::new();
2144
2145 input.set_gamepad_axis(0, GamepadAxis::AxisLeftX, 0.5);
2147 input.set_gamepad_axis(1, GamepadAxis::AxisLeftX, -0.5);
2148 input.press_gamepad_button(0, 1);
2149 input.press_gamepad_button(1, 2);
2150
2151 assert_eq!(input.gamepad_axis(0, GamepadAxis::AxisLeftX), 0.5);
2153 assert_eq!(input.gamepad_axis(1, GamepadAxis::AxisLeftX), -0.5);
2154 assert!(input.gamepad_button_pressed(0, 1));
2155 assert!(!input.gamepad_button_pressed(0, 2));
2156 assert!(input.gamepad_button_pressed(1, 2));
2157 assert!(!input.gamepad_button_pressed(1, 1));
2158 }
2159
2160 #[test]
2161 fn test_gamepad_axes_update_persistence() {
2162 let mut input = InputManager::new();
2163
2164 input.set_gamepad_axis(0, GamepadAxis::AxisLeftX, 0.8);
2165
2166 input.update();
2168 assert_eq!(input.gamepad_axis(0, GamepadAxis::AxisLeftX), 0.8);
2169
2170 input.update();
2171 assert_eq!(input.gamepad_axis(0, GamepadAxis::AxisLeftX), 0.8);
2172 }
2173
2174 #[test]
2175 fn test_gamepad_stick_magnitude() {
2176 let mut input = InputManager::new();
2177
2178 input.set_gamepad_axis(0, GamepadAxis::AxisLeftX, 0.6);
2180 input.set_gamepad_axis(0, GamepadAxis::AxisLeftY, 0.8);
2181
2182 let stick = input.gamepad_left_stick(0);
2183 let magnitude = (stick.x * stick.x + stick.y * stick.y).sqrt();
2184
2185 assert!((magnitude - 1.0).abs() < 0.01);
2187 }
2188
2189 #[test]
2190 fn test_gamepad_expansion() {
2191 let mut input = InputManager::new();
2192
2193 input.set_gamepad_axis(10, GamepadAxis::AxisLeftX, 0.5);
2195 assert_eq!(input.gamepad_axis(10, GamepadAxis::AxisLeftX), 0.5);
2196
2197 input.set_gamepad_connected(10, true);
2198 assert!(input.is_gamepad_connected(10));
2199 }
2200}