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    // set the `update_state` to the current `state`
126    pub(super) fn set_update_state_from_state(&mut self) {
127        match self {
128            Self::Button(data) => {
129                data.update_state = data.state;
130                data.update_value = data.value;
131            }
132            Self::Axis(data) => {
133                data.update_value = data.value;
134            }
135            Self::DualAxis(data) => {
136                data.update_pair = data.pair;
137            }
138            Self::TripleAxis(data) => {
139                data.update_triple = data.triple;
140            }
141        }
142    }
143
144    // set the `fixed_update_state` to the current `state`
145    pub(super) fn set_fixed_update_state_from_state(&mut self) {
146        match self {
147            Self::Button(data) => {
148                data.fixed_update_state = data.state;
149                data.fixed_update_value = data.value;
150            }
151            Self::Axis(data) => {
152                data.fixed_update_value = data.value;
153            }
154            Self::DualAxis(data) => {
155                data.fixed_update_pair = data.pair;
156            }
157            Self::TripleAxis(data) => {
158                data.fixed_update_triple = data.triple;
159            }
160        }
161    }
162}
163
164/// Metadata about an [`Buttonlike`](crate::user_input::Buttonlike) action
165#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize, Reflect)]
166pub struct ButtonData {
167    /// Is the action pressed or released?
168    pub state: ButtonState,
169    /// The `state` of the action in the `Main` schedule
170    pub update_state: ButtonState,
171    /// The `state` of the action in the `FixedMain` schedule
172    pub fixed_update_state: ButtonState,
173    /// How far has the button been pressed
174    pub value: f32,
175    /// The `value` of the action in the `Main` schedule
176    pub update_value: f32,
177    /// The `value` of the action in the `FixedMain` schedule
178    pub fixed_update_value: f32,
179    /// When was the button pressed / released, and how long has it been held for?
180    #[cfg(feature = "timing")]
181    pub timing: Timing,
182}
183
184impl ButtonData {
185    /// The default data for a button that was just pressed.
186    pub const JUST_PRESSED: Self = Self {
187        state: ButtonState::JustPressed,
188        update_state: ButtonState::JustPressed,
189        fixed_update_state: ButtonState::JustPressed,
190        value: 1.0,
191        update_value: 1.0,
192        fixed_update_value: 1.0,
193        #[cfg(feature = "timing")]
194        timing: Timing::NEW,
195    };
196
197    /// The default data for a button that was just released.
198    pub const JUST_RELEASED: Self = Self {
199        state: ButtonState::JustReleased,
200        update_state: ButtonState::JustReleased,
201        fixed_update_state: ButtonState::JustReleased,
202        value: 0.0,
203        update_value: 0.0,
204        fixed_update_value: 0.0,
205        #[cfg(feature = "timing")]
206        timing: Timing::NEW,
207    };
208
209    /// The default data for a button that is released,
210    /// but was not just released.
211    ///
212    /// This is the default state for a button,
213    /// as it avoids surprising behavior when the button is first created.
214    pub const RELEASED: Self = Self {
215        state: ButtonState::Released,
216        update_state: ButtonState::Released,
217        fixed_update_state: ButtonState::Released,
218        value: 0.0,
219        update_value: 0.0,
220        fixed_update_value: 0.0,
221        #[cfg(feature = "timing")]
222        timing: Timing::NEW,
223    };
224
225    /// Is the action currently pressed?
226    #[inline]
227    #[must_use]
228    pub fn pressed(&self) -> bool {
229        self.state.pressed()
230    }
231
232    /// Was the action pressed since the last time it was ticked?
233    #[inline]
234    #[must_use]
235    pub fn just_pressed(&self) -> bool {
236        self.state.just_pressed()
237    }
238
239    /// Is the action currently released?
240    #[inline]
241    #[must_use]
242    pub fn released(&self) -> bool {
243        self.state.released()
244    }
245
246    /// Was the action released since the last time it was ticked?
247    #[inline]
248    #[must_use]
249    pub fn just_released(&self) -> bool {
250        self.state.just_released()
251    }
252
253    /// Convert `self` to a [`ButtonValue`].
254    #[inline]
255    #[must_use]
256    pub fn to_button_value(&self) -> ButtonValue {
257        ButtonValue::new(self.state.pressed(), self.value)
258    }
259}
260
261/// The raw data for an [`ActionState`](super::ActionState) corresponding to a single virtual axis.
262#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, Reflect)]
263pub struct AxisData {
264    /// How far the axis is currently pressed
265    pub value: f32,
266    /// The `value` of the action in the `Main` schedule
267    pub update_value: f32,
268    /// The `value` of the action in the `FixedMain` schedule
269    pub fixed_update_value: f32,
270}
271
272/// The raw data for an [`ActionState`](super::ActionState) corresponding to a pair of virtual axes.
273#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, Reflect)]
274pub struct DualAxisData {
275    /// The XY coordinates of the axis
276    pub pair: Vec2,
277    /// The `pair` of the action in the `Main` schedule
278    pub update_pair: Vec2,
279    /// The `pair` of the action in the `FixedMain` schedule
280    pub fixed_update_pair: Vec2,
281}
282
283/// The raw data for an [`ActionState`](super::ActionState) corresponding to a triple of virtual axes.
284#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, Reflect)]
285pub struct TripleAxisData {
286    /// The XYZ coordinates of the axis
287    pub triple: Vec3,
288    /// The `triple` of the action in the `Main` schedule
289    pub update_triple: Vec3,
290    /// The `triple` of the action in the `FixedMain` schedule
291    pub fixed_update_triple: Vec3,
292}