moltrun 1.7.2

High-performance game engine library with AI capabilities, built on wgpu for modern 3D graphics and physics simulation
Documentation
use winit::event::{WindowEvent, ElementState, MouseScrollDelta, MouseButton, KeyEvent};
use winit::keyboard::PhysicalKey;
use winit::dpi::PhysicalPosition;
use crate::math::Vec2;
use crate::core::InputState;

/// 입력 관리자 - 이벤트 변환 + 상태 관리
pub struct InputManager {
    state: InputState,
}

impl InputManager {
    pub fn new() -> Self {
        Self {
            state: InputState::new(),
        }
    }
    
    /// InputState 읽기 전용 참조
    pub fn state(&self) -> &InputState {
        &self.state
    }
    
    /// 프레임 시작 시 호출 (Engine::update 초반)
    pub fn begin_frame(&mut self) {
        self.state.begin_frame();
    }
    
    /// 프레임 종료 시 호출 (Engine::update 끝)
    pub fn end_frame(&mut self) {
        self.state.end_frame();
    }
    
    /// winit WindowEvent 처리
    pub fn process_window_event(&mut self, event: &WindowEvent) {
        match event {
            WindowEvent::KeyboardInput { event, .. } => {
                self.process_keyboard(event);
            }
            WindowEvent::CursorMoved { position, .. } => {
                self.process_mouse_move(position);
            }
            WindowEvent::MouseInput { state, button, .. } => {
                self.process_mouse_button(*state, *button);
            }
            WindowEvent::MouseWheel { delta, .. } => {
                self.process_mouse_wheel(delta);
            }
            _ => {}
        }
    }
    
    // ========== 내부 이벤트 처리 메서드 ==========
    
    fn process_keyboard(&mut self, event: &KeyEvent) {
        if let PhysicalKey::Code(keycode) = event.physical_key {
            match event.state {
                ElementState::Pressed => {
                    // 이미 눌려있지 않았다면 "just pressed"
                    if !self.state.keys_down.contains(&keycode) {
                        self.state.keys_pressed_this_frame.insert(keycode);
                    }
                    self.state.keys_down.insert(keycode);
                }
                ElementState::Released => {
                    self.state.keys_down.remove(&keycode);
                    self.state.keys_released_this_frame.insert(keycode);
                }
            }
        }
    }
    
    fn process_mouse_move(&mut self, position: &PhysicalPosition<f64>) {
        let new_pos = Vec2::new(position.x as f32, position.y as f32);
        self.state.mouse_delta = new_pos - self.state.mouse_position;
        self.state.mouse_position = new_pos;
    }
    
    fn process_mouse_button(&mut self, state: ElementState, button: MouseButton) {
        match state {
            ElementState::Pressed => {
                if !self.state.mouse_buttons_down.contains(&button) {
                    self.state.mouse_buttons_pressed_this_frame.insert(button);
                }
                self.state.mouse_buttons_down.insert(button);
            }
            ElementState::Released => {
                self.state.mouse_buttons_down.remove(&button);
                self.state.mouse_buttons_released_this_frame.insert(button);
            }
        }
    }
    
    fn process_mouse_wheel(&mut self, delta: &MouseScrollDelta) {
        let delta_y = match delta {
            MouseScrollDelta::LineDelta(_x, y) => *y,
            MouseScrollDelta::PixelDelta(pos) => pos.y as f32 / 100.0, // 정규화
        };
        
        self.state.mouse_wheel_delta += delta_y;
    }
}

impl Default for InputManager {
    fn default() -> Self {
        Self::new()
    }
}