1pub mod input;
2
3use std::hash::Hash;
4
5use bevy::{prelude::*, utils::HashMap};
6use input::{
7 events::{InputActionContinuing, InputActionFinished, InputActionStarted},
8 gamepad::GamepadAxis,
9 mouse::MouseAxis,
10};
11
12use crate::input::events::InputActionActive;
13
14pub trait AutoBinder<K, V>
15where
16 K: Eq + Hash,
17{
18 fn bind(&mut self, key: K, value: V) -> &mut Self;
19 fn unbind(&mut self, key: K) -> &mut Self;
20}
21
22impl<K, V> AutoBinder<K, V> for HashMap<K, V>
23where
24 K: Eq + Hash,
25{
26 fn bind(&mut self, key: K, value: V) -> &mut Self {
27 self.insert(key, value);
28 self
29 }
30
31 fn unbind(&mut self, key: K) -> &mut Self {
32 self.remove(&key);
33 self
34 }
35}
36
37#[derive(Default, Clone, Resource)]
38pub struct InputMapper {
39 pub action_value: HashMap<String, f32>,
40 pub previous_action_value: HashMap<String, f32>,
41
42 pub keyboard_binding: HashMap<KeyCode, String>,
43 pub mouse_button_binding: HashMap<MouseButton, String>,
44 pub mouse_axis_binding: HashMap<MouseAxis, String>,
45
46 pub gamepad_axis_binding: HashMap<GamepadAxis, String>,
47 pub gamepad_button_binding: HashMap<GamepadButtonType, String>,
48}
49
50impl InputMapper {
51 pub fn bind_keyboard_key_press(&mut self, key: KeyCode, action: impl ToString) -> &mut Self {
52 self.keyboard_binding.bind(key, action.to_string());
53 self
54 }
55 pub fn bind_mouse_axis_move(&mut self, axis: MouseAxis, action: impl ToString) -> &mut Self {
56 self.mouse_axis_binding.bind(axis, action.to_string());
57 self
58 }
59 pub fn bind_mouse_button_press(
60 &mut self,
61 button: MouseButton,
62 action: impl ToString,
63 ) -> &mut Self {
64 self.mouse_button_binding.bind(button, action.to_string());
65 self
66 }
67 pub fn bind_gamepad_axis_move(
68 &mut self,
69 axis: GamepadAxis,
70 action: impl ToString,
71 ) -> &mut Self {
72 self.gamepad_axis_binding.bind(axis, action.to_string());
73 self
74 }
75 pub fn bind_gamepad_button_press(
76 &mut self,
77 button: GamepadButtonType,
78 action: impl ToString,
79 ) -> &mut Self {
80 self.gamepad_button_binding.bind(button, action.to_string());
81 self
82 }
83}
84
85#[derive(Default)]
86pub struct InputMapperPlugin;
87
88impl Plugin for InputMapperPlugin {
89 fn build(&self, app: &mut App) {
90 app.insert_resource(InputMapper::default())
91 .add_event::<InputActionActive>()
92 .add_event::<InputActionStarted>()
93 .add_event::<InputActionContinuing>()
94 .add_event::<InputActionFinished>()
95 .add_systems(Update, InputMapper::event_cycle)
96 .add_systems(Update, InputMapper::keyboard_key_press_system)
97 .add_systems(
98 Update,
99 (
100 InputMapper::mouse_button_press_system,
101 InputMapper::mouse_axis_move_system,
102 ),
103 )
104 .add_systems(
105 Update,
106 (
107 InputMapper::gamepad_button_press_system,
108 InputMapper::gamepad_axis_move_system,
109 ),
110 );
111 }
112}