Something went wrong. Try again.
Homebrew 4D Game Engine In Rust, inspired by Engine4D
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150//! Input mapping from raw events to semantic actions//!//! Maps keyboard and mouse input to high-level actions like ToggleCursor, Exit, etc.//! Movement keys (WASD, Space) are NOT mapped here - they go directly to CameraController.
use winit::event::{ElementState, MouseButton};use winit::keyboard::KeyCode;
/// Actions triggered by special input (not movement)#[derive(Debug, Clone, Copy, PartialEq, Eq)]pub enum InputAction { /// Toggle cursor capture (Escape when captured, click when released) ToggleCursor, /// Exit application (Escape when not captured) Exit, /// Reset camera to starting position (R key) ResetCamera, /// Toggle fullscreen mode (F key) ToggleFullscreen, /// Toggle input smoothing (G key) ToggleSmoothing,}
/// Maps raw input events to semantic actions////// Movement keys (WASD, Space, RF) are NOT mapped here - they go directly/// to the CameraController. This mapper handles "special" keys only.pub struct InputMapper;
impl InputMapper { /// Map keyboard input to an action /// /// Returns `Some(action)` for special keys, `None` for movement keys pub fn map_keyboard( key: KeyCode, state: ElementState, cursor_captured: bool, ) -> Option<InputAction> { // Only handle key presses, not releases if state != ElementState::Pressed { return None; }
match key { KeyCode::Escape => { if cursor_captured { Some(InputAction::ToggleCursor) } else { Some(InputAction::Exit) } } KeyCode::KeyR => Some(InputAction::ResetCamera), KeyCode::KeyF => Some(InputAction::ToggleFullscreen), KeyCode::KeyG => Some(InputAction::ToggleSmoothing), _ => None, // Movement keys handled by controller } }
/// Map mouse button to an action /// /// Returns `Some(ToggleCursor)` for left click when cursor not captured pub fn map_mouse_button( button: MouseButton, state: ElementState, cursor_captured: bool, ) -> Option<InputAction> { if button == MouseButton::Left && state == ElementState::Pressed && !cursor_captured { Some(InputAction::ToggleCursor) } else { None } }}
#[cfg(test)]mod tests { use super::*;
#[test] fn test_escape_when_captured_releases() { let action = InputMapper::map_keyboard( KeyCode::Escape, ElementState::Pressed, true, // cursor captured ); assert_eq!(action, Some(InputAction::ToggleCursor)); }
#[test] fn test_escape_when_released_exits() { let action = InputMapper::map_keyboard( KeyCode::Escape, ElementState::Pressed, false, // cursor not captured ); assert_eq!(action, Some(InputAction::Exit)); }
#[test] fn test_movement_keys_not_mapped() { // WASD should return None (handled by controller) for key in [KeyCode::KeyW, KeyCode::KeyA, KeyCode::KeyS, KeyCode::KeyD] { let action = InputMapper::map_keyboard(key, ElementState::Pressed, true); assert_eq!(action, None, "Key {:?} should not be mapped", key); } }
#[test] fn test_key_release_ignored() { let action = InputMapper::map_keyboard(KeyCode::Escape, ElementState::Released, true); assert_eq!(action, None); }
#[test] fn test_click_to_capture() { let action = InputMapper::map_mouse_button( MouseButton::Left, ElementState::Pressed, false, // cursor not captured ); assert_eq!(action, Some(InputAction::ToggleCursor)); }
#[test] fn test_click_when_captured_no_action() { let action = InputMapper::map_mouse_button( MouseButton::Left, ElementState::Pressed, true, // cursor already captured ); assert_eq!(action, None); }
#[test] fn test_special_keys() { assert_eq!( InputMapper::map_keyboard(KeyCode::KeyR, ElementState::Pressed, true), Some(InputAction::ResetCamera) ); assert_eq!( InputMapper::map_keyboard(KeyCode::KeyF, ElementState::Pressed, true), Some(InputAction::ToggleFullscreen) ); assert_eq!( InputMapper::map_keyboard(KeyCode::KeyG, ElementState::Pressed, true), Some(InputAction::ToggleSmoothing) ); }}