pub mod events;
pub mod fns;
pub mod mock;
pub mod relationship;
pub mod value;
use core::{any, fmt::Debug};
use bevy::prelude::*;
#[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize};
use crate::prelude::*;
use fns::ActionFns;
#[derive(Component, Deref, DerefMut)]
#[require(
Name::new(any::type_name::<A>()),
ActionFns::new::<A>(),
ActionValue::zero(A::Output::DIM),
ActionSettings,
TriggerState,
ActionEvents,
ActionTime,
ActionMock,
)]
pub struct Action<A: InputAction>(A::Output);
impl<A: InputAction> Clone for Action<A> {
fn clone(&self) -> Self {
*self
}
}
impl<A: InputAction> Copy for Action<A> {}
impl<A: InputAction> Default for Action<A> {
fn default() -> Self {
Self(Default::default())
}
}
impl<A: InputAction> PartialEq for Action<A> {
fn eq(&self, other: &Self) -> bool {
**self == **other
}
}
impl<A: InputAction> Action<A> {
pub fn new() -> Self {
Self::default()
}
}
pub trait InputAction: 'static {
type Output: ActionOutput;
}
pub trait ActionOutput:
From<ActionValue> + Default + Send + Sync + Debug + Clone + Copy + PartialEq
{
const DIM: ActionValueDim;
}
impl ActionOutput for bool {
const DIM: ActionValueDim = ActionValueDim::Bool;
}
impl ActionOutput for f32 {
const DIM: ActionValueDim = ActionValueDim::Axis1D;
}
impl ActionOutput for Vec2 {
const DIM: ActionValueDim = ActionValueDim::Axis2D;
}
impl ActionOutput for Vec3 {
const DIM: ActionValueDim = ActionValueDim::Axis3D;
}
#[derive(Component, Default, Debug, Clone, Copy)]
#[cfg_attr(
feature = "reflect",
derive(Reflect),
reflect(Clone, Component, Debug, Default)
)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[cfg_attr(
all(feature = "reflect", feature = "serialize"),
reflect(Serialize, Deserialize)
)]
pub struct ActionSettings {
pub accumulation: Accumulation,
pub require_reset: bool,
pub consume_input: bool,
}
#[derive(Debug, Default, Clone, Copy)]
#[cfg_attr(feature = "reflect", derive(Reflect), reflect(Clone, Debug, Default))]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[cfg_attr(
all(feature = "reflect", feature = "serialize"),
reflect(Serialize, Deserialize)
)]
pub enum Accumulation {
#[default]
Cumulative,
MaxAbs,
}
#[derive(Component, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
#[cfg_attr(
feature = "reflect",
derive(Reflect),
reflect(Clone, Component, Debug, Default, PartialEq)
)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[cfg_attr(
all(feature = "reflect", feature = "serialize"),
reflect(Serialize, Deserialize)
)]
pub enum TriggerState {
#[default]
None,
Ongoing,
Fired,
}
#[deprecated(since = "0.23.3", note = "Renamed to `TriggerState`")]
pub type ActionState = TriggerState;
#[derive(Component, Debug, Default, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "reflect",
derive(Reflect),
reflect(Clone, Component, Debug, Default, PartialEq)
)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[cfg_attr(
all(feature = "reflect", feature = "serialize"),
reflect(Serialize, Deserialize)
)]
pub struct ActionTime {
pub elapsed_secs: f32,
pub fired_secs: f32,
}
impl ActionTime {
pub fn update(&mut self, delta_secs: f32, state: TriggerState) {
match state {
TriggerState::None => {
self.elapsed_secs = 0.0;
self.fired_secs = 0.0;
}
TriggerState::Ongoing => {
self.elapsed_secs += delta_secs;
self.fired_secs = 0.0;
}
TriggerState::Fired => {
self.elapsed_secs += delta_secs;
self.fired_secs += delta_secs;
}
}
}
}