shine_input/
manager.rs

1use crate::mapping::{InputMapping, Mapping};
2use crate::{ButtonId, Guesture, ModifierFilterMask, ModifierId, State};
3use std::mem;
4
5pub struct Manager {
6    time: u128,
7    mapping: Mapping,
8    guestures: Vec<(String, Box<Guesture>)>,
9    state: State,
10    previous_state: State,
11}
12
13impl Manager {
14    fn now() -> u128 {
15        use std::time::SystemTime;
16        SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_micros()
17    }
18
19    pub fn new() -> Manager {
20        Manager {
21            time: 0,
22            mapping: Mapping::new(),
23            guestures: Vec::new(),
24            state: State::new(),
25            previous_state: State::new(),
26        }
27    }
28
29    pub fn add_guesture<S: ToString>(&mut self, name: S, guesture: Box<Guesture>) {
30        let name: String = name.to_string();
31        assert!(self.guestures.iter().find(|v| v.0 == name).is_none());
32        self.guestures.push((name, guesture));
33    }
34
35    pub fn get_guesture<S: ToString>(&self, name: S) -> Option<&Guesture> {
36        let name = name.to_string();
37        self.guestures
38            .iter()
39            .find_map(|v| if v.0 == name { Some(v.1.as_ref()) } else { None })
40    }
41
42    pub fn get_guesture_mut<S: ToString>(&mut self, name: S) -> Option<&mut Guesture> {
43        let name = name.to_string();
44        let id = self.guestures.iter().position(|v| v.0 == name);
45        match id {
46            None => None,
47            Some(i) => Some(self.guestures[i].1.as_mut()),
48        }
49    }
50
51    pub fn add_modifier_mapping(&mut self, input_event: InputMapping, modifier_id: ModifierId) {
52        self.mapping.add_modifier_mapping(input_event, modifier_id);
53    }
54
55    pub fn add_button_mapping(
56        &mut self,
57        input_event: InputMapping,
58        input_modifiers: Option<ModifierFilterMask>,
59        button_id: ButtonId,
60        sensitivity: f32,
61    ) {
62        self.mapping
63            .add_button_mapping(input_event, input_modifiers, button_id, sensitivity);
64    }
65
66    pub fn get_state(&self) -> &State {
67        &self.state
68    }
69
70    pub fn prepare(&mut self) {
71        self.time = Self::now();
72        mem::swap(&mut self.previous_state, &mut self.state);
73        self.state.prepare(&self.previous_state, self.time);
74    }
75
76    pub fn update(&mut self) {
77        for (_, ref mut guesture) in self.guestures.iter_mut() {
78            guesture.on_update(&self.previous_state, &mut self.state);
79        }
80    }
81
82    pub fn handle_winit_events(&mut self, event: &winit::Event) {
83        use winit::{DeviceEvent, ElementState, Event, WindowEvent};
84
85        // keyboard, button, and mouse position is handled through window events
86        // mouse "delta" movement is handled through device
87
88        match *event {
89            Event::WindowEvent {
90                event: WindowEvent::KeyboardInput { input, .. },
91                ..
92            } => {
93                // handling mapped keyboards
94                log::trace!("winit key: {:?}", input);
95
96                if let Some(modifier_id) = self.mapping.map_winit_key_to_modifier(&input) {
97                    self.state
98                        .set_modifier(modifier_id, input.state == ElementState::Pressed, false);
99                }
100
101                if let Some((button_id, modifier_mask, sensitivity)) = self.mapping.map_winit_key_to_button(&input) {
102                    let value = if input.state == ElementState::Pressed { 1. } else { 0. };
103                    log::trace!(
104                        "mapped winit key: {:?} to axis: {:?},{},{}",
105                        input,
106                        button_id,
107                        value,
108                        value * sensitivity
109                    );
110                    self.state.set_button(button_id, modifier_mask, value * sensitivity, false);
111                }
112            }
113            Event::DeviceEvent {
114                device_id,
115                event: DeviceEvent::Motion { axis, value },
116            } => {
117                log::trace!("winit dev motion: {:?},{:?},{:?}", device_id, axis, value);
118
119                if let Some(modifier_id) = self.mapping.map_winit_axis_to_modifier(device_id, axis) {
120                    self.state.set_modifier(modifier_id, true, true);
121                }
122
123                if let Some((button_id, modifier_mask, sensitivity)) = self.mapping.map_winit_axis_to_button(device_id, axis) {
124                    let value = value as f32;
125                    log::trace!(
126                        "mapping winit axis: {:?},{:?},{:?} to axis: {:?},{},{}",
127                        device_id,
128                        axis,
129                        value,
130                        button_id,
131                        value,
132                        value * sensitivity
133                    );
134                    self.state.set_button(button_id, modifier_mask, value * sensitivity, true);
135                }
136            }
137            Event::DeviceEvent {
138                device_id,
139                event: DeviceEvent::Added,
140            } => {
141                //todo: mapping - add/remove known devices
142                log::trace!("dev added: {:?}", device_id);
143            }
144            _ => {}
145        };
146    }
147
148    pub fn handle_gil_events(&mut self, event: &gilrs::Event) {
149        use gilrs::{Event, EventType};
150
151        let Event { id, event, .. } = event;
152        match event {
153            EventType::AxisChanged(axis, value, ..) => {
154                log::trace!("gil axis {:?},{:?},{:?}", id, axis, value);
155
156                if let Some(modifier_id) = self.mapping.map_gil_axis_to_modifier(*id, *axis) {
157                    self.state.set_modifier(modifier_id, *value != 0., false);
158                }
159
160                if let Some((button_id, modifier_mask, sensitivity)) = self.mapping.map_gil_axis_to_button(*id, *axis) {
161                    log::trace!(
162                        "mapping gil axis: {:?},{:?} to axis: {:?},{},{}",
163                        id,
164                        axis,
165                        button_id,
166                        value,
167                        value * sensitivity
168                    );
169                    self.state.set_button(button_id, modifier_mask, value * sensitivity, false);
170                }
171            }
172            EventType::ButtonChanged(button, value, ..) => {
173                log::trace!("gil button {:?},{:?}", button, value);
174            }
175            _ => {}
176        }
177    }
178}
179
180impl Default for Manager {
181    fn default() -> Manager {
182        Manager::new()
183    }
184}