use bevy::{
math::{Vec2, Vec3},
reflect::Reflect,
utils::Instant,
};
use serde::{Deserialize, Serialize};
#[cfg(feature = "timing")]
use crate::timing::Timing;
use crate::{buttonlike::ButtonState, InputControlKind};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Reflect)]
pub struct ActionData {
pub disabled: bool,
pub kind_data: ActionKindData,
}
impl ActionData {
pub fn from_kind(input_control_kind: InputControlKind) -> Self {
Self {
disabled: false,
kind_data: match input_control_kind {
InputControlKind::Button => ActionKindData::Button(ButtonData::default()),
InputControlKind::Axis => ActionKindData::Axis(AxisData::default()),
InputControlKind::DualAxis => ActionKindData::DualAxis(DualAxisData::default()),
InputControlKind::TripleAxis => {
ActionKindData::TripleAxis(TripleAxisData::default())
}
},
}
}
pub fn tick(&mut self, _current_instant: Instant, _previous_instant: Instant) {
match self.kind_data {
ActionKindData::Button(ref mut data) => {
data.state.tick();
#[cfg(feature = "timing")]
data.timing.tick(_current_instant, _previous_instant);
}
ActionKindData::Axis(ref mut _data) => {}
ActionKindData::DualAxis(ref mut _data) => {}
ActionKindData::TripleAxis(ref mut _data) => {}
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Reflect)]
pub enum ActionKindData {
Button(ButtonData),
Axis(AxisData),
DualAxis(DualAxisData),
TripleAxis(TripleAxisData),
}
impl ActionKindData {
pub(super) fn swap_to_update_state(&mut self) {
match self {
Self::Button(data) => {
data.fixed_update_state = data.state;
data.state = data.update_state;
}
Self::Axis(data) => {
data.fixed_update_value = data.value;
data.value = data.update_value;
}
Self::DualAxis(data) => {
data.fixed_update_pair = data.pair;
data.pair = data.update_pair;
}
Self::TripleAxis(data) => {
data.fixed_update_triple = data.triple;
data.triple = data.update_triple;
}
}
}
pub(super) fn swap_to_fixed_update_state(&mut self) {
match self {
Self::Button(data) => {
data.update_state = data.state;
data.state = data.fixed_update_state;
}
Self::Axis(data) => {
data.update_value = data.value;
data.value = data.fixed_update_value;
}
Self::DualAxis(data) => {
data.update_pair = data.pair;
data.pair = data.fixed_update_pair;
}
Self::TripleAxis(data) => {
data.update_triple = data.triple;
data.triple = data.fixed_update_triple;
}
}
}
}
#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize, Reflect)]
pub struct ButtonData {
pub state: ButtonState,
pub update_state: ButtonState,
pub fixed_update_state: ButtonState,
#[cfg(feature = "timing")]
pub timing: Timing,
}
impl ButtonData {
pub const JUST_PRESSED: Self = Self {
state: ButtonState::JustPressed,
update_state: ButtonState::JustPressed,
fixed_update_state: ButtonState::JustPressed,
#[cfg(feature = "timing")]
timing: Timing::NEW,
};
pub const JUST_RELEASED: Self = Self {
state: ButtonState::JustReleased,
update_state: ButtonState::JustReleased,
fixed_update_state: ButtonState::JustReleased,
#[cfg(feature = "timing")]
timing: Timing::NEW,
};
pub const RELEASED: Self = Self {
state: ButtonState::Released,
update_state: ButtonState::Released,
fixed_update_state: ButtonState::Released,
#[cfg(feature = "timing")]
timing: Timing::NEW,
};
#[inline]
#[must_use]
pub fn pressed(&self) -> bool {
self.state.pressed()
}
#[inline]
#[must_use]
pub fn just_pressed(&self) -> bool {
self.state.just_pressed()
}
#[inline]
#[must_use]
pub fn released(&self) -> bool {
self.state.released()
}
#[inline]
#[must_use]
pub fn just_released(&self) -> bool {
self.state.just_released()
}
}
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, Reflect)]
pub struct AxisData {
pub value: f32,
pub update_value: f32,
pub fixed_update_value: f32,
}
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, Reflect)]
pub struct DualAxisData {
pub pair: Vec2,
pub update_pair: Vec2,
pub fixed_update_pair: Vec2,
}
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize, Reflect)]
pub struct TripleAxisData {
pub triple: Vec3,
pub update_triple: Vec3,
pub fixed_update_triple: Vec3,
}