use std::collections::HashMap; use winit::{ dpi::PhysicalPosition, event::{ElementState, KeyEvent, WindowEvent}, keyboard::PhysicalKey, }; #[derive(Debug, Default)] pub enum KeyState { #[default] Pressed, Released, Held, } #[derive(Debug, Default)] pub struct MouseState { old_position: glam::Vec2, pub position: glam::Vec2, pub delta: glam::Vec2, } #[derive(Debug, Default)] pub struct InputState { pub key_states: HashMap, pub mouse_state: MouseState, } impl InputState { pub fn process_event(&mut self, event: &WindowEvent) { match event { WindowEvent::KeyboardInput { event, .. } => { self.update_key_state(event.physical_key, event); } WindowEvent::CursorMoved { position, .. } => { self.update_mouse_position(position); } _ => {} } } /// Updates deltas before running update pub fn update(&mut self) { self.mouse_state.delta = self.mouse_state.position - self.mouse_state.old_position; self.mouse_state.old_position = self.mouse_state.position; } pub fn get_key_state(&self, key: PhysicalKey) -> &KeyState { self.key_states.get(&key).unwrap_or(&KeyState::Released) } pub fn get_mouse_state(&self) -> &MouseState { &self.mouse_state } fn update_key_state(&mut self, key: PhysicalKey, event: &KeyEvent) { let key_state = self.key_states.get(&event.physical_key); let new_key_state = match key_state { Some(key_state) => match event.state { ElementState::Pressed => match key_state { KeyState::Released => Some(KeyState::Pressed), KeyState::Pressed => Some(KeyState::Held), KeyState::Held => None, }, ElementState::Released => match key_state { KeyState::Released => None, _ => Some(KeyState::Released), }, }, None => match event.state { ElementState::Pressed => Some(KeyState::Pressed), ElementState::Released => Some(KeyState::Released), }, }; if let Some(new_key_state) = new_key_state { log::trace!( "New key state {:?} for key {:?}", new_key_state, event.physical_key ); self.key_states.insert(key, new_key_state); } } fn update_mouse_position(&mut self, position: &PhysicalPosition) { self.mouse_state.position = glam::Vec2::new(position.x as f32, position.y as f32); } }