hassium_input/
resource.rs1use crate::{device::InputDevice, Scalar};
2use std::{borrow::Borrow, collections::HashMap};
3
4#[derive(Debug, Clone, Copy, Eq, PartialEq)]
5pub enum TriggerState {
6 Idle,
7 Pressed,
8 Hold,
9 Released,
10}
11
12impl TriggerState {
13 #[inline]
14 pub fn is_on(self) -> bool {
15 self == TriggerState::Pressed || self == TriggerState::Hold
16 }
17
18 #[inline]
19 pub fn is_off(self) -> bool {
20 !self.is_on()
21 }
22}
23
24#[derive(Default)]
25pub struct InputController {
26 devices: HashMap<String, Box<dyn InputDevice>>,
27 mapping_axes: HashMap<String, (String, String)>,
28 mapping_triggers: HashMap<String, (String, String)>,
29 axes: HashMap<String, Scalar>,
30 triggers: HashMap<String, TriggerState>,
31}
32
33impl InputController {
34 pub fn new() -> Self {
35 Self::default()
36 }
37
38 pub fn register<D>(&mut self, mut device: D)
39 where
40 D: InputDevice + 'static,
41 {
42 device.on_register();
43 self.devices
44 .insert(device.name().to_owned(), Box::new(device));
45 }
46
47 pub fn unregister(&mut self, name: &str) -> Option<Box<dyn InputDevice>> {
48 if let Some(mut device) = self.devices.remove(name) {
49 device.on_unregister();
50 Some(device)
51 } else {
52 None
53 }
54 }
55
56 pub fn device(&self, id: &str) -> Option<&dyn InputDevice> {
57 if let Some(device) = self.devices.get(id) {
58 Some(device.borrow())
59 } else {
60 None
61 }
62 }
63
64 pub fn as_device<T>(&self, id: &str) -> Option<&T>
65 where
66 T: InputDevice,
67 {
68 if let Some(device) = self.devices.get(id) {
69 device.as_any().downcast_ref::<T>()
70 } else {
71 None
72 }
73 }
74
75 pub fn map_axis(&mut self, name_from: &str, device: &str, name_to: &str) {
76 self.mapping_axes.insert(
77 name_from.to_owned(),
78 (device.to_owned(), name_to.to_owned()),
79 );
80 }
81
82 pub fn unmap_axis(&mut self, name: &str) {
83 self.mapping_axes.remove(name);
84 }
85
86 pub fn map_trigger(&mut self, name_from: &str, device: &str, name_to: &str) {
87 self.mapping_triggers.insert(
88 name_from.to_owned(),
89 (device.to_owned(), name_to.to_owned()),
90 );
91 }
92
93 pub fn unmap_trigger(&mut self, name: &str) {
94 self.mapping_triggers.remove(name);
95 }
96
97 pub fn axis(&self, name: &str) -> Option<Scalar> {
98 self.axes.get(name).cloned()
99 }
100
101 pub fn axis_or_default(&self, name: &str) -> Scalar {
102 self.axis(name).unwrap_or(0.0)
103 }
104
105 pub fn set_axis(&mut self, name: &str, value: Scalar) {
106 self.axes.insert(name.to_owned(), value);
107 }
108
109 pub fn trigger(&self, name: &str) -> Option<TriggerState> {
110 self.triggers.get(name).cloned()
111 }
112
113 pub fn trigger_or_default(&self, name: &str) -> TriggerState {
114 self.trigger(name).unwrap_or(TriggerState::Idle)
115 }
116
117 pub fn set_trigger(&mut self, name: &str, value: TriggerState) {
118 self.triggers.insert(name.to_owned(), value);
119 }
120
121 pub fn process(&mut self) {
122 for device in self.devices.values_mut() {
123 device.process();
124 }
125 self.axes.clear();
126 self.triggers.clear();
127 for (name_from, (dev, name_to)) in &self.mapping_axes {
128 if let Some(device) = self.devices.get(dev) {
129 if let Some(value) = device.query_axis(name_to) {
130 self.axes.insert(name_from.to_owned(), value);
131 }
132 }
133 }
134 for (name_from, (dev, name_to)) in &self.mapping_triggers {
135 if let Some(device) = self.devices.get(dev) {
136 if let Some(value) = device.query_trigger(name_to) {
137 let prev = self.triggers.get(name_from).unwrap_or(&TriggerState::Idle);
138 match (prev, value) {
139 (TriggerState::Idle, true) | (TriggerState::Released, true) => {
140 self.triggers
141 .insert(name_from.to_owned(), TriggerState::Pressed);
142 }
143 (TriggerState::Pressed, true) | (TriggerState::Pressed, false) => {
144 self.triggers
145 .insert(name_from.to_owned(), TriggerState::Hold);
146 }
147 (TriggerState::Hold, false) => {
148 self.triggers
149 .insert(name_from.to_owned(), TriggerState::Released);
150 }
151 (TriggerState::Released, false) => {
152 self.triggers
153 .insert(name_from.to_owned(), TriggerState::Idle);
154 }
155 _ => {}
156 }
157 }
158 }
159 }
160 }
161}