Skip to content

Commit

Permalink
Add Multiple variant to the Axis enum
Browse files Browse the repository at this point in the history
  • Loading branch information
MilanVasko committed Jun 28, 2020
1 parent 059d640 commit fd2276b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 22 deletions.
19 changes: 19 additions & 0 deletions amethyst_input/src/axis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ pub enum Axis {
/// You almost always want this false.
horizontal: bool,
},
/// Represents multiple input alternatives. Allows to bind more than one input to a single axis.
Multiple(Vec<Axis>),
}

pub(super) enum Conflict {
Expand All @@ -52,6 +54,14 @@ pub(super) enum Conflict {
}

impl Axis {
pub(super) fn conflicts_with_button(&self, other: &Button) -> bool {
match self {
Axis::Emulated { pos, neg } => other == pos || other == neg,
Axis::Multiple(axes) => axes.iter().any(|a| a.conflicts_with_button(other)),
_ => false,
}
}

pub(super) fn conflicts_with_axis(&self, other: &Axis) -> Option<Conflict> {
match self {
Axis::Emulated {
Expand Down Expand Up @@ -98,6 +108,15 @@ impl Axis {
}
}
}
Axis::Multiple(axes) => {
if let Some(inner_conflict) = axes
.iter()
.map(|a| a.conflicts_with_axis(other))
.find(|x| x.is_some())
{
return inner_conflict;
}
}
}
None
}
Expand Down
20 changes: 12 additions & 8 deletions amethyst_input/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,16 @@ impl BindingTypes for StringBindings {
/// pos: Key(Up),
/// neg: Key(Down)
/// ),
/// "leftright": Emulated(
/// pos: Key(Right),
/// neg: Key(Left)
/// )
/// "leftright": Multiple([ // Multiple bindings for one axis
/// Emulated(
/// pos: Key(Right),
/// neg: Key(Left)
/// ),
/// Emulated(
/// pos: Key(D),
/// neg: Key(A)
/// )
/// ])
/// },
/// actions: {
/// "fire": [ [Mouse(Left)], [Key(X)] ], // Multiple bindings for one action
Expand Down Expand Up @@ -426,10 +432,8 @@ impl<T: BindingTypes> Bindings<T> {
}
if bind.len() == 1 {
for (k, a) in self.axes.iter() {
if let Axis::Emulated { pos, neg } = a {
if bind[0] == *pos || bind[0] == *neg {
return Err(BindingError::ButtonBoundToAxis(k.clone(), a.clone()));
}
if a.conflicts_with_button(&bind[0]) {
return Err(BindingError::ButtonBoundToAxis(k.clone(), a.clone()));
}
}
}
Expand Down
37 changes: 23 additions & 14 deletions amethyst_input/src/input_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,15 +518,10 @@ where
}
}

/// Returns the value of an axis by the id, if the id doesn't exist this returns None.
pub fn axis_value<A>(&self, id: &A) -> Option<f32>
where
T::Axis: Borrow<A>,
A: Hash + Eq + ?Sized,
{
self.bindings.axes.get(id).map(|a| match *a {
fn axis_value_impl(&self, a: &Axis) -> f32 {
match a {
Axis::Emulated { pos, neg, .. } => {
match (self.button_is_down(pos), self.button_is_down(neg)) {
match (self.button_is_down(*pos), self.button_is_down(*neg)) {
(true, false) => 1.0,
(false, true) => -1.0,
_ => 0.0,
Expand All @@ -541,10 +536,10 @@ where
} => self
.controller_axes
.iter()
.find(|&&(id, a, _)| id == controller_id && a == axis)
.map(|&(_, _, val)| if invert { -val } else { val })
.find(|&&(id, a, _)| id == *controller_id && a == *axis)
.map(|&(_, _, val)| if *invert { -val } else { val })
.map(|val| {
let dead_zone = dead_zone as f32;
let dead_zone = *dead_zone as f32;
if val < -dead_zone {
(val + dead_zone) / (1.0 - dead_zone)
} else if val > dead_zone {
Expand All @@ -569,7 +564,7 @@ where

let rel_delta = delta / radius;

if over_extendable {
if *over_extendable {
rel_delta
} else if rel_delta > 1. {
1.
Expand All @@ -579,8 +574,22 @@ where
rel_delta
}
}
Axis::MouseWheel { horizontal } => self.mouse_wheel_value(horizontal),
})
Axis::MouseWheel { horizontal } => self.mouse_wheel_value(*horizontal),
Axis::Multiple(axes) => axes
.iter()
.map(|a| self.axis_value_impl(a))
.max_by(|x, y| x.abs().partial_cmp(&y.abs()).unwrap())
.unwrap_or(0.0),
}
}

/// Returns the value of an axis by the id, if the id doesn't exist this returns None.
pub fn axis_value<A>(&self, id: &A) -> Option<f32>
where
T::Axis: Borrow<A>,
A: Hash + Eq + ?Sized,
{
self.bindings.axes.get(id).map(|a| self.axis_value_impl(a))
}

/// Returns true if any of the actions bindings is down.
Expand Down

0 comments on commit fd2276b

Please sign in to comment.