104 lines
3.6 KiB
Rust
104 lines
3.6 KiB
Rust
use std::{
|
|
collections::HashMap,
|
|
sync::{Arc, RwLock},
|
|
};
|
|
|
|
use bevy_ecs::resource::Resource;
|
|
use cache::{CachedElementState, CachedMovement};
|
|
use virtual_input::VirtualInput;
|
|
use winit::{
|
|
event::{DeviceEvent, MouseButton, MouseScrollDelta, WindowEvent},
|
|
keyboard::PhysicalKey,
|
|
};
|
|
|
|
mod cache;
|
|
mod virtual_binding;
|
|
mod virtual_input;
|
|
mod virtual_state;
|
|
pub use virtual_binding::{AxisDirection, VirtualBinding};
|
|
|
|
#[derive(Default)]
|
|
pub struct InputManager {
|
|
keys_state: CachedElementState<PhysicalKey>,
|
|
mouse_buttons_state: CachedElementState<MouseButton>,
|
|
mouse_position_delta: CachedMovement<glam::Vec2>,
|
|
mouse_wheel_delta: CachedMovement<glam::Vec2>,
|
|
virtual_input: VirtualInput,
|
|
}
|
|
|
|
#[derive(Resource)]
|
|
pub struct InputManagerResource(pub Arc<RwLock<InputManager>>);
|
|
|
|
impl std::fmt::Debug for InputManager {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
f.debug_struct("InputManager")
|
|
.field("virtual_input", &self.virtual_input)
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
impl InputManager {
|
|
pub fn new(input_mapping: HashMap<String, Vec<VirtualBinding>>) -> Self {
|
|
let mut input_manager = InputManager::default();
|
|
for (value_name, bindings) in input_mapping {
|
|
input_manager.add_virtual_bindings(value_name, bindings);
|
|
}
|
|
input_manager
|
|
}
|
|
|
|
pub fn process_device_event(&mut self, event: &DeviceEvent) {
|
|
if let DeviceEvent::MouseMotion { delta, .. } = event {
|
|
self.mouse_position_delta += glam::Vec2::new(delta.0 as f32, delta.1 as f32);
|
|
}
|
|
}
|
|
|
|
pub fn process_window_event(&mut self, event: &WindowEvent) {
|
|
match event {
|
|
WindowEvent::AxisMotion { axis, value, .. } => {
|
|
self.virtual_input.update_axis_binding(*axis, *value as f32);
|
|
}
|
|
WindowEvent::KeyboardInput { event, .. } => {
|
|
let new_key_state = self
|
|
.keys_state
|
|
.set_key_state(event.physical_key, event.state);
|
|
if let Some(new_key_state) = new_key_state {
|
|
self.virtual_input
|
|
.update_key_binding(event.physical_key, new_key_state);
|
|
}
|
|
}
|
|
WindowEvent::MouseInput { button, state, .. } => {
|
|
let new_mouse_button_state =
|
|
self.mouse_buttons_state.set_key_state(*button, *state);
|
|
if let Some(new_mouse_button_state) = new_mouse_button_state {
|
|
self.virtual_input
|
|
.update_mouse_button_binding(*button, new_mouse_button_state);
|
|
}
|
|
}
|
|
WindowEvent::MouseWheel { delta, .. } => {
|
|
self.mouse_wheel_delta += match delta {
|
|
MouseScrollDelta::PixelDelta(position) => {
|
|
glam::Vec2::new(position.x as f32, position.y as f32)
|
|
}
|
|
MouseScrollDelta::LineDelta(x, y) => glam::Vec2::new(*x, *y),
|
|
};
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
/// Updates deltas before running update
|
|
pub fn update(&mut self) {
|
|
self.virtual_input
|
|
.update_mouse_move_binding(&self.mouse_position_delta.reset());
|
|
self.virtual_input
|
|
.update_mouse_wheel_binding(&self.mouse_wheel_delta.reset());
|
|
}
|
|
|
|
pub fn get_virtual_input_state(&self, value_name: &str) -> f32 {
|
|
self.virtual_input.get_state(value_name)
|
|
}
|
|
|
|
fn add_virtual_bindings(&mut self, value_name: String, bindings: Vec<VirtualBinding>) {
|
|
self.virtual_input.add_bindings(value_name, bindings);
|
|
}
|
|
}
|