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}