meru_interface/
key_assign.rs

1use serde::{Deserialize, Serialize};
2use std::fmt::Display;
3
4#[derive(PartialEq, Eq, Copy, Clone, Debug, Serialize, Deserialize)]
5pub enum KeyCode {
6    Key1,
7    Key2,
8    Key3,
9    Key4,
10    Key5,
11    Key6,
12    Key7,
13    Key8,
14    Key9,
15    Key0,
16    A,
17    B,
18    C,
19    D,
20    E,
21    F,
22    G,
23    H,
24    I,
25    J,
26    K,
27    L,
28    M,
29    N,
30    O,
31    P,
32    Q,
33    R,
34    S,
35    T,
36    U,
37    V,
38    W,
39    X,
40    Y,
41    Z,
42    Escape,
43    F1,
44    F2,
45    F3,
46    F4,
47    F5,
48    F6,
49    F7,
50    F8,
51    F9,
52    F10,
53    F11,
54    F12,
55    F13,
56    F14,
57    F15,
58    F16,
59    F17,
60    F18,
61    F19,
62    F20,
63    F21,
64    F22,
65    F23,
66    F24,
67    Snapshot,
68    Scroll,
69    Pause,
70    Insert,
71    Home,
72    Delete,
73    End,
74    PageDown,
75    PageUp,
76    Left,
77    Up,
78    Right,
79    Down,
80    Back,
81    Return,
82    Space,
83    Compose,
84    Caret,
85    Numlock,
86    Numpad0,
87    Numpad1,
88    Numpad2,
89    Numpad3,
90    Numpad4,
91    Numpad5,
92    Numpad6,
93    Numpad7,
94    Numpad8,
95    Numpad9,
96    AbntC1,
97    AbntC2,
98    NumpadAdd,
99    Apostrophe,
100    Apps,
101    Asterisk,
102    Plus,
103    At,
104    Ax,
105    Backslash,
106    Calculator,
107    Capital,
108    Colon,
109    Comma,
110    Convert,
111    NumpadDecimal,
112    NumpadDivide,
113    Equals,
114    Grave,
115    Kana,
116    Kanji,
117    LAlt,
118    LBracket,
119    LControl,
120    LShift,
121    LWin,
122    Mail,
123    MediaSelect,
124    MediaStop,
125    Minus,
126    NumpadMultiply,
127    Mute,
128    MyComputer,
129    NavigateForward,
130    NavigateBackward,
131    NextTrack,
132    NoConvert,
133    NumpadComma,
134    NumpadEnter,
135    NumpadEquals,
136    Oem102,
137    Period,
138    PlayPause,
139    Power,
140    PrevTrack,
141    RAlt,
142    RBracket,
143    RControl,
144    RShift,
145    RWin,
146    Semicolon,
147    Slash,
148    Sleep,
149    Stop,
150    NumpadSubtract,
151    Sysrq,
152    Tab,
153    Underline,
154    Unlabeled,
155    VolumeDown,
156    VolumeUp,
157    Wake,
158    WebBack,
159    WebFavorites,
160    WebForward,
161    WebHome,
162    WebRefresh,
163    WebSearch,
164    WebStop,
165    Yen,
166    Copy,
167    Paste,
168    Cut,
169}
170
171#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
172pub struct GamepadButton {
173    pub gamepad: Gamepad,
174    pub button_type: GamepadButtonType,
175}
176
177impl GamepadButton {
178    pub fn new(gamepad: Gamepad, button_type: GamepadButtonType) -> Self {
179        Self {
180            gamepad,
181            button_type,
182        }
183    }
184}
185
186#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
187pub struct Gamepad {
188    pub id: usize,
189}
190
191impl Gamepad {
192    pub fn new(id: usize) -> Self {
193        Self { id }
194    }
195}
196
197#[derive(PartialEq, Eq, Copy, Clone, Debug, Serialize, Deserialize)]
198pub enum GamepadButtonType {
199    South,
200    East,
201    North,
202    West,
203    C,
204    Z,
205    LeftTrigger,
206    LeftTrigger2,
207    RightTrigger,
208    RightTrigger2,
209    Select,
210    Start,
211    Mode,
212    LeftThumb,
213    RightThumb,
214    DPadUp,
215    DPadDown,
216    DPadLeft,
217    DPadRight,
218}
219
220#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
221pub struct GamepadAxis {
222    pub gamepad: Gamepad,
223    pub axis_type: GamepadAxisType,
224}
225
226impl GamepadAxis {
227    pub fn new(gamepad: Gamepad, axis_type: GamepadAxisType) -> Self {
228        Self { gamepad, axis_type }
229    }
230}
231
232#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
233pub enum GamepadAxisType {
234    LeftStickX,
235    LeftStickY,
236    LeftZ,
237    RightStickX,
238    RightStickY,
239    RightZ,
240}
241
242#[derive(PartialEq, Eq, Default, Clone, Debug, Serialize, Deserialize)]
243pub struct KeyAssign(pub Vec<MultiKey>);
244
245impl From<SingleKey> for KeyAssign {
246    fn from(key: SingleKey) -> Self {
247        KeyAssign(vec![MultiKey(vec![key])])
248    }
249}
250
251#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
252pub struct MultiKey(pub Vec<SingleKey>);
253
254#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
255pub enum SingleKey {
256    KeyCode(KeyCode),
257    GamepadButton(GamepadButton),
258    GamepadAxis(GamepadAxis, GamepadAxisDir),
259}
260
261#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
262pub enum GamepadAxisDir {
263    Pos,
264    Neg,
265}
266
267impl Display for KeyCode {
268    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
269        write!(f, "{:?}", self)
270    }
271}
272
273impl Display for GamepadButton {
274    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
275        write!(f, "Pad{}.{}", self.gamepad.id, self.button_type)
276    }
277}
278
279impl Display for GamepadButtonType {
280    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
281        use GamepadButtonType::*;
282        let s = match self {
283            South => "S",
284            East => "E",
285            North => "N",
286            West => "W",
287            C => "C",
288            Z => "Z",
289            LeftTrigger => "LB",
290            LeftTrigger2 => "LT",
291            RightTrigger => "RB",
292            RightTrigger2 => "RT",
293            Select => "Select",
294            Start => "Start",
295            Mode => "Mode",
296            LeftThumb => "LS",
297            RightThumb => "RS",
298            DPadUp => "DPadUp",
299            DPadDown => "DPadDown",
300            DPadLeft => "DPadLeft",
301            DPadRight => "DPadRight",
302        };
303        write!(f, "{s}")
304    }
305}
306
307impl Display for GamepadAxis {
308    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
309        write!(f, "Pad{}.{}", self.gamepad.id, self.axis_type)
310    }
311}
312
313impl Display for GamepadAxisDir {
314    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
315        let s = match self {
316            GamepadAxisDir::Pos => "+",
317            GamepadAxisDir::Neg => "-",
318        };
319        write!(f, "{s}")
320    }
321}
322
323impl Display for GamepadAxisType {
324    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
325        use GamepadAxisType::*;
326        let s = match self {
327            LeftStickX => "LX",
328            LeftStickY => "LY",
329            LeftZ => "LZ",
330            RightStickX => "RX",
331            RightStickY => "RY",
332            RightZ => "RZ",
333        };
334        write!(f, "{s}")
335    }
336}
337
338impl Display for MultiKey {
339    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
340        let mut first = true;
341        for single_key in &self.0 {
342            if !first {
343                write!(f, "+")?;
344            }
345            write!(f, "{}", single_key)?;
346            first = false;
347        }
348        Ok(())
349    }
350}
351
352impl Display for SingleKey {
353    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
354        match self {
355            SingleKey::KeyCode(kc) => write!(f, "{kc}"),
356            SingleKey::GamepadButton(button) => write!(f, "{button}"),
357            SingleKey::GamepadAxis(axis, dir) => write!(f, "{axis}{dir}"),
358        }
359    }
360}
361
362pub trait InputState {
363    fn pressed(&self, key: &SingleKey) -> bool;
364    fn just_pressed(&self, key: &SingleKey) -> bool;
365}
366
367impl KeyAssign {
368    pub fn and(self, rhs: Self) -> Self {
369        let mut ret = vec![];
370        for l in self.0.into_iter() {
371            for r in rhs.0.iter() {
372                let mut t = l.0.clone();
373                t.append(&mut r.0.clone());
374                ret.push(MultiKey(t));
375            }
376        }
377        Self(ret)
378    }
379
380    pub fn or(mut self, mut rhs: Self) -> Self {
381        self.0.append(&mut rhs.0);
382        self
383    }
384    pub fn pressed(&self, input_state: &impl InputState) -> bool {
385        self.0
386            .iter()
387            .any(|multi_key| multi_key.pressed(input_state))
388    }
389
390    pub fn just_pressed(&self, input_state: &impl InputState) -> bool {
391        self.0
392            .iter()
393            .any(|multi_key| multi_key.just_pressed(input_state))
394    }
395
396    pub fn extract_keycode(&self) -> Option<KeyCode> {
397        for MultiKey(mk) in &self.0 {
398            if let [SingleKey::KeyCode(r)] = &mk[..] {
399                return Some(*r);
400            }
401        }
402        None
403    }
404
405    pub fn insert_keycode(&mut self, kc: KeyCode) {
406        for MultiKey(mk) in self.0.iter_mut() {
407            if let [SingleKey::KeyCode(r)] = &mut mk[..] {
408                *r = kc;
409                return;
410            }
411        }
412        self.0.push(MultiKey(vec![SingleKey::KeyCode(kc)]));
413    }
414
415    pub fn extract_gamepad(&self) -> Option<GamepadButton> {
416        for MultiKey(mk) in &self.0 {
417            if let [SingleKey::GamepadButton(r)] = &mk[..] {
418                return Some(*r);
419            }
420        }
421        None
422    }
423
424    pub fn insert_gamepad(&mut self, button: GamepadButton) {
425        for MultiKey(mk) in self.0.iter_mut() {
426            if let [SingleKey::GamepadButton(r)] = &mut mk[..] {
427                *r = button;
428                return;
429            }
430        }
431        self.0
432            .push(MultiKey(vec![SingleKey::GamepadButton(button)]));
433    }
434}
435
436impl MultiKey {
437    fn pressed(&self, input_state: &impl InputState) -> bool {
438        self.0
439            .iter()
440            .all(|single_key| input_state.pressed(single_key))
441    }
442
443    fn just_pressed(&self, input_state: &impl InputState) -> bool {
444        // all key are pressed and some key is just pressed
445        self.pressed(input_state)
446            && self
447                .0
448                .iter()
449                .any(|single_key| input_state.just_pressed(single_key))
450    }
451}
452
453#[macro_export]
454macro_rules! any {
455    ($x:expr, $($xs:expr),* $(,)?) => {
456        [$($xs),*].into_iter().fold($x, |a, b| a.or(b))
457    };
458}
459pub use any;
460
461#[macro_export]
462macro_rules! all {
463    ($x:expr, $($xs:expr),* $(,)?) => {{
464        [$($xs),*].into_iter().fold($x, |a, b| a.and(b))
465    }};
466}
467pub use all;
468
469#[macro_export]
470macro_rules! keycode {
471    ($code:ident) => {
472        KeyAssign(vec![MultiKey(vec![
473            $crate::key_assign::SingleKey::KeyCode($crate::key_assign::KeyCode::$code),
474        ])])
475    };
476}
477pub use keycode;
478
479#[macro_export]
480macro_rules! pad_button {
481    ($id:literal, $button:ident) => {
482        $crate::key_assign::KeyAssign(vec![$crate::key_assign::MultiKey(vec![
483            $crate::key_assign::SingleKey::GamepadButton($crate::key_assign::GamepadButton::new(
484                $crate::key_assign::Gamepad::new($id),
485                $crate::key_assign::GamepadButtonType::$button,
486            )),
487        ])])
488    };
489}
490pub use pad_button;