1use crate::buttonlike::ButtonValue;
4use crate::input_map::UpdatedValue;
5use crate::{Actionlike, InputControlKind};
6use crate::{action_diff::ActionDiff, input_map::UpdatedActions};
7
8use bevy::math::{Vec2, Vec3};
9use bevy::platform::{collections::HashMap, time::Instant};
10use bevy::prelude::Component;
11use bevy::prelude::ReflectComponent;
12use bevy::reflect::Reflect;
13#[cfg(feature = "timing")]
14use core::time::Duration;
15use serde::{Deserialize, Serialize};
16
17mod action_data;
18pub use action_data::*;
19
20#[derive(Component, Clone, Debug, PartialEq, Serialize, Deserialize, Reflect)]
87#[reflect(Component)]
88pub struct ActionState<A: Actionlike> {
89 disabled: bool,
91 action_data: HashMap<A, ActionData>,
93}
94
95impl<A: Actionlike> Default for ActionState<A> {
98 fn default() -> Self {
99 Self {
100 disabled: false,
101 action_data: HashMap::default(),
102 }
103 }
104}
105
106impl<A: Actionlike> ActionState<A> {
107 #[inline]
109 #[must_use]
110 pub fn all_action_data(&self) -> &HashMap<A, ActionData> {
111 &self.action_data
112 }
113
114 pub(crate) fn swap_to_update_state(&mut self) {
118 for action_datum in self.action_data.values_mut() {
119 action_datum.kind_data.swap_to_update_state();
120 }
121 }
122
123 pub(crate) fn swap_to_fixed_update_state(&mut self) {
127 for action_datum in self.action_data.values_mut() {
128 action_datum.kind_data.swap_to_fixed_update_state();
129 }
130 }
131
132 pub fn set_update_state_from_state(&mut self) {
134 for action_datum in self.action_data.values_mut() {
135 action_datum.kind_data.set_update_state_from_state();
136 }
137 }
138
139 pub fn set_fixed_update_state_from_state(&mut self) {
141 for action_datum in self.action_data.values_mut() {
142 action_datum.kind_data.set_fixed_update_state_from_state();
143 }
144 }
145
146 pub fn update(&mut self, updated_actions: UpdatedActions<A>) {
153 for (action, action_data) in self.action_data.iter_mut() {
155 if updated_actions.contains_key(action) {
156 continue;
157 }
158 match action_data.kind_data {
159 ActionKindData::Button(_) => {}
160 ActionKindData::Axis(ref mut data) => {
161 data.value = 0.0;
162 }
163 ActionKindData::DualAxis(ref mut data) => {
164 data.pair = Vec2::ZERO;
165 }
166 ActionKindData::TripleAxis(ref mut data) => {
167 data.triple = Vec3::ZERO;
168 }
169 }
170 }
171
172 for (action, updated_value) in updated_actions.iter() {
173 match updated_value {
174 UpdatedValue::Button(ButtonValue { pressed, value }) => {
175 if *pressed {
176 self.press(action);
177 } else {
178 self.release(action);
179 }
180 self.set_button_value(action, *value);
181 }
182 UpdatedValue::Axis(value) => {
183 self.set_value(action, *value);
184 }
185 UpdatedValue::DualAxis(pair) => {
186 self.set_axis_pair(action, *pair);
187 }
188 UpdatedValue::TripleAxis(triple) => {
189 self.set_axis_triple(action, *triple);
190 }
191 }
192 }
193 }
194
195 pub fn tick(&mut self, _current_instant: Instant, _previous_instant: Instant) {
241 self.action_data
243 .values_mut()
244 .for_each(|action_datum| action_datum.tick(_current_instant, _previous_instant));
245 }
246
247 #[inline]
249 #[must_use]
250 pub fn action_data(&self, action: &A) -> Option<&ActionData> {
251 self.action_data.get(action)
252 }
253
254 #[inline]
259 #[must_use]
260 pub fn action_data_mut(&mut self, action: &A) -> Option<&mut ActionData> {
261 self.action_data.get_mut(action)
262 }
263
264 pub fn action_data_mut_or_default(&mut self, action: &A) -> &mut ActionData {
270 if self.action_data.contains_key(action) {
271 self.action_data.get_mut(action).unwrap()
273 } else {
274 self.action_data.insert(
275 action.clone(),
276 ActionData::from_kind(action.input_control_kind()),
277 );
278 self.action_data_mut(action).unwrap()
280 }
281 }
282
283 #[inline]
298 #[must_use]
299 pub fn button_data(&self, action: &A) -> Option<&ButtonData> {
300 match self.action_data(action) {
301 Some(action_data) => match action_data.kind_data {
302 ActionKindData::Button(ref button_data) => Some(button_data),
303 _ => None,
304 },
305 None => None,
306 }
307 }
308
309 #[inline]
327 #[must_use]
328 pub fn button_data_mut(&mut self, action: &A) -> Option<&mut ButtonData> {
329 match self.action_data_mut(action) {
330 Some(action_data) => match &mut action_data.kind_data {
331 ActionKindData::Button(button_data) => Some(button_data),
332 _ => None,
333 },
334 None => None,
335 }
336 }
337
338 #[inline]
347 #[must_use]
348 #[track_caller]
349 pub fn button_data_mut_or_default(&mut self, action: &A) -> &mut ButtonData {
350 debug_assert_eq!(action.input_control_kind(), InputControlKind::Button);
351
352 let action_data = self.action_data_mut_or_default(action);
353 let ActionKindData::Button(ref mut button_data) = action_data.kind_data else {
354 panic!("{action:?} is not a Button");
355 };
356 button_data
357 }
358
359 #[inline]
371 #[must_use]
372 #[track_caller]
373 pub fn axis_data(&self, action: &A) -> Option<&AxisData> {
374 debug_assert_eq!(action.input_control_kind(), InputControlKind::Axis);
375
376 match self.action_data(action) {
377 Some(action_data) => match action_data.kind_data {
378 ActionKindData::Axis(ref axis_data) => Some(axis_data),
379 _ => None,
380 },
381 None => None,
382 }
383 }
384
385 #[inline]
397 #[must_use]
398 pub fn axis_data_mut(&mut self, action: &A) -> Option<&mut AxisData> {
399 match self.action_data_mut(action) {
400 Some(action_data) => match &mut action_data.kind_data {
401 ActionKindData::Axis(axis_data) => Some(axis_data),
402 _ => None,
403 },
404 None => None,
405 }
406 }
407
408 #[inline]
417 #[must_use]
418 #[track_caller]
419 pub fn axis_data_mut_or_default(&mut self, action: &A) -> &mut AxisData {
420 debug_assert_eq!(action.input_control_kind(), InputControlKind::Axis);
421
422 let action_data = self.action_data_mut_or_default(action);
423 let ActionKindData::Axis(ref mut axis_data) = action_data.kind_data else {
424 panic!("{action:?} is not an Axis");
425 };
426 axis_data
427 }
428
429 #[inline]
441 #[must_use]
442 #[track_caller]
443 pub fn dual_axis_data(&self, action: &A) -> Option<&DualAxisData> {
444 debug_assert_eq!(action.input_control_kind(), InputControlKind::DualAxis);
445
446 match self.action_data(action) {
447 Some(action_data) => match action_data.kind_data {
448 ActionKindData::DualAxis(ref dual_axis_data) => Some(dual_axis_data),
449 _ => None,
450 },
451 None => None,
452 }
453 }
454
455 #[inline]
467 #[must_use]
468 #[track_caller]
469 pub fn dual_axis_data_mut(&mut self, action: &A) -> Option<&mut DualAxisData> {
470 debug_assert_eq!(action.input_control_kind(), InputControlKind::DualAxis);
471
472 match self.action_data_mut(action) {
473 Some(action_data) => match &mut action_data.kind_data {
474 ActionKindData::DualAxis(dual_axis_data) => Some(dual_axis_data),
475 _ => None,
476 },
477 None => None,
478 }
479 }
480
481 #[inline]
490 #[must_use]
491 #[track_caller]
492 pub fn dual_axis_data_mut_or_default(&mut self, action: &A) -> &mut DualAxisData {
493 debug_assert_eq!(action.input_control_kind(), InputControlKind::DualAxis);
494
495 let action_data = self.action_data_mut_or_default(action);
496 let ActionKindData::DualAxis(ref mut dual_axis_data) = action_data.kind_data else {
497 panic!("{action:?} is not a DualAxis");
498 };
499 dual_axis_data
500 }
501
502 #[inline]
514 #[must_use]
515 #[track_caller]
516 pub fn triple_axis_data(&self, action: &A) -> Option<&TripleAxisData> {
517 debug_assert_eq!(action.input_control_kind(), InputControlKind::TripleAxis);
518
519 match self.action_data(action) {
520 Some(action_data) => match action_data.kind_data {
521 ActionKindData::TripleAxis(ref triple_axis_data) => Some(triple_axis_data),
522 _ => None,
523 },
524 None => None,
525 }
526 }
527
528 #[inline]
540 #[must_use]
541 #[track_caller]
542 pub fn triple_axis_data_mut(&mut self, action: &A) -> Option<&mut TripleAxisData> {
543 debug_assert_eq!(action.input_control_kind(), InputControlKind::TripleAxis);
544
545 match self.action_data_mut(action) {
546 Some(action_data) => match &mut action_data.kind_data {
547 ActionKindData::TripleAxis(triple_axis_data) => Some(triple_axis_data),
548 _ => None,
549 },
550 None => None,
551 }
552 }
553
554 #[inline]
563 #[must_use]
564 #[track_caller]
565 pub fn triple_axis_data_mut_or_default(&mut self, action: &A) -> &mut TripleAxisData {
566 debug_assert_eq!(action.input_control_kind(), InputControlKind::TripleAxis);
567
568 let action_data = self.action_data_mut_or_default(action);
569 let ActionKindData::TripleAxis(ref mut triple_axis_data) = action_data.kind_data else {
570 panic!("{action:?} is not a TripleAxis");
571 };
572 triple_axis_data
573 }
574
575 #[inline]
583 #[must_use]
584 #[track_caller]
585 pub fn button_value(&self, action: &A) -> f32 {
586 debug_assert_eq!(action.input_control_kind(), InputControlKind::Button);
587
588 if self.action_disabled(action) {
589 return 0.0;
590 }
591
592 let action_data = self.button_data(action);
593 action_data.map_or(0.0, |action_data| action_data.value)
594 }
595
596 #[track_caller]
606 pub fn set_button_value(&mut self, action: &A, value: f32) {
607 debug_assert_eq!(action.input_control_kind(), InputControlKind::Button);
608 const BUTTON_PRESS_THRESHOLD: f32 = 0.02;
609
610 let button_data = self.button_data_mut_or_default(action);
611 button_data.value = value;
612
613 if value > BUTTON_PRESS_THRESHOLD {
614 #[cfg(feature = "timing")]
615 if button_data.state.released() {
616 button_data.timing.flip();
617 }
618
619 button_data.state.press();
620 } else {
621 #[cfg(feature = "timing")]
622 if button_data.state.pressed() {
623 button_data.timing.flip();
624 }
625
626 button_data.state.release();
627 }
628 }
629
630 pub fn clamped_button_value(&self, action: &A) -> f32 {
637 self.button_value(action).clamp(0., 1.)
638 }
639
640 #[inline]
648 #[must_use]
649 #[track_caller]
650 pub fn value(&self, action: &A) -> f32 {
651 debug_assert_eq!(action.input_control_kind(), InputControlKind::Axis);
652
653 if self.action_disabled(action) {
654 return 0.0;
655 }
656
657 let action_data = self.axis_data(action);
658 action_data.map_or(0.0, |action_data| action_data.value)
659 }
660
661 #[track_caller]
663 pub fn set_value(&mut self, action: &A, value: f32) {
664 debug_assert_eq!(action.input_control_kind(), InputControlKind::Axis);
665
666 let axis_data = self.axis_data_mut_or_default(action);
667 axis_data.value = value;
668 }
669
670 pub fn clamped_value(&self, action: &A) -> f32 {
677 self.value(action).clamp(-1., 1.)
678 }
679
680 #[must_use]
697 #[track_caller]
698 pub fn axis_pair(&self, action: &A) -> Vec2 {
699 debug_assert_eq!(action.input_control_kind(), InputControlKind::DualAxis);
700
701 if self.action_disabled(action) {
702 return Vec2::ZERO;
703 }
704
705 let action_data = self.dual_axis_data(action);
706 action_data.map_or(Vec2::ZERO, |action_data| action_data.pair)
707 }
708
709 #[track_caller]
711 pub fn set_axis_pair(&mut self, action: &A, pair: Vec2) {
712 debug_assert_eq!(action.input_control_kind(), InputControlKind::DualAxis);
713
714 let dual_axis_data = self.dual_axis_data_mut_or_default(action);
715 dual_axis_data.pair = pair;
716 }
717
718 pub fn clamped_axis_pair(&self, action: &A) -> Vec2 {
725 let pair = self.axis_pair(action);
726 pair.clamp(Vec2::NEG_ONE, Vec2::ONE)
727 }
728
729 #[must_use]
746 #[track_caller]
747 pub fn axis_triple(&self, action: &A) -> Vec3 {
748 debug_assert_eq!(action.input_control_kind(), InputControlKind::TripleAxis);
749
750 if self.action_disabled(action) {
751 return Vec3::ZERO;
752 }
753
754 let action_data = self.triple_axis_data(action);
755 action_data.map_or(Vec3::ZERO, |action_data| action_data.triple)
756 }
757
758 #[track_caller]
760 pub fn set_axis_triple(&mut self, action: &A, triple: Vec3) {
761 debug_assert_eq!(action.input_control_kind(), InputControlKind::TripleAxis);
762
763 let triple_axis_data = self.triple_axis_data_mut_or_default(action);
764 triple_axis_data.triple = triple;
765 }
766
767 pub fn clamped_axis_triple(&self, action: &A) -> Vec3 {
774 let triple = self.axis_triple(action);
775 triple.clamp(Vec3::NEG_ONE, Vec3::ONE)
776 }
777
778 #[inline]
815 #[track_caller]
816 pub fn set_button_data(&mut self, action: A, data: ButtonData) {
817 debug_assert_eq!(action.input_control_kind(), InputControlKind::Button);
818
819 let button_data = self.button_data_mut_or_default(&action);
820 *button_data = data;
821 }
822
823 #[inline]
828 #[track_caller]
829 pub fn press(&mut self, action: &A) {
830 debug_assert_eq!(action.input_control_kind(), InputControlKind::Button);
831
832 let action_data = self.button_data_mut_or_default(action);
833
834 #[cfg(feature = "timing")]
835 if action_data.update_state.released() {
836 action_data.timing.flip();
837 }
838
839 action_data.state.press();
840 action_data.value = 1.0;
841 }
842
843 #[inline]
848 pub fn release(&mut self, action: &A) {
849 debug_assert_eq!(action.input_control_kind(), InputControlKind::Button);
850
851 let action_data = self.button_data_mut_or_default(action);
852
853 #[cfg(feature = "timing")]
854 if action_data.update_state.pressed() {
855 action_data.timing.flip();
856 }
857
858 action_data.state.release();
859 action_data.value = 0.0;
860 }
861
862 pub fn reset(&mut self, action: &A) {
866 match action.input_control_kind() {
867 InputControlKind::Button => self.release(action),
868 InputControlKind::Axis => {
869 self.set_value(action, 0.0);
870 }
871 InputControlKind::DualAxis => {
872 self.set_axis_pair(action, Vec2::ZERO);
873 }
874 InputControlKind::TripleAxis => {
875 self.set_axis_triple(action, Vec3::ZERO);
876 }
877 }
878 }
879
880 pub fn reset_all(&mut self) {
885 let all_actions = self.action_data.keys().cloned().collect::<Vec<A>>();
887 for action in all_actions.into_iter() {
888 self.reset(&action);
889 }
890 }
891
892 pub fn disabled(&self) -> bool {
894 self.disabled
895 }
896
897 #[inline]
899 #[must_use]
900 pub fn action_disabled(&self, action: &A) -> bool {
901 if self.disabled {
902 return true;
903 }
904
905 match self.action_data(action) {
906 Some(action_data) => action_data.disabled,
907 None => false,
908 }
909 }
910
911 #[inline]
915 pub fn disable(&mut self) {
916 self.disabled = true;
917 self.reset_all();
918 }
919
920 #[inline]
924 pub fn disable_action(&mut self, action: &A) {
925 let action_data = self.action_data_mut_or_default(action);
926
927 action_data.disabled = true;
928 self.reset(action);
929 }
930
931 #[inline]
933 pub fn disable_all_actions(&mut self) {
934 for action in self.keys() {
935 self.disable_action(&action);
936 }
937 }
938
939 #[inline]
941 pub fn enable(&mut self) {
942 self.disabled = false;
943 }
944
945 #[inline]
947 pub fn enable_action(&mut self, action: &A) {
948 let action_data = self.action_data_mut_or_default(action);
949
950 action_data.disabled = false;
951 }
952
953 #[inline]
955 pub fn enable_all_actions(&mut self) {
956 for action in self.keys() {
957 self.enable_action(&action);
958 }
959 }
960
961 #[inline]
968 #[must_use]
969 #[track_caller]
970 pub fn pressed(&self, action: &A) -> bool {
971 debug_assert_eq!(action.input_control_kind(), InputControlKind::Button);
972
973 if self.action_disabled(action) {
974 return false;
975 }
976
977 match self.button_data(action) {
978 Some(button_data) => button_data.pressed(),
979 None => false,
980 }
981 }
982
983 #[inline]
990 #[must_use]
991 #[track_caller]
992 pub fn just_pressed(&self, action: &A) -> bool {
993 debug_assert_eq!(action.input_control_kind(), InputControlKind::Button);
994
995 if self.action_disabled(action) {
996 return false;
997 }
998
999 match self.button_data(action) {
1000 Some(button_data) => button_data.just_pressed(),
1001 None => false,
1002 }
1003 }
1004
1005 #[inline]
1014 #[must_use]
1015 #[track_caller]
1016 pub fn released(&self, action: &A) -> bool {
1017 debug_assert_eq!(action.input_control_kind(), InputControlKind::Button);
1018
1019 if self.action_disabled(action) {
1020 return true;
1021 }
1022
1023 match self.button_data(action) {
1024 Some(button_data) => button_data.released(),
1025 None => true,
1026 }
1027 }
1028
1029 #[inline]
1036 #[must_use]
1037 #[track_caller]
1038 pub fn just_released(&self, action: &A) -> bool {
1039 debug_assert_eq!(action.input_control_kind(), InputControlKind::Button);
1040
1041 if self.action_disabled(action) {
1042 return false;
1043 }
1044
1045 match self.button_data(action) {
1046 Some(button_data) => button_data.just_released(),
1047 None => false,
1048 }
1049 }
1050
1051 #[must_use]
1052 pub fn get_pressed(&self) -> Vec<A> {
1054 let all_actions = self.action_data.keys().cloned();
1055
1056 all_actions
1057 .into_iter()
1058 .filter(|action| action.input_control_kind() == InputControlKind::Button)
1059 .filter(|action| self.pressed(action))
1060 .collect()
1061 }
1062
1063 #[must_use]
1064 pub fn get_just_pressed(&self) -> Vec<A> {
1066 let all_actions = self.action_data.keys().cloned();
1067
1068 all_actions
1069 .into_iter()
1070 .filter(|action| action.input_control_kind() == InputControlKind::Button)
1071 .filter(|action| self.just_pressed(action))
1072 .collect()
1073 }
1074
1075 #[must_use]
1076 pub fn get_released(&self) -> Vec<A> {
1078 let all_actions = self.action_data.keys().cloned();
1079
1080 all_actions
1081 .into_iter()
1082 .filter(|action| action.input_control_kind() == InputControlKind::Button)
1083 .filter(|action| self.released(action))
1084 .collect()
1085 }
1086
1087 #[must_use]
1088 pub fn get_just_released(&self) -> Vec<A> {
1090 let all_actions = self.action_data.keys().cloned();
1091
1092 all_actions
1093 .into_iter()
1094 .filter(|action| action.input_control_kind() == InputControlKind::Button)
1095 .filter(|action| self.just_released(action))
1096 .collect()
1097 }
1098
1099 #[cfg(feature = "timing")]
1110 #[must_use]
1111 #[track_caller]
1112 pub fn instant_started(&self, action: &A) -> Option<Instant> {
1113 debug_assert_eq!(action.input_control_kind(), InputControlKind::Button);
1114
1115 let button_data = self.button_data(action)?;
1116 button_data.timing.instant_started
1117 }
1118
1119 #[cfg(feature = "timing")]
1123 #[must_use]
1124 #[track_caller]
1125 pub fn current_duration(&self, action: &A) -> Duration {
1126 debug_assert_eq!(action.input_control_kind(), InputControlKind::Button);
1127
1128 self.button_data(action)
1129 .map(|data| data.timing.current_duration)
1130 .unwrap_or_default()
1131 }
1132
1133 #[cfg(feature = "timing")]
1140 #[must_use]
1141 #[track_caller]
1142 pub fn previous_duration(&self, action: &A) -> Duration {
1143 debug_assert_eq!(action.input_control_kind(), InputControlKind::Button);
1144
1145 self.button_data(action)
1146 .map(|data| data.timing.previous_duration)
1147 .unwrap_or_default()
1148 }
1149
1150 pub fn apply_diff(&mut self, action_diff: &ActionDiff<A>) {
1154 match action_diff {
1155 ActionDiff::Pressed { action, value } => {
1156 self.set_button_value(action, *value);
1157 }
1158 ActionDiff::Released { action } => {
1159 self.release(action);
1160 }
1161 ActionDiff::AxisChanged { action, value } => {
1162 self.set_value(action, *value);
1163 }
1164 ActionDiff::DualAxisChanged { action, axis_pair } => {
1165 self.set_axis_pair(action, *axis_pair);
1166 }
1167 ActionDiff::TripleAxisChanged {
1168 action,
1169 axis_triple,
1170 } => {
1171 self.set_axis_triple(action, *axis_triple);
1172 }
1173 };
1174 }
1175
1176 #[inline]
1178 #[must_use]
1179 pub fn keys(&self) -> Vec<A> {
1180 self.action_data.keys().cloned().collect()
1181 }
1182}
1183
1184#[cfg(test)]
1185mod tests {
1186 use crate as leafwing_input_manager;
1187 use crate::action_diff::ActionDiff;
1188 use crate::action_state::{
1189 ActionData, ActionKindData, ActionState, AxisData, ButtonData, DualAxisData,
1190 };
1191 use crate::buttonlike::{ButtonState, ButtonValue};
1192 use crate::input_map::UpdatedActions;
1193 #[cfg(any(feature = "gamepad", feature = "keyboard"))]
1194 use crate::prelude::{ButtonlikeChord, InputMap};
1195 #[cfg(feature = "gamepad")]
1196 use bevy::input::gamepad::GamepadButton;
1197 #[cfg(feature = "keyboard")]
1198 use bevy::input::keyboard::KeyCode;
1199 use bevy::platform::collections::HashMap;
1200 use bevy::prelude::*;
1201 use leafwing_input_manager_macros::Actionlike;
1202
1203 #[derive(Actionlike, Clone, Copy, PartialEq, Eq, Hash, Debug, Reflect)]
1204 enum TestAction {
1205 Trigger,
1206 Run,
1207 Jump,
1208 Hide,
1209 One,
1210 Two,
1211 OneAndTwo,
1212 #[actionlike(Axis)]
1213 Axis,
1214 #[actionlike(DualAxis)]
1215 DualAxis,
1216 #[actionlike(TripleAxis)]
1217 TripleAxis,
1218 }
1219
1220 #[cfg(any(feature = "keyboard", feature = "gamepad"))]
1221 struct TestContext {
1222 pub app: App,
1223 pub input_map: InputMap<TestAction>,
1224 }
1225
1226 #[cfg(any(feature = "keyboard", feature = "gamepad"))]
1227 impl TestContext {
1228 pub fn new() -> Self {
1229 use bevy::input::InputPlugin;
1230
1231 use crate::plugin::InputManagerPlugin;
1232
1233 let mut app = App::new();
1234 app.add_plugins((
1235 MinimalPlugins,
1236 InputPlugin,
1237 InputManagerPlugin::<TestAction>::default(),
1238 ));
1239
1240 let mut input_map = InputMap::default();
1241 #[cfg(feature = "gamepad")]
1242 input_map.insert(TestAction::Trigger, GamepadButton::RightTrigger);
1243
1244 #[cfg(feature = "keyboard")]
1245 {
1246 input_map.insert(TestAction::One, KeyCode::Digit1);
1247 input_map.insert(TestAction::Two, KeyCode::Digit2);
1248 input_map.insert(
1249 TestAction::OneAndTwo,
1250 ButtonlikeChord::new([KeyCode::Digit1, KeyCode::Digit2]),
1251 );
1252 input_map.insert(TestAction::Run, KeyCode::KeyR);
1253 }
1254
1255 app.world_mut().spawn(input_map.clone());
1258
1259 app.update();
1260
1261 Self { app, input_map }
1262 }
1263
1264 #[cfg(feature = "gamepad")]
1265 pub fn send_gamepad_connection_event(&mut self, gamepad: Option<Entity>) -> Entity {
1266 use bevy::input::gamepad::{GamepadConnection, GamepadConnectionEvent};
1267
1268 let gamepad = gamepad.unwrap_or_else(|| self.app.world_mut().spawn_empty().id());
1269 self.app
1270 .world_mut()
1271 .resource_mut::<Messages<GamepadConnectionEvent>>()
1272 .write(GamepadConnectionEvent::new(
1273 gamepad,
1274 GamepadConnection::Connected {
1275 name: "TestController".to_string(),
1276 vendor_id: None,
1277 product_id: None,
1278 },
1279 ));
1280 gamepad
1281 }
1282
1283 pub fn update(&mut self) {
1284 self.app.update();
1285 }
1286 }
1287
1288 #[test]
1289 fn action_state_default_state() {
1290 let action_state = ActionState::<TestAction>::default();
1291
1292 assert!(!action_state.disabled);
1293 assert_eq!(action_state.action_data, HashMap::default());
1294 }
1295
1296 #[test]
1297 fn action_state_all_action_data() {
1298 let action_state = ActionState::<TestAction>::default();
1299
1300 assert_eq!(action_state.all_action_data(), &action_state.action_data);
1301 }
1302
1303 #[test]
1304 fn action_state_button() {
1305 let mut action_state = ActionState::<TestAction>::default();
1306
1307 assert!(!action_state.pressed(&TestAction::Jump));
1308 assert_eq!(action_state.button_value(&TestAction::Jump), 0.0);
1309
1310 let mut updated_actions = UpdatedActions::<TestAction>::default();
1311 updated_actions.0.insert(
1312 TestAction::Jump,
1313 crate::input_map::UpdatedValue::Button(ButtonValue {
1314 pressed: true,
1315 value: 0.5,
1316 }),
1317 );
1318
1319 action_state.update(updated_actions);
1320
1321 assert!(action_state.pressed(&TestAction::Jump));
1322 assert_eq!(action_state.button_value(&TestAction::Jump), 0.5);
1323 }
1324
1325 #[test]
1326 fn action_state_axis() {
1327 let mut action_state = ActionState::<TestAction>::default();
1328
1329 assert_eq!(action_state.value(&TestAction::Axis), 0.0);
1330
1331 let mut updated_actions = UpdatedActions::<TestAction>::default();
1332 updated_actions
1333 .0
1334 .insert(TestAction::Axis, crate::input_map::UpdatedValue::Axis(0.5));
1335
1336 action_state.update(updated_actions);
1337
1338 assert_eq!(action_state.value(&TestAction::Axis), 0.5);
1339 }
1340
1341 #[test]
1342 fn action_state_dual_axis() {
1343 let mut action_state = ActionState::<TestAction>::default();
1344
1345 assert_eq!(
1346 action_state.axis_pair(&TestAction::DualAxis),
1347 Vec2::new(0.0, 0.0)
1348 );
1349
1350 let mut updated_actions = UpdatedActions::<TestAction>::default();
1351 updated_actions.0.insert(
1352 TestAction::DualAxis,
1353 crate::input_map::UpdatedValue::DualAxis(Vec2::new(0.5, 0.5)),
1354 );
1355
1356 action_state.update(updated_actions);
1357
1358 assert_eq!(
1359 action_state.axis_pair(&TestAction::DualAxis),
1360 Vec2::new(0.5, 0.5)
1361 );
1362 }
1363
1364 #[test]
1365 fn action_state_triple_axis() {
1366 let mut action_state = ActionState::<TestAction>::default();
1367
1368 assert_eq!(
1369 action_state.axis_triple(&TestAction::TripleAxis),
1370 Vec3::new(0.0, 0.0, 0.0)
1371 );
1372
1373 let mut updated_actions = UpdatedActions::<TestAction>::default();
1374 updated_actions.0.insert(
1375 TestAction::TripleAxis,
1376 crate::input_map::UpdatedValue::TripleAxis(Vec3::new(0.5, 0.5, 0.5)),
1377 );
1378
1379 action_state.update(updated_actions);
1380
1381 assert_eq!(
1382 action_state.axis_triple(&TestAction::TripleAxis),
1383 Vec3::new(0.5, 0.5, 0.5)
1384 );
1385 }
1386
1387 #[cfg(feature = "keyboard")]
1388 #[test]
1389 fn press_lifecycle() {
1390 use std::time::{Duration, Instant};
1391
1392 use crate::prelude::Buttonlike;
1393 use crate::prelude::ClashStrategy;
1394 use crate::prelude::updating::CentralInputStore;
1395
1396 let ctx = TestContext::new();
1397 let mut app = ctx.app;
1398 let input_map = ctx.input_map;
1399
1400 let mut action_state = ActionState::<TestAction>::default();
1402 println!(
1403 "Default button data: {:?}",
1404 action_state.button_data(&TestAction::Run)
1405 );
1406
1407 let input_store = app.world().resource::<CentralInputStore>();
1409 action_state.update(input_map.process_actions(None, input_store, ClashStrategy::PressAll));
1410
1411 println!(
1412 "Initialized button data: {:?}",
1413 action_state.button_data(&TestAction::Run)
1414 );
1415
1416 assert!(!action_state.pressed(&TestAction::Run));
1417 assert!(!action_state.just_pressed(&TestAction::Run));
1418 assert!(action_state.released(&TestAction::Run));
1419 assert!(!action_state.just_released(&TestAction::Run));
1420
1421 KeyCode::KeyR.press(app.world_mut());
1423 app.update();
1425 let input_store = app.world().resource::<CentralInputStore>();
1426
1427 action_state.update(input_map.process_actions(None, input_store, ClashStrategy::PressAll));
1428
1429 assert!(action_state.pressed(&TestAction::Run));
1430 assert!(action_state.just_pressed(&TestAction::Run));
1431 assert!(!action_state.released(&TestAction::Run));
1432 assert!(!action_state.just_released(&TestAction::Run));
1433
1434 action_state.tick(Instant::now(), Instant::now() - Duration::from_micros(1));
1436 action_state.update(input_map.process_actions(None, input_store, ClashStrategy::PressAll));
1437
1438 assert!(action_state.pressed(&TestAction::Run));
1439 assert!(!action_state.just_pressed(&TestAction::Run));
1440 assert!(!action_state.released(&TestAction::Run));
1441 assert!(!action_state.just_released(&TestAction::Run));
1442
1443 KeyCode::KeyR.release(app.world_mut());
1445 app.update();
1446 let input_store = app.world().resource::<CentralInputStore>();
1447
1448 action_state.update(input_map.process_actions(None, input_store, ClashStrategy::PressAll));
1449
1450 assert!(!action_state.pressed(&TestAction::Run));
1451 assert!(!action_state.just_pressed(&TestAction::Run));
1452 assert!(action_state.released(&TestAction::Run));
1453 assert!(action_state.just_released(&TestAction::Run));
1454
1455 action_state.tick(Instant::now(), Instant::now() - Duration::from_micros(1));
1457 action_state.update(input_map.process_actions(None, input_store, ClashStrategy::PressAll));
1458
1459 assert!(!action_state.pressed(&TestAction::Run));
1460 assert!(!action_state.just_pressed(&TestAction::Run));
1461 assert!(action_state.released(&TestAction::Run));
1462 assert!(!action_state.just_released(&TestAction::Run));
1463 }
1464
1465 #[test]
1466 fn synthetic_press() {
1467 let mut action_state = ActionState::<TestAction>::default();
1468 action_state.press(&TestAction::One);
1469 dbg!(&action_state);
1470
1471 assert!(action_state.pressed(&TestAction::One));
1472 assert!(action_state.just_pressed(&TestAction::One));
1473 assert!(!action_state.released(&TestAction::One));
1474 assert!(!action_state.just_released(&TestAction::One));
1475
1476 assert!(!action_state.pressed(&TestAction::Two));
1477 assert!(!action_state.just_pressed(&TestAction::Two));
1478 assert!(action_state.released(&TestAction::Two));
1479 assert!(!action_state.just_released(&TestAction::Two));
1480 }
1481
1482 #[cfg(feature = "keyboard")]
1483 #[test]
1484 #[ignore = "Clashing inputs for non-buttonlike inputs is broken."]
1485 fn update_with_clashes_prioritizing_longest() {
1486 use std::time::{Duration, Instant};
1487
1488 use crate::prelude::ClashStrategy;
1489 use crate::prelude::updating::CentralInputStore;
1490 use crate::user_input::Buttonlike;
1491 use bevy::prelude::KeyCode::*;
1492
1493 let ctx = TestContext::new();
1494 let mut app = ctx.app;
1495 let input_map = ctx.input_map;
1496
1497 let mut action_state = ActionState::<TestAction>::default();
1499
1500 let input_store = app.world().resource::<CentralInputStore>();
1502 action_state.update(input_map.process_actions(
1503 None,
1504 input_store,
1505 ClashStrategy::PrioritizeLongest,
1506 ));
1507 assert!(action_state.released(&TestAction::One));
1508 assert!(action_state.released(&TestAction::Two));
1509 assert!(action_state.released(&TestAction::OneAndTwo));
1510
1511 Digit1.press(app.world_mut());
1513 app.update();
1514 let input_store = app.world().resource::<CentralInputStore>();
1515
1516 action_state.update(input_map.process_actions(
1517 None,
1518 input_store,
1519 ClashStrategy::PrioritizeLongest,
1520 ));
1521
1522 assert!(action_state.pressed(&TestAction::One));
1523 assert!(action_state.released(&TestAction::Two));
1524 assert!(action_state.released(&TestAction::OneAndTwo));
1525
1526 action_state.tick(Instant::now(), Instant::now() - Duration::from_micros(1));
1528 action_state.update(input_map.process_actions(
1529 None,
1530 input_store,
1531 ClashStrategy::PrioritizeLongest,
1532 ));
1533
1534 assert!(action_state.pressed(&TestAction::One));
1535 assert!(action_state.released(&TestAction::Two));
1536 assert!(action_state.released(&TestAction::OneAndTwo));
1537
1538 Digit2.press(app.world_mut());
1540 app.update();
1541 let input_store = app.world().resource::<CentralInputStore>();
1542
1543 action_state.update(input_map.process_actions(
1544 None,
1545 input_store,
1546 ClashStrategy::PrioritizeLongest,
1547 ));
1548
1549 assert!(action_state.released(&TestAction::One));
1552 assert!(action_state.released(&TestAction::Two));
1553 assert!(action_state.pressed(&TestAction::OneAndTwo));
1554
1555 action_state.tick(Instant::now(), Instant::now() - Duration::from_micros(1));
1557 action_state.update(input_map.process_actions(
1558 None,
1559 input_store,
1560 ClashStrategy::PrioritizeLongest,
1561 ));
1562
1563 assert!(action_state.released(&TestAction::One));
1564 assert!(action_state.released(&TestAction::Two));
1565 assert!(action_state.pressed(&TestAction::OneAndTwo));
1566 }
1567
1568 #[test]
1569 fn test_set_update_state_from_state() {
1570 let mut action_state = ActionState::<TestAction>::default();
1571
1572 assert!(action_state.released(&TestAction::Run));
1574 assert!(!action_state.just_released(&TestAction::Run));
1575 assert!(!action_state.pressed(&TestAction::Run));
1576 assert!(!action_state.just_pressed(&TestAction::Run));
1577
1578 action_state.action_data.insert(
1580 TestAction::Run,
1581 ActionData {
1582 disabled: false,
1583 kind_data: ActionKindData::Button(ButtonData {
1584 state: ButtonState::Pressed,
1585 update_state: ButtonState::Pressed,
1586 fixed_update_state: ButtonState::Pressed,
1587 value: 1.0,
1588 update_value: 1.0,
1589 fixed_update_value: 1.0,
1590 #[cfg(feature = "timing")]
1591 timing: Default::default(),
1592 }),
1593 },
1594 );
1595 action_state.set_update_state_from_state();
1596
1597 assert!(action_state.pressed(&TestAction::Run));
1599 assert!(!action_state.just_pressed(&TestAction::Run));
1600 assert!(!action_state.released(&TestAction::Run));
1601 assert!(!action_state.just_released(&TestAction::Run));
1602 }
1603
1604 #[test]
1605 fn test_set_fixed_update_state_from_state() {
1606 let mut action_state = ActionState::<TestAction>::default();
1607
1608 assert!(action_state.released(&TestAction::Run));
1610 assert!(!action_state.just_released(&TestAction::Run));
1611 assert!(!action_state.pressed(&TestAction::Run));
1612 assert!(!action_state.just_pressed(&TestAction::Run));
1613
1614 action_state.action_data.insert(
1616 TestAction::Run,
1617 ActionData {
1618 disabled: false,
1619 kind_data: ActionKindData::Button(ButtonData {
1620 state: ButtonState::Pressed,
1621 update_state: ButtonState::Pressed,
1622 fixed_update_state: ButtonState::Pressed,
1623 value: 1.0,
1624 update_value: 1.0,
1625 fixed_update_value: 1.0,
1626 #[cfg(feature = "timing")]
1627 timing: Default::default(),
1628 }),
1629 },
1630 );
1631 action_state.set_fixed_update_state_from_state();
1632
1633 assert!(action_state.pressed(&TestAction::Run));
1634 assert!(!action_state.just_pressed(&TestAction::Run));
1635 assert!(!action_state.released(&TestAction::Run));
1636 assert!(!action_state.just_released(&TestAction::Run));
1637 }
1638
1639 #[test]
1640 fn test_button_data_for_button_action_without_data() {
1641 let mut action_state = ActionState::<TestAction>::default();
1642 action_state.action_data.remove(&TestAction::Run);
1643 assert!(action_state.button_data(&TestAction::Run).is_none());
1644 }
1645
1646 #[test]
1647 fn test_button_data_for_non_button_action() {
1648 let mut action_state = ActionState::<TestAction>::default();
1649 action_state.action_data.insert(
1650 TestAction::Axis,
1651 ActionData {
1652 disabled: false,
1653 kind_data: ActionKindData::Axis(AxisData {
1654 value: 0.5,
1655 update_value: 0.5,
1656 fixed_update_value: 0.5,
1657 }),
1658 },
1659 );
1660 assert!(action_state.button_data(&TestAction::Axis).is_none());
1661 }
1662
1663 #[test]
1664 fn test_button_data_mut_for_button_action() {
1665 let mut action_state = ActionState::<TestAction>::default();
1666 action_state.action_data.insert(
1667 TestAction::Run,
1668 ActionData {
1669 disabled: false,
1670 kind_data: ActionKindData::Button(ButtonData {
1671 state: ButtonState::Released,
1672 update_state: ButtonState::Released,
1673 fixed_update_state: ButtonState::Released,
1674 value: 0.0,
1675 update_value: 0.0,
1676 fixed_update_value: 0.0,
1677 #[cfg(feature = "timing")]
1678 timing: Default::default(),
1679 }),
1680 },
1681 );
1682
1683 assert!(action_state.button_data_mut(&TestAction::Run).is_some());
1684 }
1685
1686 #[test]
1687 fn test_button_data_mut_for_button_action_without_data() {
1688 let mut action_state = ActionState::<TestAction>::default();
1689
1690 assert!(action_state.button_data_mut(&TestAction::Run).is_none());
1691 }
1692
1693 #[test]
1694 fn test_button_data_mut_for_non_button_action() {
1695 let mut action_state = ActionState::<TestAction>::default();
1696 action_state.action_data.insert(
1697 TestAction::Axis,
1698 ActionData {
1699 disabled: false,
1700 kind_data: ActionKindData::Axis(AxisData {
1701 value: 0.5,
1702 update_value: 0.5,
1703 fixed_update_value: 0.5,
1704 }),
1705 },
1706 );
1707 assert!(action_state.button_data_mut(&TestAction::Axis).is_none());
1708 }
1709
1710 #[test]
1711 #[should_panic(expected = "assertion `left == right` failed\n left: Axis\n right: Button")]
1712 fn test_button_data_mut_or_default_for_non_button_action() {
1713 let mut action_state = ActionState::<TestAction>::default();
1714 let _ = action_state.button_data_mut_or_default(&TestAction::Axis);
1715 }
1716
1717 #[test]
1718 fn test_axis_data_for_axis_action_without_data() {
1719 let action_state = ActionState::<TestAction>::default();
1720 assert!(action_state.axis_data(&TestAction::Axis).is_none());
1721 }
1722
1723 #[test]
1724 #[should_panic(expected = "assertion `left == right` failed\n left: Button\n right: Axis")]
1725 fn test_axis_data_for_non_axis_action() {
1726 let action_state = ActionState::<TestAction>::default();
1727 assert!(action_state.axis_data(&TestAction::Run).is_none());
1728 }
1729
1730 #[test]
1731 fn test_axis_data_mut_for_axis_action() {
1732 let mut action_state = ActionState::<TestAction>::default();
1733 action_state.action_data.insert(
1734 TestAction::Axis,
1735 ActionData {
1736 disabled: false,
1737 kind_data: ActionKindData::Axis(AxisData {
1738 value: 0.5,
1739 update_value: 0.5,
1740 fixed_update_value: 0.5,
1741 }),
1742 },
1743 );
1744 assert!(action_state.axis_data_mut(&TestAction::Axis).is_some());
1745 }
1746
1747 #[test]
1748 fn test_axis_data_mut_for_axis_action_without_data() {
1749 let mut action_state = ActionState::<TestAction>::default();
1750 assert!(action_state.axis_data_mut(&TestAction::Axis).is_none());
1751 }
1752
1753 #[test]
1754 fn test_axis_data_mut_for_non_axis_action() {
1755 let mut action_state = ActionState::<TestAction>::default();
1756 action_state.action_data.insert(
1757 TestAction::Run,
1758 ActionData {
1759 disabled: false,
1760 kind_data: ActionKindData::Button(ButtonData {
1761 state: ButtonState::Released,
1762 update_state: ButtonState::Released,
1763 fixed_update_state: ButtonState::Released,
1764 value: 0.0,
1765 update_value: 0.0,
1766 fixed_update_value: 0.0,
1767 #[cfg(feature = "timing")]
1768 timing: Default::default(),
1769 }),
1770 },
1771 );
1772 assert!(action_state.axis_data_mut(&TestAction::Run).is_none());
1773 }
1774
1775 #[test]
1776 #[should_panic(expected = "assertion `left == right` failed\n left: Button\n right: Axis")]
1777 fn test_axis_data_mut_or_default_for_non_axis_action() {
1778 let mut action_state = ActionState::<TestAction>::default();
1779 let _ = action_state.axis_data_mut_or_default(&TestAction::Run);
1780 }
1781
1782 #[test]
1783 fn test_dual_axis_data_for_dual_axis_action_without_data() {
1784 let action_state = ActionState::<TestAction>::default();
1785 assert!(action_state.dual_axis_data(&TestAction::DualAxis).is_none());
1786 }
1787
1788 #[test]
1789 fn test_dual_axis_data_mut_for_dual_axis_action() {
1790 let mut action_state = ActionState::<TestAction>::default();
1791 action_state.action_data.insert(
1792 TestAction::DualAxis,
1793 ActionData {
1794 disabled: false,
1795 kind_data: ActionKindData::DualAxis(DualAxisData {
1796 pair: Vec2::new(0.5, 0.5),
1797 update_pair: Vec2::new(0.5, 0.5),
1798 fixed_update_pair: Vec2::new(0.5, 0.5),
1799 }),
1800 },
1801 );
1802 assert!(
1803 action_state
1804 .dual_axis_data_mut(&TestAction::DualAxis)
1805 .is_some()
1806 );
1807 }
1808
1809 #[test]
1810 fn test_dual_axis_data_mut_for_dual_axis_action_without_data() {
1811 let mut action_state = ActionState::<TestAction>::default();
1812 assert!(
1813 action_state
1814 .dual_axis_data_mut(&TestAction::DualAxis)
1815 .is_none()
1816 );
1817 }
1818
1819 #[test]
1820 #[should_panic(expected = "assertion `left == right` failed\n left: Button\n right: DualAxis")]
1821 fn test_dual_axis_data_mut_for_non_dual_axis_action() {
1822 let mut action_state = ActionState::<TestAction>::default();
1823 assert!(action_state.dual_axis_data_mut(&TestAction::Run).is_none());
1824 }
1825
1826 #[test]
1827 fn test_triple_axis_data_for_triple_axis_action_without_data() {
1828 let action_state = ActionState::<TestAction>::default();
1829 assert!(
1830 action_state
1831 .triple_axis_data(&TestAction::TripleAxis)
1832 .is_none()
1833 );
1834 }
1835
1836 #[test]
1837 fn test_triple_axis_data_mut_for_triple_axis_action() {
1838 let mut action_state = ActionState::<TestAction>::default();
1839 action_state.action_data.insert(
1840 TestAction::TripleAxis,
1841 ActionData {
1842 disabled: false,
1843 kind_data: ActionKindData::TripleAxis(crate::action_state::TripleAxisData {
1844 triple: Vec3::new(0.5, 0.5, 0.5),
1845 update_triple: Vec3::new(0.5, 0.5, 0.5),
1846 fixed_update_triple: Vec3::new(0.5, 0.5, 0.5),
1847 }),
1848 },
1849 );
1850 assert!(
1851 action_state
1852 .triple_axis_data_mut(&TestAction::TripleAxis)
1853 .is_some()
1854 );
1855 }
1856
1857 #[test]
1858 fn test_button_value_for_disabled_button_action() {
1859 let mut action_state = ActionState::<TestAction>::default();
1860 action_state.action_data.insert(
1861 TestAction::Run,
1862 ActionData {
1863 disabled: true,
1864 kind_data: ActionKindData::Button(ButtonData {
1865 state: ButtonState::Pressed,
1866 update_state: ButtonState::Pressed,
1867 fixed_update_state: ButtonState::Pressed,
1868 value: 1.0,
1869 update_value: 1.0,
1870 fixed_update_value: 1.0,
1871 #[cfg(feature = "timing")]
1872 timing: Default::default(),
1873 }),
1874 },
1875 );
1876 action_state.disable_action(&TestAction::Run);
1877 assert_eq!(action_state.button_value(&TestAction::Run), 0.0);
1878 }
1879
1880 #[test]
1881 fn test_clamped_button_value_less_than_zero() {
1882 let mut action_state = ActionState::<TestAction>::default();
1883 action_state.set_button_value(&TestAction::Run, -0.5);
1884 assert_eq!(action_state.clamped_button_value(&TestAction::Run), 0.0);
1885 }
1886
1887 #[test]
1888 fn test_clamped_button_value_greater_than_zero() {
1889 let mut action_state: ActionState<TestAction> = ActionState::<TestAction>::default();
1890 action_state.set_button_value(&TestAction::Run, 1.5);
1891 assert_eq!(action_state.clamped_button_value(&TestAction::Run), 1.0);
1892 }
1893
1894 #[test]
1895 fn test_value_for_disabled_axis_action() {
1896 let mut action_state = ActionState::<TestAction>::default();
1897 action_state.action_data.insert(
1898 TestAction::Axis,
1899 ActionData {
1900 disabled: true,
1901 kind_data: ActionKindData::Axis(AxisData {
1902 value: 1.0,
1903 update_value: 1.0,
1904 fixed_update_value: 1.0,
1905 }),
1906 },
1907 );
1908 action_state.disable_action(&TestAction::Axis);
1909 assert_eq!(action_state.value(&TestAction::Axis), 0.0);
1910 }
1911
1912 #[test]
1913 fn test_clamped_value_less_than_negative_one() {
1914 let mut action_state = ActionState::<TestAction>::default();
1915 action_state.set_value(&TestAction::Axis, -2.0);
1916 assert_eq!(action_state.clamped_value(&TestAction::Axis), -1.0);
1917 }
1918
1919 #[test]
1920 fn test_clamped_value_greater_than_one() {
1921 let mut action_state = ActionState::<TestAction>::default();
1922 action_state.set_value(&TestAction::Axis, 2.0);
1923 assert_eq!(action_state.clamped_value(&TestAction::Axis), 1.0);
1924 }
1925
1926 #[test]
1927 fn test_axis_pair_for_disabled_dual_axis_action() {
1928 let mut action_state = ActionState::<TestAction>::default();
1929 action_state.disable_action(&TestAction::DualAxis);
1930 assert_eq!(action_state.axis_pair(&TestAction::DualAxis), Vec2::ZERO);
1931 }
1932
1933 #[test]
1934 fn test_clamped_axis_pair_greater_than_vec2_one() {
1935 let mut action_state = ActionState::<TestAction>::default();
1936 action_state.set_axis_pair(&TestAction::DualAxis, Vec2::new(2.0, 2.0));
1937 assert_eq!(
1938 action_state.clamped_axis_pair(&TestAction::DualAxis),
1939 Vec2::ONE
1940 );
1941 }
1942
1943 #[test]
1944 fn test_clamped_axis_pair_less_than_vec2_negative_one() {
1945 let mut action_state = ActionState::<TestAction>::default();
1946 action_state.set_axis_pair(&TestAction::DualAxis, Vec2::new(-2.0, -2.0));
1947 assert_eq!(
1948 action_state.clamped_axis_pair(&TestAction::DualAxis),
1949 Vec2::NEG_ONE
1950 );
1951 }
1952
1953 #[test]
1954 fn test_axis_triple_for_disabled_triple_axis_action() {
1955 let mut action_state = ActionState::<TestAction>::default();
1956 action_state.disable_action(&TestAction::TripleAxis);
1957 assert_eq!(
1958 action_state.axis_triple(&TestAction::TripleAxis),
1959 Vec3::ZERO
1960 );
1961 }
1962
1963 #[test]
1964 fn test_clamped_axis_triple_greater_than_vec3_one() {
1965 let mut action_state = ActionState::<TestAction>::default();
1966 action_state.set_axis_triple(&TestAction::TripleAxis, Vec3::new(2.0, 2.0, 2.0));
1967 assert_eq!(
1968 action_state.clamped_axis_triple(&TestAction::TripleAxis),
1969 Vec3::ONE
1970 );
1971 }
1972
1973 #[test]
1974 fn test_clamped_axis_triple_less_than_vec3_negative_one() {
1975 let mut action_state = ActionState::<TestAction>::default();
1976 action_state.set_axis_triple(&TestAction::TripleAxis, Vec3::new(-2.0, -2.0, -2.0));
1977 assert_eq!(
1978 action_state.clamped_axis_triple(&TestAction::TripleAxis),
1979 Vec3::NEG_ONE
1980 );
1981 }
1982
1983 #[test]
1984 fn test_set_button_data_for_button_action() {
1985 let mut action_state = ActionState::<TestAction>::default();
1986 let button_data = ButtonData {
1987 state: ButtonState::Pressed,
1988 update_state: ButtonState::Pressed,
1989 fixed_update_state: ButtonState::Pressed,
1990 value: 1.0,
1991 update_value: 1.0,
1992 fixed_update_value: 1.0,
1993 #[cfg(feature = "timing")]
1994 timing: Default::default(),
1995 };
1996 action_state.set_button_data(TestAction::Run, button_data);
1997
1998 let returned_data = action_state.button_data(&TestAction::Run).unwrap();
1999 assert_eq!(returned_data.state, ButtonState::Pressed);
2000 assert_eq!(returned_data.value, 1.0);
2001 }
2002
2003 #[test]
2004 #[should_panic(expected = "assertion `left == right` failed\n left: Axis\n right: Button")]
2005 fn test_set_button_data_for_non_button_action() {
2006 let mut action_state = ActionState::<TestAction>::default();
2007 let button_data = ButtonData {
2008 state: ButtonState::Pressed,
2009 update_state: ButtonState::Pressed,
2010 fixed_update_state: ButtonState::Pressed,
2011 value: 1.0,
2012 update_value: 1.0,
2013 fixed_update_value: 1.0,
2014 #[cfg(feature = "timing")]
2015 timing: Default::default(),
2016 };
2017 action_state.set_button_data(TestAction::Axis, button_data);
2018 }
2019
2020 #[test]
2021 fn test_reset_button_action() {
2022 let mut action_state = ActionState::<TestAction>::default();
2023 action_state.set_button_value(&TestAction::Run, 1.0);
2024 action_state.reset(&TestAction::Run);
2025
2026 assert!(!action_state.pressed(&TestAction::Run));
2027 assert_eq!(action_state.button_value(&TestAction::Run), 0.0);
2028 }
2029
2030 #[test]
2031 fn test_reset_axis_action() {
2032 let mut action_state = ActionState::<TestAction>::default();
2033 action_state.set_value(&TestAction::Axis, 1.0);
2034 action_state.reset(&TestAction::Axis);
2035
2036 assert_eq!(action_state.value(&TestAction::Axis), 0.0);
2037 }
2038
2039 #[test]
2040 fn test_reset_dual_axis_action() {
2041 let mut action_state = ActionState::<TestAction>::default();
2042 action_state.set_axis_pair(&TestAction::DualAxis, Vec2::ONE);
2043 action_state.reset(&TestAction::DualAxis);
2044
2045 assert_eq!(action_state.axis_pair(&TestAction::DualAxis), Vec2::ZERO);
2046 }
2047
2048 #[test]
2049 fn test_reset_triple_axis_action() {
2050 let mut action_state = ActionState::<TestAction>::default();
2051 action_state.set_axis_triple(&TestAction::TripleAxis, Vec3::ONE);
2052 action_state.reset(&TestAction::TripleAxis);
2053
2054 assert_eq!(
2055 action_state.axis_triple(&TestAction::TripleAxis),
2056 Vec3::ZERO
2057 );
2058 }
2059
2060 #[test]
2061 fn test_action_disabled_when_action_state_disabled() {
2062 let mut action_state = ActionState::<TestAction>::default();
2063 action_state.disable();
2064
2065 assert!(action_state.action_disabled(&TestAction::Run));
2066 }
2067
2068 #[test]
2069 fn test_action_disabled_when_action_state_not_disabled() {
2070 let mut action_state = ActionState::<TestAction>::default();
2071 assert!(!action_state.action_disabled(&TestAction::Run));
2072
2073 action_state.disable_action(&TestAction::Run);
2074 assert!(action_state.action_disabled(&TestAction::Run));
2075 }
2076
2077 #[test]
2078 fn test_disable() {
2079 let mut action_state = ActionState::<TestAction>::default();
2080 action_state.disable();
2081
2082 assert!(action_state.disabled);
2083 }
2084
2085 #[test]
2086 fn test_enable() {
2087 let mut action_state = ActionState::<TestAction>::default();
2088 action_state.disable();
2089 action_state.enable();
2090 assert!(!action_state.disabled);
2091 }
2092
2093 #[test]
2094 fn test_just_pressed_when_action_disabled() {
2095 let mut action_state = ActionState::<TestAction>::default();
2096 action_state.disable_action(&TestAction::Run);
2097
2098 assert!(!action_state.just_pressed(&TestAction::Run));
2099 }
2100
2101 #[test]
2102 fn test_released_when_action_disabled() {
2103 let mut action_state = ActionState::<TestAction>::default();
2104 action_state.disable_action(&TestAction::Run);
2105
2106 assert!(action_state.released(&TestAction::Run));
2107 }
2108
2109 #[test]
2110 fn test_just_released_when_action_disabled() {
2111 let mut action_state = ActionState::<TestAction>::default();
2112 action_state.disable_action(&TestAction::Run);
2113
2114 assert!(!action_state.just_released(&TestAction::Run));
2115 }
2116
2117 #[test]
2118 fn test_pressed_when_action_disabled() {
2119 let mut action_state = ActionState::<TestAction>::default();
2120 action_state.disable();
2121
2122 assert!(!action_state.pressed(&TestAction::Run));
2123 }
2124
2125 #[test]
2126 fn apply_diff_triple_axis() {
2127 let mut action_state = ActionState::<TestAction>::default();
2128 action_state.set_axis_triple(&TestAction::TripleAxis, Vec3::new(1.0, 1.0, 1.0));
2129
2130 let diff = ActionDiff::TripleAxisChanged {
2131 action: TestAction::TripleAxis,
2132 axis_triple: Vec3::new(0.5, 1.0, 1.5),
2133 };
2134 action_state.apply_diff(&diff);
2135
2136 assert_eq!(
2137 action_state.axis_triple(&TestAction::TripleAxis),
2138 Vec3::new(0.5, 1.0, 1.5)
2139 );
2140 }
2141
2142 #[test]
2143 fn test_get_pressed() {
2144 let mut action_state = ActionState::<TestAction>::default();
2145 action_state.set_button_value(&TestAction::Run, 1.0);
2146
2147 let pressed_actions: Vec<TestAction> = action_state.get_pressed();
2148 assert_eq!(pressed_actions.len(), 1);
2149 assert!(pressed_actions.contains(&TestAction::Run));
2150 }
2151
2152 #[test]
2153 fn test_get_just_pressed() {
2154 let mut action_state = ActionState::<TestAction>::default();
2155 action_state.set_button_value(&TestAction::Run, 1.0);
2156
2157 let just_pressed_actions: Vec<TestAction> = action_state.get_just_pressed();
2158 assert_eq!(just_pressed_actions.len(), 1);
2159 assert!(just_pressed_actions.contains(&TestAction::Run));
2160 }
2161
2162 #[test]
2163 fn test_get_released() {
2164 let mut action_state = ActionState::<TestAction>::default();
2165 action_state.set_button_value(&TestAction::Run, 0.0);
2166
2167 let released_actions: Vec<TestAction> = action_state.get_released();
2168 assert_eq!(released_actions.len(), 1);
2169 assert!(released_actions.contains(&TestAction::Run));
2170 }
2171
2172 #[test]
2173 fn test_get_just_released() {
2174 let mut action_state = ActionState::<TestAction>::default();
2175 action_state.set_button_value(&TestAction::Run, 1.0);
2176 action_state.set_button_value(&TestAction::Run, 0.0);
2177
2178 let just_released_actions: Vec<TestAction> = action_state.get_just_released();
2179 assert_eq!(just_released_actions.len(), 1);
2180 assert!(just_released_actions.contains(&TestAction::Run));
2181 }
2182
2183 #[cfg(feature = "gamepad")]
2184 #[test]
2185 fn test_triggerlikes() {
2186 use crate::prelude::Buttonlike;
2187
2188 fn single_action_state(app: &mut App) -> ActionState<TestAction> {
2190 let world = app.world_mut();
2191 let mut query = world.query::<&ActionState<TestAction>>();
2192 query.single(world).unwrap().clone()
2193 }
2194
2195 let mut ctx = TestContext::new();
2196 let _gamepad = ctx.send_gamepad_connection_event(None);
2197 ctx.update();
2198
2199 let action_state = single_action_state(&mut ctx.app);
2200 assert!(action_state.released(&TestAction::Trigger));
2201
2202 let mut ctx = TestContext::new();
2204 let gamepad = ctx.send_gamepad_connection_event(None);
2205 ctx.update();
2206
2207 GamepadButton::RightTrigger.set_value_as_gamepad(ctx.app.world_mut(), 0.8, Some(gamepad));
2208 ctx.update();
2209
2210 let action_state = single_action_state(&mut ctx.app);
2211 assert!(action_state.pressed(&TestAction::Trigger));
2212 assert!(action_state.just_pressed(&TestAction::Trigger));
2213 assert_eq!(action_state.button_value(&TestAction::Trigger), 0.8);
2214 }
2215}