pawkit_input/
manager.rs

1use std::sync::{Arc, RwLock};
2
3use num_enum::TryFromPrimitive;
4use pawkit_bitarray::BitArray;
5use pawkit_holy_array::HolyArray;
6use serde::{Deserialize, Serialize};
7
8#[repr(u8)]
9#[derive(
10    Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, TryFromPrimitive,
11)]
12pub enum InputFamily {
13    Keyboard,
14    Mouse,
15    Gamepad,
16}
17
18impl InputFamily {
19    pub fn digital_count(&self) -> usize {
20        return match self {
21            Self::Keyboard => 120,
22            Self::Mouse => 5,
23            Self::Gamepad => 26,
24        };
25    }
26
27    pub fn analog_count(&self) -> usize {
28        return match self {
29            Self::Keyboard => 0,
30            Self::Mouse => 4,
31            Self::Gamepad => 6,
32        };
33    }
34}
35
36pub struct InputDeviceManager {
37    family: InputFamily,
38    devices: RwLock<HolyArray<Arc<InputDeviceState>>>,
39}
40
41pub struct InputDeviceState {
42    raw_id: usize,
43    pub digital_inputs: RwLock<BitArray>,
44    pub analog_inputs: RwLock<Box<[f32]>>,
45}
46
47impl InputDeviceManager {
48    pub fn new(family: InputFamily) -> Self {
49        return Self {
50            family,
51            devices: RwLock::new(HolyArray::new()),
52        };
53    }
54
55    pub fn raw_id_to_id(&self, raw_id: usize) -> Option<usize> {
56        let devices = self.devices.read().ok()?;
57
58        for id in 0..devices.len() {
59            let Some(device) = devices.get(id) else {
60                continue;
61            };
62
63            if device.raw_id == raw_id {
64                return Some(id);
65            }
66        }
67
68        return None;
69    }
70
71    pub fn device_connected(&self, raw_id: usize) -> usize {
72        let mut devices = self.devices.write().unwrap();
73
74        return devices.acquire(Arc::new(InputDeviceState {
75            raw_id,
76            digital_inputs: RwLock::new(BitArray::new(self.family.digital_count())),
77            analog_inputs: RwLock::new(vec![0f32; self.family.analog_count()].into_boxed_slice()),
78        }));
79    }
80
81    pub fn device_disconnected(&self, id: usize) {
82        let mut devices = self.devices.write().unwrap();
83
84        devices.release(id);
85    }
86
87    pub fn device_disconnected_raw(&self, raw_id: usize) {
88        let Some(id) = self.raw_id_to_id(raw_id) else {
89            return;
90        };
91
92        self.device_disconnected(id);
93    }
94
95    pub fn get_state(&self, id: usize) -> Option<Arc<InputDeviceState>> {
96        let devices = self.devices.read().ok()?;
97
98        return devices.get(id).map(Arc::clone);
99    }
100
101    pub fn get_state_raw(&self, raw_id: usize) -> Option<Arc<InputDeviceState>> {
102        let Some(id) = self.raw_id_to_id(raw_id) else {
103            return None;
104        };
105
106        return self.get_state(id);
107    }
108}
109
110impl InputDeviceState {
111    pub fn get_analog(&self, axis: usize) -> f32 {
112        let analog = self.analog_inputs.read().unwrap();
113
114        return analog[axis];
115    }
116
117    pub fn get_digital(&self, button: usize) -> bool {
118        let digital = self.digital_inputs.read().unwrap();
119
120        return digital.get(button).unwrap();
121    }
122
123    pub fn set_analog(&self, axis: usize, value: f32) {
124        let mut analog = self.analog_inputs.write().unwrap();
125
126        analog[axis] = value
127    }
128
129    pub fn set_digital(&self, button: usize, value: bool) {
130        let mut digital = self.digital_inputs.write().unwrap();
131
132        if value {
133            digital.set(button);
134        } else {
135            digital.reset(button);
136        }
137    }
138}