use std::collections::HashSet;
use winit::event::{ElementState, KeyEvent, WindowEvent};
use winit::keyboard::{KeyCode, PhysicalKey};
pub struct InputState {
keys_pressed: HashSet<KeyCode>,
keys_just_pressed: HashSet<KeyCode>,
keys_just_released: HashSet<KeyCode>,
mouse_position: (f32, f32),
}
impl InputState {
pub fn new() -> Self {
Self {
keys_pressed: HashSet::new(),
keys_just_pressed: HashSet::new(),
keys_just_released: HashSet::new(),
mouse_position: (0.0, 0.0),
}
}
pub fn process_event(&mut self, event: &WindowEvent) {
match event {
WindowEvent::KeyboardInput {
event:
KeyEvent {
physical_key: PhysicalKey::Code(keycode),
state,
..
},
..
} => match state {
ElementState::Pressed => {
if !self.keys_pressed.contains(keycode) {
self.keys_just_pressed.insert(*keycode);
}
self.keys_pressed.insert(*keycode);
}
ElementState::Released => {
self.keys_pressed.remove(keycode);
self.keys_just_released.insert(*keycode);
}
},
WindowEvent::CursorMoved { position, .. } => {
self.mouse_position = (position.x as f32, position.y as f32);
}
_ => {}
}
}
pub fn end_frame(&mut self) {
self.keys_just_pressed.clear();
self.keys_just_released.clear();
}
pub fn key_pressed(&self, key: KeyCode) -> bool {
self.keys_pressed.contains(&key)
}
pub fn key_just_pressed(&self, key: KeyCode) -> bool {
self.keys_just_pressed.contains(&key)
}
pub fn key_just_released(&self, key: KeyCode) -> bool {
self.keys_just_released.contains(&key)
}
pub fn mouse_position(&self) -> (f32, f32) {
self.mouse_position
}
}
impl Default for InputState {
fn default() -> Self {
Self::new()
}
}