leafwing_input_manager/action_state/
action_data.rs

1//! Contains types used to store the state of the actions held in an [`ActionState`](super::ActionState).
2
3use bevy::{
4    math::{Vec2, Vec3},
5    platform::time::Instant,
6    reflect::Reflect,
7};
8use serde::{Deserialize, Serialize};
9
10use crate::buttonlike::ButtonValue;
11#[cfg(feature = "timing")]
12use crate::timing::Timing;
13use crate::{buttonlike::ButtonState, InputControlKind};
14
15/// Data about the state of an action.
16///
17/// Universal data about the state of the data is stored directly in this struct,
18/// while data for each kind of action (buttonlike, axislike...) is stored in the `kind_data` field.
19#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Reflect)]
20pub struct ActionData {
21    /// Whether or not the action is disabled.
22    ///
23    /// While disabled, buttons will always report as released, and axes will always report as 0.
24    pub disabled: bool,
25    /// The data for the action.
26    pub kind_data: ActionKindData,
27}
28
29impl ActionData {
30    /// Constructs a new `ActionData` with default values corresponding to the given `kind_data`.
31    pub fn from_kind(input_control_kind: InputControlKind) -> Self {
32        Self {
33            disabled: false,
34            kind_data: match input_control_kind {
35                InputControlKind::Button => ActionKindData::Button(ButtonData::default()),
36                InputControlKind::Axis => ActionKindData::Axis(AxisData::default()),
37                InputControlKind::DualAxis => ActionKindData::DualAxis(DualAxisData::default()),
38                InputControlKind::TripleAxis => {
39                    ActionKindData::TripleAxis(TripleAxisData::default())
40                }
41            },
42        }
43    }
44
45    /// Ticks the action data, updating the state of the action.
46    pub fn tick(&mut self, _current_instant: Instant, _previous_instant: Instant) {
47        match self.kind_data {
48            ActionKindData::Button(ref mut data) => {
49                data.state.tick();
50
51                #[cfg(feature = "timing")]
52                data.timing.tick(_current_instant, _previous_instant);
53            }
54            ActionKindData::Axis(ref mut _data) => {}
55            ActionKindData::DualAxis(ref mut _data) => {}
56            ActionKindData::TripleAxis(ref mut _data) => {}
57        }
58    }
59}
60
61/// A wrapper over the various forms of data that an action can take.
62#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Reflect)]
63pub enum ActionKindData {
64    /// The data for a button-like action.
65    Button(ButtonData),
66    /// The data for an axis-like action.
67    Axis(AxisData),
68    /// The data for a dual-axis-like action.
69    DualAxis(DualAxisData),
70    /// The data for a triple-axis-like action.
71    TripleAxis(TripleAxisData),
72}
73
74impl ActionKindData {
75    pub(super) fn swap_to_update_state(&mut self) {
76        // save the changes applied to `state` into `fixed_update_state`
77        // switch to loading the `update_state` into `state`
78        match self {
79            Self::Button(data) => {
80                data.fixed_update_state = data.state;
81                data.fixed_update_value = data.value;
82                data.state = data.update_state;
83                data.value = data.update_value;
84            }
85            Self::Axis(data) => {
86                data.fixed_update_value = data.value;
87                data.value = data.update_value;
88            }
89            Self::DualAxis(data) => {
90                data.fixed_update_pair = data.pair;
91                data.pair = data.update_pair;
92            }
93            Self::TripleAxis(data) => {
94                data.fixed_update_triple = data.triple;
95                data.triple = data.update_triple;
96            }
97        }
98    }
99
100    pub(super) fn swap_to_fixed_update_state(&mut self) {
101        // save the changes applied to `state` into `update_state`
102        // switch to loading the `fixed_update_state` into `state`
103        match self {
104            Self::Button(data) => {
105                data.update_state = data.state;
106                data.update_value = data.value;
107                data.state = data.fixed_update_state;
108                data.value = data.fixed_update_value;
109            }
110            Self::Axis(data) => {
111                data.update_value = data.value;
112                data.value = data.fixed_update_value;
113            }
114            Self::DualAxis(data) => {
115                data.update_pair = data.pair;
116                data.pair = data.fixed_update_pair;
117            }
118            Self::TripleAxis(data) => {
119                data.update_triple = data.triple;
120                data.triple = data.fixed_update_triple;
121            }
122        }
123    }
124}
125
126/// Metadata about an [`Buttonlike`](crate::user_input::Buttonlike) action
127#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize, Reflect)]
128pub struct ButtonData {
129    /// Is the action pressed or released?
130    pub state: ButtonState,
131    /// The `state` of the action in the `Main` schedule
132    pub update_state: ButtonState,
133    /// The `state` of the action in the `FixedMain` schedule
134    pub fixed_update_state: ButtonState,
135    /// How far has the button been pressed
136    pub value: f32,
137    /// The `value` of the action in the `Main` schedule
138    pub update_value: f32,
139    /// The `value` of the action in the `FixedMain` schedule
140    pub fixed_update_value: f32,
141    /// When was the button pressed / released, and how long has it been held for?
142    #[cfg(feature = "timing")]
143    pub timing: Timing,
144}
145
146impl ButtonData {
147    /// The default data for a button that was just pressed.
148    pub const JUST_PRESSED: Self = Self {
149        state: ButtonState::JustPressed,
150        update_state: ButtonState::JustPressed,
151        fixed_update_state: ButtonState::JustPressed,
152        value: 1.0,
153        update_value: 1.0,
154        fixed_update_value: 1.0,
155        #[cfg(feature = "timing")]
156        timing: Timing::NEW,
157    };
158
159    /// The default data for a button that was just released.
160    pub const JUST_RELEASED: Self = Self {
161        state: ButtonState::JustReleased,
162        update_state: ButtonState::JustReleased,
163        fixed_update_state: ButtonState::JustReleased,
164        value: 0.0,
165        update_value: 0.0,
166        fixed_update_value: 0.0,
167        #[cfg(feature = "timing")]
168        timing: Timing::NEW,
169    };
170
171    /// The default data for a button that is released,
172    /// but was not just released.
173    ///
174    /// This is the default state for a button,
175    /// as it avoids surprising behavior when the button is first created.
176    pub const RELEASED: Self = Self {
177        state: ButtonState::Released,
178        update_state: ButtonState::Released,
179        fixed_update_state: ButtonState::Released,
180        value: 0.0,
181        update_value: 0.0,
182        fixed_update_value: 0.0,
183        #[cfg(feature = "timing")]
184        timing: Timing::NEW,
185    };
186
187    /// Is the action currently pressed?
188    #[inline]
189    #[must_use]
190    pub fn pressed(&self) -> bool {
191        self.state.pressed()
192    }
193
194    /// Was the action pressed since the last time it was ticked?
195    #[inline]
196    #[must_use]
197    pub fn just_pressed(&self) -> bool {
198        self.state.just_pressed()
199    }
200
201    /// Is the action currently released?
202    #[inline]
203    #[must_use]
204    pub fn released(&self) -> bool {
205        self.state.released()
206    }
207
208    /// Was the action released since the last time it was ticked?
209    #[inline]
210    #[must_use]
211    pub fn just_released(&self) -> bool {
212        self.state.just_released()
213    }
214
215    /// Convert `self` to a [`ButtonValue`].
216    #[inline]
217    #[must_use]
218    pub fn to_button_value(&self) -> ButtonValue {
219        ButtonValue::new(self.state.pressed(), self.value)
220    }
221}
222
223/// The raw data for an [`ActionState`](super::ActionState) corresponding to a single virtual axis.
224#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, Reflect)]
225pub struct AxisData {
226    /// How far the axis is currently pressed
227    pub value: f32,
228    /// The `value` of the action in the `Main` schedule
229    pub update_value: f32,
230    /// The `value` of the action in the `FixedMain` schedule
231    pub fixed_update_value: f32,
232}
233
234/// The raw data for an [`ActionState`](super::ActionState) corresponding to a pair of virtual axes.
235#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, Reflect)]
236pub struct DualAxisData {
237    /// The XY coordinates of the axis
238    pub pair: Vec2,
239    /// The `pair` of the action in the `Main` schedule
240    pub update_pair: Vec2,
241    /// The `pair` of the action in the `FixedMain` schedule
242    pub fixed_update_pair: Vec2,
243}
244
245/// The raw data for an [`ActionState`](super::ActionState) corresponding to a triple of virtual axes.
246#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, Reflect)]
247pub struct TripleAxisData {
248    /// The XYZ coordinates of the axis
249    pub triple: Vec3,
250    /// The `triple` of the action in the `Main` schedule
251    pub update_triple: Vec3,
252    /// The `triple` of the action in the `FixedMain` schedule
253    pub fixed_update_triple: Vec3,
254}