use bevy::prelude::*;
use crate::prelude::*;
#[derive(Component, Reflect, Debug, Clone, Copy)]
pub struct Negate {
pub x: bool,
pub y: bool,
pub z: bool,
}
impl Negate {
#[must_use]
pub const fn splat(invert: bool) -> Self {
Self {
x: invert,
y: invert,
z: invert,
}
}
#[must_use]
pub const fn none() -> Self {
Self::splat(false)
}
#[must_use]
pub const fn all() -> Self {
Self::splat(true)
}
#[must_use]
pub const fn x() -> Self {
Self {
x: true,
..Self::none()
}
}
#[must_use]
pub const fn y() -> Self {
Self {
y: true,
..Self::none()
}
}
#[must_use]
pub const fn z() -> Self {
Self {
z: true,
..Self::none()
}
}
}
impl InputModifier for Negate {
fn transform(
&mut self,
_actions: &ActionsQuery,
_time: &ContextTime,
value: ActionValue,
) -> ActionValue {
match value {
ActionValue::Bool(value) => {
let value = if value { 1.0 } else { 0.0 };
self.transform(_actions, _time, value.into())
}
ActionValue::Axis1D(value) => {
if self.x {
(-value).into()
} else {
value.into()
}
}
ActionValue::Axis2D(mut value) => {
if self.x {
value.x = -value.x;
}
if self.y {
value.y = -value.y;
}
value.into()
}
ActionValue::Axis3D(mut value) => {
if self.x {
value.x = -value.x;
}
if self.y {
value.y = -value.y;
}
if self.z {
value.z = -value.z;
}
value.into()
}
}
}
}
#[cfg(test)]
mod tests {
use bevy::prelude::*;
use super::*;
use crate::context;
#[test]
fn x() {
let (world, mut state) = context::init_world();
let (time, actions) = state.get(&world);
let mut modifier = Negate::x();
assert_eq!(
modifier.transform(&actions, &time, true.into()),
(-1.0).into()
);
assert_eq!(
modifier.transform(&actions, &time, false.into()),
0.0.into()
);
assert_eq!(
modifier.transform(&actions, &time, 0.5.into()),
(-0.5).into()
);
assert_eq!(
modifier.transform(&actions, &time, Vec2::ONE.into()),
(-1.0, 1.0).into()
);
assert_eq!(
modifier.transform(&actions, &time, Vec3::ONE.into()),
(-1.0, 1.0, 1.0).into(),
);
}
#[test]
fn y() {
let (world, mut state) = context::init_world();
let (time, actions) = state.get(&world);
let mut modifier = Negate::y();
assert_eq!(modifier.transform(&actions, &time, true.into()), 1.0.into());
assert_eq!(
modifier.transform(&actions, &time, false.into()),
0.0.into()
);
assert_eq!(modifier.transform(&actions, &time, 0.5.into()), 0.5.into());
assert_eq!(
modifier.transform(&actions, &time, Vec2::ONE.into()),
(1.0, -1.0).into()
);
assert_eq!(
modifier.transform(&actions, &time, Vec3::ONE.into()),
(1.0, -1.0, 1.0).into(),
);
}
#[test]
fn z() {
let (world, mut state) = context::init_world();
let (time, actions) = state.get(&world);
let mut modifier = Negate::z();
assert_eq!(modifier.transform(&actions, &time, true.into()), 1.0.into());
assert_eq!(
modifier.transform(&actions, &time, false.into()),
0.0.into()
);
assert_eq!(modifier.transform(&actions, &time, 0.5.into()), 0.5.into());
assert_eq!(
modifier.transform(&actions, &time, Vec2::ONE.into()),
Vec2::ONE.into()
);
assert_eq!(
modifier.transform(&actions, &time, Vec3::ONE.into()),
(1.0, 1.0, -1.0).into(),
);
}
#[test]
fn all() {
let (world, mut state) = context::init_world();
let (time, actions) = state.get(&world);
let mut modifier = Negate::all();
assert_eq!(
modifier.transform(&actions, &time, true.into()),
(-1.0).into()
);
assert_eq!(
modifier.transform(&actions, &time, false.into()),
0.0.into()
);
assert_eq!(
modifier.transform(&actions, &time, 0.5.into()),
(-0.5).into()
);
assert_eq!(
modifier.transform(&actions, &time, Vec2::ONE.into()),
Vec2::NEG_ONE.into(),
);
assert_eq!(
modifier.transform(&actions, &time, Vec3::ONE.into()),
Vec3::NEG_ONE.into(),
);
}
}