Skip to main content

amethyst_input/
axis.rs

1use serde::{Deserialize, Serialize};
2
3use super::{Button, ControllerAxis, MouseAxis};
4
5/// Represents any input represented by a float value from -1 to 1.
6/// Retrieve the value of this with [axis_value](struct.InputHandler.html#method.axis_value).
7#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
8pub enum Axis {
9    /// Represents an emulated analogue axis made up of pair of digital inputs,
10    /// like W and S keyboard buttons or `DPadUp` and `DPadDown` controller buttons.
11    Emulated {
12        /// Positive button, when pressed down axis value will return 1 if `neg` is not pressed down.
13        pos: Button,
14        /// Negative button, when pressed down axis value will return -1 if `pos` is not pressed down.
15        neg: Button,
16    },
17    /// Represents an analogue axis of a controller.
18    Controller {
19        /// A number representing a specific controller, assigned and reused in order of connection.
20        controller_id: u32,
21        /// The axis being bound
22        axis: ControllerAxis,
23        /// Whether or not to multiply the axis value by -1.
24        invert: bool,
25        /// Treat input values from -dead_zone to dead_zone as 0,
26        /// linearly interpolate remaining ranges.
27        dead_zone: f64,
28    },
29    /// Represents a mouse as a 2D input device
30    Mouse {
31        /// The axis being bound
32        axis: MouseAxis,
33        /// Should the API be allowed to return values outside [-1..1]?
34        over_extendable: bool,
35        /// Zone to which the movement is relative
36        radius: f32,
37    },
38    /// Represents the wheel on a PC mouse.
39    MouseWheel {
40        /// If this value is true then this axis is for the horizontal mouse wheel rather than the vertical mouse wheel.
41        ///
42        /// You almost always want this false.
43        horizontal: bool,
44    },
45    /// Represents multiple input alternatives. Allows to bind more than one input to a single axis.
46    Multiple(Vec<Axis>),
47}
48
49pub(super) enum Conflict {
50    Button,
51    ControllerAxis,
52    MouseAxis,
53    MouseWheelAxis,
54}
55
56impl Axis {
57    pub(super) fn conflicts_with_button(&self, other: &Button) -> bool {
58        match self {
59            Axis::Emulated { pos, neg } => other == pos || other == neg,
60            Axis::Multiple(axes) => axes.iter().any(|a| a.conflicts_with_button(other)),
61            _ => false,
62        }
63    }
64
65    pub(super) fn conflicts_with_axis(&self, other: &Axis) -> Option<Conflict> {
66        if let Axis::Multiple(axes) = other {
67            if let Some(inner_conflict) = axes
68                .iter()
69                .map(|a| self.conflicts_with_axis(a))
70                .find(|x| x.is_some())
71            {
72                return inner_conflict;
73            }
74        }
75
76        match self {
77            Axis::Emulated {
78                pos: ref self_pos,
79                neg: ref self_neg,
80            } => {
81                if let Axis::Emulated { pos, neg } = other {
82                    if self_pos == pos || self_pos == neg || self_neg == pos || self_neg == neg {
83                        return Some(Conflict::Button);
84                    }
85                }
86            }
87            Axis::Controller {
88                controller_id: ref self_controller_id,
89                axis: ref self_axis,
90                ..
91            } => {
92                if let Axis::Controller {
93                    controller_id,
94                    axis,
95                    ..
96                } = other
97                {
98                    if self_controller_id == controller_id && self_axis == axis {
99                        return Some(Conflict::ControllerAxis);
100                    }
101                }
102            }
103            Axis::Mouse {
104                axis: self_axis, ..
105            } => {
106                if let Axis::Mouse { axis, .. } = other {
107                    if self_axis == axis {
108                        return Some(Conflict::MouseAxis);
109                    }
110                }
111            }
112            Axis::MouseWheel {
113                horizontal: self_horizontal,
114            } => {
115                if let Axis::MouseWheel { horizontal } = other {
116                    if self_horizontal == horizontal {
117                        return Some(Conflict::MouseWheelAxis);
118                    }
119                }
120            }
121            Axis::Multiple(axes) => {
122                if let Some(inner_conflict) = axes
123                    .iter()
124                    .map(|a| a.conflicts_with_axis(other))
125                    .find(|x| x.is_some())
126                {
127                    return inner_conflict;
128                }
129            }
130        }
131        None
132    }
133}