gilrs/ev/
state.rs

1// Copyright 2016-2018 Mateusz Sieczko and other GilRs Developers
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use crate::ev::Code;
9
10use fnv::FnvHashMap;
11
12use std::collections::hash_map;
13use std::iter::Iterator;
14use std::time::SystemTime;
15
16/// Cached gamepad state.
17#[derive(Clone, Debug)]
18pub struct GamepadState {
19    // Indexed by EvCode (nec)
20    buttons: FnvHashMap<Code, ButtonData>,
21    // Indexed by EvCode (nec)
22    axes: FnvHashMap<Code, AxisData>,
23}
24
25impl GamepadState {
26    pub(crate) fn new() -> Self {
27        GamepadState {
28            buttons: FnvHashMap::default(),
29            axes: FnvHashMap::default(),
30        }
31    }
32
33    /// Returns `true` if given button is pressed. Returns `false` if there is no information about
34    /// `btn` or it is not pressed.
35    pub fn is_pressed(&self, btn: Code) -> bool {
36        self.buttons
37            .get(&btn)
38            .map(|s| s.is_pressed())
39            .unwrap_or(false)
40    }
41
42    /// Returns value of `el` or 0.0 when there is no information about it. `el` can be either axis
43    /// or button.
44    pub fn value(&self, el: Code) -> f32 {
45        self.axes
46            .get(&el)
47            .map(|s| s.value())
48            .or_else(|| self.buttons.get(&el).map(|s| s.value()))
49            .unwrap_or(0.0)
50    }
51
52    /// Iterate over buttons data.
53    pub fn buttons(&self) -> ButtonDataIter<'_> {
54        ButtonDataIter(self.buttons.iter())
55    }
56
57    /// Iterate over axes data.
58    pub fn axes(&self) -> AxisDataIter<'_> {
59        AxisDataIter(self.axes.iter())
60    }
61
62    /// Returns button state and when it changed.
63    pub fn button_data(&self, btn: Code) -> Option<&ButtonData> {
64        self.buttons.get(&btn)
65    }
66
67    /// Returns axis state and when it changed.
68    pub fn axis_data(&self, axis: Code) -> Option<&AxisData> {
69        self.axes.get(&axis)
70    }
71
72    pub(crate) fn set_btn_pressed(
73        &mut self,
74        btn: Code,
75        pressed: bool,
76        counter: u64,
77        timestamp: SystemTime,
78    ) {
79        let data = self.buttons.entry(btn).or_insert_with(|| {
80            ButtonData::new(
81                if pressed { 1.0 } else { 0.0 },
82                pressed,
83                false,
84                counter,
85                timestamp,
86            )
87        });
88        data.is_pressed = pressed;
89        data.is_repeating = false;
90        data.counter = counter;
91        data.last_event_ts = timestamp;
92    }
93
94    pub(crate) fn set_btn_repeating(&mut self, btn: Code, counter: u64, timestamp: SystemTime) {
95        let data = self
96            .buttons
97            .entry(btn)
98            .or_insert_with(|| ButtonData::new(1.0, true, true, counter, timestamp));
99        data.is_repeating = true;
100        data.counter = counter;
101        data.last_event_ts = timestamp;
102    }
103
104    pub(crate) fn set_btn_value(
105        &mut self,
106        btn: Code,
107        value: f32,
108        counter: u64,
109        timestamp: SystemTime,
110    ) {
111        let data = self
112            .buttons
113            .entry(btn)
114            .or_insert_with(|| ButtonData::new(value, false, false, counter, timestamp));
115        data.value = value;
116        data.counter = counter;
117        data.last_event_ts = timestamp;
118    }
119
120    pub(crate) fn update_axis(&mut self, axis: Code, data: AxisData) {
121        self.axes.insert(axis, data);
122    }
123}
124
125/// Iterator over `ButtonData`.
126pub struct ButtonDataIter<'a>(hash_map::Iter<'a, Code, ButtonData>);
127
128/// Iterator over `AxisData`.
129pub struct AxisDataIter<'a>(hash_map::Iter<'a, Code, AxisData>);
130
131impl<'a> Iterator for ButtonDataIter<'a> {
132    type Item = (Code, &'a ButtonData);
133
134    fn next(&mut self) -> Option<Self::Item> {
135        self.0.next().map(|(k, v)| (*k, v))
136    }
137}
138
139impl<'a> Iterator for AxisDataIter<'a> {
140    type Item = (Code, &'a AxisData);
141
142    fn next(&mut self) -> Option<Self::Item> {
143        self.0.next().map(|(k, v)| (*k, v))
144    }
145}
146
147/// Information about button stored in `State`.
148#[derive(Clone, Copy, Debug)]
149pub struct ButtonData {
150    last_event_ts: SystemTime,
151    counter: u64,
152    value: f32,
153    is_pressed: bool,
154    is_repeating: bool,
155}
156
157impl ButtonData {
158    pub(crate) fn new(
159        value: f32,
160        pressed: bool,
161        repeating: bool,
162        counter: u64,
163        time: SystemTime,
164    ) -> Self {
165        ButtonData {
166            last_event_ts: time,
167            counter,
168            value,
169            is_pressed: pressed,
170            is_repeating: repeating,
171        }
172    }
173
174    /// Returns `true` if button is pressed.
175    pub fn is_pressed(&self) -> bool {
176        self.is_pressed
177    }
178
179    /// Returns value of button.
180    pub fn value(&self) -> f32 {
181        self.value
182    }
183
184    /// Returns `true` if button is repeating.
185    pub fn is_repeating(&self) -> bool {
186        self.is_repeating
187    }
188
189    /// Returns value of counter when button state last changed.
190    pub fn counter(&self) -> u64 {
191        self.counter
192    }
193
194    /// Returns when button state last changed.
195    pub fn timestamp(&self) -> SystemTime {
196        self.last_event_ts
197    }
198}
199
200/// Information about axis stored in `State`.
201#[derive(Clone, Copy, Debug)]
202pub struct AxisData {
203    last_event_ts: SystemTime,
204    last_event_c: u64,
205    value: f32,
206}
207
208impl AxisData {
209    pub(crate) fn new(value: f32, counter: u64, time: SystemTime) -> Self {
210        AxisData {
211            last_event_ts: time,
212            last_event_c: counter,
213            value,
214        }
215    }
216    /// Returns value of axis.
217    pub fn value(&self) -> f32 {
218        self.value
219    }
220
221    /// Returns value of counter when axis value last changed.
222    pub fn counter(&self) -> u64 {
223        self.last_event_c
224    }
225
226    /// Returns when axis value last changed.
227    pub fn timestamp(&self) -> SystemTime {
228        self.last_event_ts
229    }
230}