bevy_input_mapper/
lib.rs

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}