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}