fantasy_craft/input/
manager.rs1use std::collections::HashMap;
2use macroquad::prelude::*;
3
4#[derive(Debug, Clone, Copy, PartialEq)]
5pub enum InputVariant {
6 Key(KeyCode),
7 Mouse(MouseButton)
8}
9
10#[derive(Debug, Clone, Copy, PartialEq)]
11pub enum KeyboardLayout {
12 Qwerty,
13 Azerty,
14}
15
16pub struct InputManager {
17 bindings: HashMap<String, Vec<InputVariant>>,
18 pub layout: KeyboardLayout,
21}
22
23impl Default for InputManager {
24 fn default() -> Self {
25 Self {
26 bindings: HashMap::new(),
27 layout: KeyboardLayout::Qwerty, }
29 }
30}
31
32impl InputManager {
33 pub fn new() -> Self {
34 Self::default()
35 }
36
37 pub fn set_layout(&mut self, layout: KeyboardLayout) {
38 self.layout = layout;
39 info!("InputManager: Keyboard layout set to {:?}", layout);
42 }
43
44 pub fn bind(&mut self, action: &str, input: InputVariant) {
45 self.bindings
46 .entry(action.to_string())
47 .or_insert_with(Vec::new)
48 .push(input);
49 }
50
51 pub fn load_from_string(&mut self, json_content: &str) {
53 let json_bindings: HashMap<String, Vec<String>> = match serde_json::from_str(json_content) {
54 Ok(data) => data,
55 Err(e) => {
56 error!("InputManager: Failed to parse bindings JSON. Error: {}", e);
57 return;
58 }
59 };
60
61 self.bindings.clear();
63
64 for (action, inputs) in json_bindings {
65 for input_str in inputs {
66 let variants = self.parse_input_string(&input_str);
67
68 if variants.is_empty() {
69 warn!("InputManager: Unknown input key '{}' for action '{}'", input_str, action);
70 }
71
72 for variant in variants {
73 self.bind(&action, variant);
74 }
75 }
76 }
77 info!("InputManager: Bindings loaded.");
78 }
79
80 pub fn is_action_down(&self, action: &str) -> bool {
81 if let Some(inputs) = self.bindings.get(action) {
82 for input in inputs {
83 match input {
84 InputVariant::Key(k) => if is_key_down(*k) { return true; },
85 InputVariant::Mouse(b) => if is_mouse_button_down(*b) { return true; }
86 }
87 }
88 }
89 false
90 }
91
92 pub fn is_action_just_pressed(&self, action: &str) -> bool {
93 if let Some(inputs) = self.bindings.get(action) {
94 for input in inputs {
95 match input {
96 InputVariant::Key(k) => if is_key_pressed(*k) { return true; },
97 InputVariant::Mouse(b) => if is_mouse_button_pressed(*b) { return true; }
98 }
99 }
100 }
101 false
102 }
103
104 fn parse_input_string(&self, s: &str) -> Vec<InputVariant> {
106 let mut variants = Vec::new();
107
108 let use_azerty_mapping = {
112 #[cfg(target_arch = "wasm32")]
113 { false }
114 #[cfg(not(target_arch = "wasm32"))]
115 { self.layout == KeyboardLayout::Azerty }
116 };
117
118 match s {
119 "MouseLeft" => variants.push(InputVariant::Mouse(MouseButton::Left)),
121 "MouseRight" => variants.push(InputVariant::Mouse(MouseButton::Right)),
122 "MouseMiddle" => variants.push(InputVariant::Mouse(MouseButton::Middle)),
123
124 "W" | "ScanCodeW" => {
128 if use_azerty_mapping {
129 variants.push(InputVariant::Key(KeyCode::Z)); } else {
131 variants.push(InputVariant::Key(KeyCode::W)); }
133 },
134
135 "A" | "ScanCodeA" => {
136 if use_azerty_mapping {
137 variants.push(InputVariant::Key(KeyCode::Q));
138 } else {
139 variants.push(InputVariant::Key(KeyCode::A));
140 }
141 },
142
143 "Z" | "ScanCodeZ" => {
144 if use_azerty_mapping {
145 variants.push(InputVariant::Key(KeyCode::W));
146 } else {
147 variants.push(InputVariant::Key(KeyCode::Z));
148 }
149 },
150
151 "Q" | "ScanCodeQ" => {
152 if use_azerty_mapping {
153 variants.push(InputVariant::Key(KeyCode::A));
154 } else {
155 variants.push(InputVariant::Key(KeyCode::Q));
156 }
157 },
158
159 "M" => {
160 if use_azerty_mapping {
161 variants.push(InputVariant::Key(KeyCode::M));
166 } else {
167 variants.push(InputVariant::Key(KeyCode::M));
168 }
169 },
170
171 "S" | "ScanCodeS" => variants.push(InputVariant::Key(KeyCode::S)),
173 "D" | "ScanCodeD" => variants.push(InputVariant::Key(KeyCode::D)),
174
175 "Space" => variants.push(InputVariant::Key(KeyCode::Space)),
176 "Escape" => variants.push(InputVariant::Key(KeyCode::Escape)),
177 "Enter" => variants.push(InputVariant::Key(KeyCode::Enter)),
178 "Tab" => variants.push(InputVariant::Key(KeyCode::Tab)),
179 "LeftShift" => variants.push(InputVariant::Key(KeyCode::LeftShift)),
180 "RightShift" => variants.push(InputVariant::Key(KeyCode::RightShift)),
181 "LeftControl" => variants.push(InputVariant::Key(KeyCode::LeftControl)),
182 "RightControl" => variants.push(InputVariant::Key(KeyCode::RightControl)),
183
184 "Up" => variants.push(InputVariant::Key(KeyCode::Up)),
185 "Down" => variants.push(InputVariant::Key(KeyCode::Down)),
186 "Left" => variants.push(InputVariant::Key(KeyCode::Left)),
187 "Right" => variants.push(InputVariant::Key(KeyCode::Right)),
188
189 "B" => variants.push(InputVariant::Key(KeyCode::B)),
191 "C" => variants.push(InputVariant::Key(KeyCode::C)),
192 "E" => variants.push(InputVariant::Key(KeyCode::E)),
193 "F" => variants.push(InputVariant::Key(KeyCode::F)),
194 "G" => variants.push(InputVariant::Key(KeyCode::G)),
195 "H" => variants.push(InputVariant::Key(KeyCode::H)),
196 "I" => variants.push(InputVariant::Key(KeyCode::I)),
197 "J" => variants.push(InputVariant::Key(KeyCode::J)),
198 "K" => variants.push(InputVariant::Key(KeyCode::K)),
199 "L" => variants.push(InputVariant::Key(KeyCode::L)),
200 "N" => variants.push(InputVariant::Key(KeyCode::N)),
201 "O" => variants.push(InputVariant::Key(KeyCode::O)),
202 "P" => variants.push(InputVariant::Key(KeyCode::P)),
203 "R" => variants.push(InputVariant::Key(KeyCode::R)),
204 "T" => variants.push(InputVariant::Key(KeyCode::T)),
205 "U" => variants.push(InputVariant::Key(KeyCode::U)),
206 "V" => variants.push(InputVariant::Key(KeyCode::V)),
207 "X" => variants.push(InputVariant::Key(KeyCode::X)),
208 "Y" => variants.push(InputVariant::Key(KeyCode::Y)),
209
210 "0" => variants.push(InputVariant::Key(KeyCode::Key0)),
211 "1" => variants.push(InputVariant::Key(KeyCode::Key1)),
212 "2" => variants.push(InputVariant::Key(KeyCode::Key2)),
213 "3" => variants.push(InputVariant::Key(KeyCode::Key3)),
214 "4" => variants.push(InputVariant::Key(KeyCode::Key4)),
215 "5" => variants.push(InputVariant::Key(KeyCode::Key5)),
216 "6" => variants.push(InputVariant::Key(KeyCode::Key6)),
217 "7" => variants.push(InputVariant::Key(KeyCode::Key7)),
218 "8" => variants.push(InputVariant::Key(KeyCode::Key8)),
219 "9" => variants.push(InputVariant::Key(KeyCode::Key9)),
220
221 _ => {},
222 };
223
224 variants
225 }
226}