Skip to main content

leafwing_input_manager/action_state/
mod.rs

1//! This module contains [`ActionState`] and its supporting methods and impls.
2
3use 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/// Stores the canonical input-method-agnostic representation of the inputs received
21///
22/// Stored as a [`Component`] on entities that you wish to control directly from player input.
23///
24/// To model a single abstract / global input, spawn one dedicated entity holding the [`InputMap`](crate::prelude::InputMap)
25/// (which will add an [`ActionState`] via required components) and read/write to it using [`Single<&ActionState>`](bevy::prelude::Single).
26///
27/// # Disabling actions
28///
29/// Actions can be disabled in four different ways, with increasing granularity:
30///
31/// 1. By disabling updates to all actions using a run condition on [`InputManagerSystem::Update`](crate::plugin::InputManagerSystem::Update).
32/// 2. By disabling updates to all actions of type `A` using a run condition on [`TickActionStateSystem::<A>`](crate::plugin::TickActionStateSystem).
33/// 3. By setting a specific action state to disabled using [`ActionState::disable`].
34/// 4. By disabling a specific action using [`ActionState::disable_action`].
35///
36/// More general mechanisms of disabling actions will cause specific mechanisms to be ignored.
37/// For example, if an entire action state is disabled, then enabling or disabling individual actions will have no effect.
38///
39/// Actions that are disabled will report as released (but not just released), and their values will be zero.
40/// Under the hood, their values are still updated to avoid surprising behavior when re-enabled,
41/// but they are not reported to the user using standard methods like [`ActionState::pressed`].
42/// To check the underlying values, access their [`ActionData`] directly.
43///
44/// # Example
45///
46/// ```rust
47/// use bevy::reflect::Reflect;
48/// use leafwing_input_manager::prelude::*;
49/// use bevy::platform::time::Instant;
50///
51/// #[derive(Actionlike, PartialEq, Eq, Hash, Clone, Copy, Debug, Reflect)]
52/// enum Action {
53///     Left,
54///     Right,
55///     Jump,
56/// }
57///
58/// let mut action_state = ActionState::<Action>::default();
59///
60/// // Typically, this is done automatically by the `InputManagerPlugin` from user inputs
61/// // using the `ActionState::update` method
62/// action_state.press(&Action::Jump);
63///
64/// assert!(action_state.pressed(&Action::Jump));
65/// assert!(action_state.just_pressed(&Action::Jump));
66/// assert!(action_state.released(&Action::Left));
67///
68/// // Resets just_pressed and just_released
69/// let t0 = Instant::now();
70/// let t1 = Instant::now();
71///
72///  action_state.tick(t1, t0);
73/// assert!(action_state.pressed(&Action::Jump));
74/// assert!(!action_state.just_pressed(&Action::Jump));
75///
76/// action_state.release(&Action::Jump);
77/// assert!(!action_state.pressed(&Action::Jump));
78/// assert!(action_state.released(&Action::Jump));
79/// assert!(action_state.just_released(&Action::Jump));
80///
81/// let t2 = Instant::now();
82/// action_state.tick(t2, t1);
83/// assert!(action_state.released(&Action::Jump));
84/// assert!(!action_state.just_released(&Action::Jump));
85/// ```
86#[derive(Component, Clone, Debug, PartialEq, Serialize, Deserialize, Reflect)]
87#[reflect(Component)]
88pub struct ActionState<A: Actionlike> {
89    /// Whether or not all of the actions are disabled.
90    disabled: bool,
91    /// The shared action data for each action
92    action_data: HashMap<A, ActionData>,
93}
94
95// The derive does not work unless A: Default,
96// so we have to implement it manually
97impl<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    /// Returns a reference to the complete [`ActionData`] for all actions.
108    #[inline]
109    #[must_use]
110    pub fn all_action_data(&self) -> &HashMap<A, ActionData> {
111        &self.action_data
112    }
113
114    /// We are about to enter the `Main` schedule, so we:
115    /// - save all the changes applied to `state` into the `fixed_update_state`
116    /// - switch to loading the `update_state`
117    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    /// We are about to enter the `FixedMain` schedule, so we:
124    /// - save all the changes applied to `state` into the `update_state`
125    /// - switch to loading the `fixed_update_state`
126    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    /// Function for advanced users to override the `state` from the `update_state`
133    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    /// Function for advanced users to override the `state` from the `fixed_update_state`
140    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    /// Updates the [`ActionState`] based on the provided [`UpdatedActions`],
147    /// typically constructed from [`InputMap::process_actions`](crate::input_map::InputMap::process_actions).
148    ///
149    /// Actions absent from `updated_actions` but with existing data are reset to zero/released.
150    /// Actions that are disabled will still be updated: instead, their values will be read as released / zero.
151    /// You can see their underlying values by checking their [`ActionData`] directly.
152    pub fn update(&mut self, updated_actions: UpdatedActions<A>) {
153        // Reset existing action data absent from this frame's update (e.g. after rollback restore).
154        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    /// Advances the time for all actions,
196    /// transitioning them from `just_pressed` to `pressed`, and `just_released` to `released`.
197    ///
198    /// If the `timing` feature flag is enabled, the underlying timing and action data will be advanced according to the `current_instant`.
199    /// - if no [`Instant`] is set, the `current_instant` will be set as the initial time at which the button was pressed / released
200    /// - the [`Duration`] will advance to reflect elapsed time
201    ///
202    ///
203    /// # Example
204    /// ```rust
205    /// use bevy::prelude::Reflect;
206    /// use leafwing_input_manager::prelude::*;
207    /// use leafwing_input_manager::buttonlike::ButtonState;
208    /// use bevy::platform::time::Instant;
209    ///
210    /// #[derive(Actionlike, Clone, Copy, PartialEq, Eq, Hash, Debug, Reflect)]
211    /// enum Action {
212    ///     Run,
213    ///     Jump,
214    /// }
215    ///
216    /// let mut action_state = ActionState::<Action>::default();
217    ///
218    /// // Actions start released
219    /// assert!(action_state.released(&Action::Jump));
220    /// assert!(!action_state.just_released(&Action::Run));
221    ///
222    /// // Ticking time moves causes buttons just released to no longer be just released
223    /// let t0 = Instant::now();
224    /// let t1 = Instant::now();
225    ///
226    /// action_state.tick(t1, t0);
227    /// assert!(action_state.released(&Action::Jump));
228    /// assert!(!action_state.just_released(&Action::Jump));
229    ///
230    /// action_state.press(&Action::Jump);
231    /// assert!(action_state.just_pressed(&Action::Jump));
232    ///
233    /// // Ticking time moves causes buttons just pressed to no longer be just pressed
234    /// let t2 = Instant::now();
235    ///
236    /// action_state.tick(t2, t1);
237    /// assert!(action_state.pressed(&Action::Jump));
238    /// assert!(!action_state.just_pressed(&Action::Jump));
239    /// ```
240    pub fn tick(&mut self, _current_instant: Instant, _previous_instant: Instant) {
241        // Advanced the action states
242        self.action_data
243            .values_mut()
244            .for_each(|action_datum| action_datum.tick(_current_instant, _previous_instant));
245    }
246
247    /// A reference to the [`ActionData`] corresponding to the `action`.
248    #[inline]
249    #[must_use]
250    pub fn action_data(&self, action: &A) -> Option<&ActionData> {
251        self.action_data.get(action)
252    }
253
254    /// A mutable reference to the [`ActionData`] corresponding to the `action`.
255    ///
256    /// To initialize the [`ActionData`] if it has not yet been triggered,
257    /// use [`action_data_mut_or_default`](Self::action_data_mut_or_default) method.
258    #[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    /// A mutable reference to the [`ActionData`] corresponding to the `action`, initializing it if needed.
265    ///
266    /// If the `action` has no data yet (because the `action` has not been triggered),
267    /// this method will create and insert a default [`ActionData`] for you,
268    /// avoiding potential errors from unwrapping [`None`].
269    pub fn action_data_mut_or_default(&mut self, action: &A) -> &mut ActionData {
270        if self.action_data.contains_key(action) {
271            // Safe to unwrap because we just checked
272            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            // Safe to unwrap because we just inserted
279            self.action_data_mut(action).unwrap()
280        }
281    }
282
283    /// A reference of the [`ButtonData`] corresponding to the `action`.
284    ///
285    /// Generally, it'll be clearer to call `pressed` or so on directly on the [`ActionState`].
286    /// However, accessing the raw data directly allows you to examine detailed metadata holistically.
287    ///
288    /// # Caution
289    ///
290    /// To access the [`ButtonData`] regardless of whether the `action` has been triggered,
291    /// use [`unwrap_or_default`](Option::unwrap_or_default) on the returned [`Option`].
292    ///
293    /// # Returns
294    ///
295    /// - `Some(ButtonData)` if it exists.
296    /// - `None` if the `action` has never been triggered (pressed, clicked, etc.).
297    #[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    /// A mutable reference of the [`ButtonData`] corresponding to the `action`.
310    ///
311    /// Generally, it'll be clearer to call `pressed` or so on directly on the [`ActionState`].
312    /// However, accessing the raw data directly allows you to examine detailed metadata holistically.
313    ///
314    /// # Caution
315    ///
316    /// To access the [`ButtonData`] regardless of whether the `action` has been triggered,
317    /// use [`unwrap_or_default`](Option::unwrap_or_default) on the returned [`Option`].
318    ///
319    /// To insert a default [`ButtonData`] if it doesn't exist,
320    /// use [`button_data_mut_or_default`](Self::button_data_mut_or_default) method.
321    ///
322    /// # Returns
323    ///
324    /// - `Some(ButtonData)` if it exists.
325    /// - `None` if the `action` has never been triggered (pressed, clicked, etc.).
326    #[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    /// A mutable reference of the [`ButtonData`] corresponding to the `action`, initializing it if needed.
339    ///
340    /// If the `action` has no data yet (because the `action` has not been triggered),
341    /// this method will create and insert a default [`ButtonData`] for you,
342    /// avoiding potential errors from unwrapping [`None`].
343    ///
344    /// Generally, it'll be clearer to call `pressed` or so on directly on the [`ActionState`].
345    /// However, accessing the raw data directly allows you to examine detailed metadata holistically.
346    #[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    /// A reference of the [`AxisData`] corresponding to the `action`.
360    ///
361    /// # Caution
362    ///
363    /// To access the [`AxisData`] regardless of whether the `action` has been triggered,
364    /// use [`unwrap_or_default`](Option::unwrap_or_default) on the returned [`Option`].
365    ///
366    /// # Returns
367    ///
368    /// - `Some(AxisData)` if it exists.
369    /// - `None` if the `action` has never been triggered (pressed, clicked, etc.).
370    #[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    /// A mutable reference of the [`AxisData`] corresponding to the `action`.
386    ///
387    /// # Caution
388    ///
389    /// To insert a default [`AxisData`] if it doesn't exist,
390    /// use [`axis_data_mut_or_default`](Self::axis_data_mut_or_default) method.
391    ///
392    /// # Returns
393    ///
394    /// - `Some(AxisData)` if it exists.
395    /// - `None` if the `action` has never been triggered (pressed, clicked, etc.).
396    #[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    /// A mutable reference of the [`AxisData`] corresponding to the `action`, initializing it if needed..
409    ///
410    /// If the `action` has no data yet (because the `action` has not been triggered),
411    /// this method will create and insert a default [`AxisData`] for you,
412    /// avoiding potential errors from unwrapping [`None`].
413    ///
414    /// Generally, it'll be clearer to call `pressed` or so on directly on the [`ActionState`].
415    /// However, accessing the raw data directly allows you to examine detailed metadata holistically.
416    #[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    /// A reference of the [`DualAxisData`] corresponding to the `action`.
430    ///
431    /// # Caution
432    ///
433    /// To access the [`DualAxisData`] regardless of whether the `action` has been triggered,
434    /// use [`unwrap_or_default`](Option::unwrap_or_default) on the returned [`Option`].
435    ///
436    /// # Returns
437    ///
438    /// - `Some(DualAxisData)` if it exists.
439    /// - `None` if the `action` has never been triggered (pressed, clicked, etc.).
440    #[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    /// A mutable reference of the [`DualAxisData`] corresponding to the `action`.
456    ///
457    /// # Caution
458    ///
459    /// To insert a default [`DualAxisData`] if it doesn't exist,
460    /// use [`dual_axis_data_mut_or_default`](Self::dual_axis_data_mut_or_default) method.
461    ///
462    /// # Returns
463    ///
464    /// - `Some(DualAxisData)` if it exists.
465    /// - `None` if the `action` has never been triggered (pressed, clicked, etc.).
466    #[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    /// A mutable reference of the [`DualAxisData`] corresponding to the `action` initializing it if needed.
482    ///
483    /// If the `action` has no data yet (because the `action` has not been triggered),
484    /// this method will create and insert a default [`DualAxisData`] for you,
485    /// avoiding potential errors from unwrapping [`None`].
486    ///
487    /// Generally, it'll be clearer to call `pressed` or so on directly on the [`ActionState`].
488    /// However, accessing the raw data directly allows you to examine detailed metadata holistically.
489    #[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    /// A reference of the [`TripleAxisData`] corresponding to the `action`.
503    ///
504    /// # Caution
505    ///
506    /// To access the [`TripleAxisData`] regardless of whether the `action` has been triggered,
507    /// use [`unwrap_or_default`](Option::unwrap_or_default) on the returned [`Option`].
508    ///
509    /// # Returns
510    ///
511    /// - `Some(TripleAxisData)` if it exists.
512    /// - `None` if the `action` has never been triggered (pressed, clicked, etc.).
513    #[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    /// A mutable reference of the [`TripleAxisData`] corresponding to the `action`.
529    ///
530    /// # Caution
531    ///
532    /// To insert a default [`TripleAxisData`] if it doesn't exist,
533    /// use [`triple_axis_data_mut_or_default`](Self::dual_axis_data_mut_or_default) method.
534    ///
535    /// # Returns
536    ///
537    /// - `Some(ButtonData)` if it exists.
538    /// - `None` if the `action` has never been triggered (pressed, clicked, etc.).
539    #[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    /// A mutable reference of the [`TripleAxisData`] corresponding to the `action` initializing it if needed.
555    ///
556    /// If the `action` has no data yet (because the `action` has not been triggered),
557    /// this method will create and insert a default [`TripleAxisData`] for you,
558    /// avoiding potential errors from unwrapping [`None`].
559    ///
560    /// Generally, it'll be clearer to call `pressed` or so on directly on the [`ActionState`].
561    /// However, accessing the raw data directly allows you to examine detailed metadata holistically.
562    #[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    /// Get the value associated with the corresponding buttonlike `action` if present.
576    ///
577    /// # Warnings
578    ///
579    /// This value may not be bounded as you might expect.
580    /// Consider clamping this to account for multiple triggering inputs,
581    /// typically using the [`clamped_button_value`](Self::clamped_button_value) method instead.
582    #[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    /// Sets the value of the buttonlike `action` to the provided `value`.
597    /// A threshold of `0.02` must be overcome for the button to count as "pressed"
598    /// This is used to account for a semi-frequent issue with analog inputs
599    /// (e.g., gamepad triggers) reporting very small non-zero values when
600    /// not physically pressed, due to sensor imprecision.
601    ///
602    /// Also updates the state of the button based on the `value`:
603    /// - If `value > 0.02`, the button will be pressed.
604    /// - If `value <= 0.0`, the button will be released.
605    #[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    /// Get the value associated with the corresponding `action`, clamped to `[0.0, 1.0]`.
631    ///
632    /// # Warning
633    ///
634    /// This value will be 0. by default,
635    /// even if the action is not a buttonlike action.
636    pub fn clamped_button_value(&self, action: &A) -> f32 {
637        self.button_value(action).clamp(0., 1.)
638    }
639
640    /// Get the value associated with the corresponding axislike `action` if present.
641    ///
642    /// # Warnings
643    ///
644    /// This value may not be bounded as you might expect.
645    /// Consider clamping this to account for multiple triggering inputs,
646    /// typically using the [`clamped_value`](Self::clamped_value) method instead.
647    #[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    /// Sets the value of the axislike `action` to the provided `value`.
662    #[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    /// Get the value associated with the corresponding `action`, clamped to `[-1.0, 1.0]`.
671    ///
672    /// # Warning
673    ///
674    /// This value will be 0. by default,
675    /// even if the action is not an axislike action.
676    pub fn clamped_value(&self, action: &A) -> f32 {
677        self.value(action).clamp(-1., 1.)
678    }
679
680    /// Get the [`Vec2`] from the binding that triggered the corresponding `action`.
681    ///
682    /// Only messages that represent dual-axis control provide a [`Vec2`],
683    /// and this will return [`None`] for other messages.
684    ///
685    /// If multiple inputs with an axis pair trigger the same game action at the same time, the
686    /// value of each axis pair will be added together.
687    ///
688    /// # Warning
689    ///
690    /// This value will be [`Vec2::ZERO`] by default,
691    /// even if the action is not a dual-axislike action.
692    ///
693    /// These values may not be bounded as you might expect.
694    /// Consider clamping this to account for multiple triggering inputs,
695    /// typically using the [`clamped_axis_pair`](Self::clamped_axis_pair) method instead.
696    #[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    /// Sets the [`Vec2`] of the `action` to the provided `pair`.
710    #[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    /// Get the [`Vec2`] associated with the corresponding `action`, clamped to `[-1.0, 1.0]`.
719    ///  
720    /// # Warning
721    ///
722    /// This value will be [`Vec2::ZERO`] by default,
723    /// even if the action is not a dual-axislike action.
724    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    /// Get the [`Vec3`] from the binding that triggered the corresponding `action`.
730    ///
731    /// Only messages that represent triple-axis control provide a [`Vec3`],
732    /// and this will return [`None`] for other messages.
733    ///
734    /// If multiple inputs with an axis triple trigger the same game action at the same time, the
735    /// value of each axis triple will be added together.
736    ///
737    /// # Warning
738    ///
739    /// This value will be [`Vec3::ZERO`] by default,
740    /// even if the action is not a triple-axislike action.
741    ///
742    /// These values may not be bounded as you might expect.
743    /// Consider clamping this to account for multiple triggering inputs,
744    /// typically using the [`clamped_axis_triple`](Self::clamped_axis_triple) method instead.
745    #[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    /// Sets the [`Vec2`] of the `action` to the provided `pair`.
759    #[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    /// Get the [`Vec3`] associated with the corresponding `action`, clamped to the cube of values bounded by -1 and 1 on all axes.
768    ///
769    /// # Warning
770    ///
771    /// This value will be [`Vec3::ZERO`] by default,
772    /// even if the action is not a dual-axislike action.
773    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    /// Manually sets the [`ButtonData`] of the corresponding `action`
779    ///
780    /// You should almost always use more direct methods, as they are simpler and less error-prone.
781    ///
782    /// However, this method can be useful for testing,
783    /// or when transferring [`ButtonData`] between action states.
784    ///
785    /// # Example
786    /// ```rust
787    /// use bevy::prelude::Reflect;
788    /// use leafwing_input_manager::prelude::*;
789    ///
790    /// #[derive(Actionlike, Clone, Copy, PartialEq, Eq, Hash, Debug, Reflect)]
791    /// enum AbilitySlot {
792    ///     Slot1,
793    ///     Slot2,
794    /// }
795    ///
796    /// #[derive(Actionlike, Clone, Copy, PartialEq, Eq, Hash, Debug, Reflect)]
797    /// enum Action {
798    ///     Run,
799    ///     Jump,
800    /// }
801    ///
802    /// let mut ability_slot_state = ActionState::<AbilitySlot>::default();
803    /// let mut action_state = ActionState::<Action>::default();
804    ///
805    /// // Extract the state from the ability slot
806    /// let slot_1_state = ability_slot_state.button_data(&AbilitySlot::Slot1);
807    ///
808    /// // And transfer it to the actual ability that we care about
809    /// // without losing timing information
810    /// if let Some(state) = slot_1_state {
811    ///    action_state.set_button_data(Action::Run, state.clone());
812    /// }
813    /// ```
814    #[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    /// Press the `action`
824    ///
825    /// No initial instant or reasons why the button was pressed will be recorded.
826    /// Instead, this is set through [`ActionState::tick()`]
827    #[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    /// Release the `action`
844    ///
845    /// No initial instant will be recorded.
846    /// Instead, this is set through [`ActionState::tick()`]
847    #[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    /// Resets an action to its default state.
863    ///
864    /// Buttons will be released, and axes will be set to 0.
865    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    /// Releases all [`Buttonlike`](crate::user_input::Buttonlike) actions,
881    /// sets all [`Axislike`](crate::user_input::Axislike) actions to 0,
882    /// sets all [`DualAxislike`](crate::user_input::DualAxislike) actions to [`Vec2::ZERO`],
883    /// and sets all [`TripleAxislike`](crate::user_input::TripleAxislike) actions to [`Vec3::ZERO`].
884    pub fn reset_all(&mut self) {
885        // Collect out to avoid angering the borrow checker
886        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    /// Is the entire [`ActionState`] currently disabled?
893    pub fn disabled(&self) -> bool {
894        self.disabled
895    }
896
897    /// Is this `action` currently disabled?
898    #[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    /// Disables the entire [`ActionState`].
912    ///
913    /// All values will be reset to their default state.
914    #[inline]
915    pub fn disable(&mut self) {
916        self.disabled = true;
917        self.reset_all();
918    }
919
920    /// Disables the `action`.
921    ///
922    /// The action's value will be reset to its default state.
923    #[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    /// Disables all actions
932    #[inline]
933    pub fn disable_all_actions(&mut self) {
934        for action in self.keys() {
935            self.disable_action(&action);
936        }
937    }
938
939    /// Enables the entire [`ActionState`]
940    #[inline]
941    pub fn enable(&mut self) {
942        self.disabled = false;
943    }
944
945    /// Enables the `action`
946    #[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    /// Enables all actions
954    #[inline]
955    pub fn enable_all_actions(&mut self) {
956        for action in self.keys() {
957            self.enable_action(&action);
958        }
959    }
960
961    /// Is this `action` currently pressed?
962    ///
963    /// # Warning
964    ///
965    /// This value will be `false` by default,
966    /// even if the action is not a buttonlike action.
967    #[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    /// Was this `action` pressed since the last time [tick](ActionState::tick) was called?
984    ///
985    /// # Warning
986    ///
987    /// This value will be `false` by default,
988    /// even if the action is not a buttonlike action.
989    #[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    /// Is this `action` currently released?
1006    ///
1007    /// This is always the logical negation of [pressed](ActionState::pressed)
1008    ///
1009    /// # Warning
1010    ///
1011    /// This value will be `true` by default,
1012    /// even if the action is not a buttonlike action.
1013    #[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    /// Was this `action` released since the last time [tick](ActionState::tick) was called?
1030    ///
1031    /// # Warning
1032    ///
1033    /// This value will be `false` by default,
1034    /// even if the action is not a buttonlike action.
1035    #[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    /// Which actions are currently pressed?
1053    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    /// Which actions were just pressed?
1065    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    /// Which actions are currently released?
1077    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    /// Which actions were just released?
1089    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    /// The [`Instant`] that the action was last pressed or released
1100    ///
1101    ///
1102    ///
1103    /// If the action was pressed or released since the last time [`ActionState::tick`] was called
1104    /// the value will be [`None`].
1105    /// This ensures that all our actions are assigned a timing and duration
1106    /// that corresponds exactly to the start of a frame, rather than relying on idiosyncratic timing.
1107    ///
1108    /// This will also be [`None`] if the action was never pressed or released.
1109    #[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    /// The [`Duration`] for which the action has been held or released
1120    ///
1121    /// This will be [`Duration::ZERO`] if the action was never pressed or released.
1122    #[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    /// The [`Duration`] for which the action was last held or released
1134    ///
1135    /// This is a snapshot of the [`ActionState::current_duration`] state at the time
1136    /// the action was last pressed or released.
1137    ///
1138    /// This will be [`Duration::ZERO`] if the action was never pressed or released.
1139    #[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    /// Applies an [`ActionDiff`] (usually received over the network) to the [`ActionState`].
1151    ///
1152    /// This lets you reconstruct an [`ActionState`] from a stream of [`ActionDiff`]s
1153    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    /// Returns an owned list of the [`Actionlike`] keys in this [`ActionState`].
1177    #[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            // Spawn a single input entity. The `InputMap` requires an `ActionState`,
1256            // so it is added automatically.
1257            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        // Action state
1401        let mut action_state = ActionState::<TestAction>::default();
1402        println!(
1403            "Default button data: {:?}",
1404            action_state.button_data(&TestAction::Run)
1405        );
1406
1407        // Starting state
1408        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        // Pressing
1422        KeyCode::KeyR.press(app.world_mut());
1423        // Process the input messages into Input<KeyCode> data
1424        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        // Waiting
1435        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        // Releasing
1444        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        // Waiting
1456        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        // Action state
1498        let mut action_state = ActionState::<TestAction>::default();
1499
1500        // Starting state
1501        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        // Pressing One
1512        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        // Waiting
1527        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        // Pressing Two
1539        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        // Now only the longest OneAndTwo has been pressed,
1550        // while both One and Two have been released
1551        assert!(action_state.released(&TestAction::One));
1552        assert!(action_state.released(&TestAction::Two));
1553        assert!(action_state.pressed(&TestAction::OneAndTwo));
1554
1555        // Waiting
1556        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        // Initial state
1573        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        // Update the state manually
1579        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        // Check the state
1598        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        // Initial state
1609        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        // Update the state manually
1615        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        /// Returns a clone of the single [`ActionState<TestAction>`] component in the app.
2189        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        // App Context
2203        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}