#[cfg(test)] mod tests { use cgmath::{vec3}; use winit::{dpi::PhysicalPosition, event::{DeviceId, ElementState, Event, Force, KeyboardInput, ModifiersState, Touch, TouchPhase, WindowEvent}, window::WindowId}; use crate::{config::LogConfig, game::player::{intersect_triangle}, input::InputState}; use crate::input::vk_to_scan_code; fn epsilon_eq(f1: f32, f2: f32) { assert!(f32::abs(f1 - f2) < f32::EPSILON, "{} == {}", f1, f2); } fn epsilon_eq_option(o1: Option, o2: Option) { if let Some(f1) = o1 { if let Some(f2) = o2 { epsilon_eq(f1, f2); } else { panic!("Some({}) == None", f1); } } else if let Some(f2) = o2 { panic!("None == Some({})", f2); } } #[test] fn triangle_intersection() { let zero = vec3(0.0, 0.0, 0.0); let a = [2.0, 0.5, 0.5]; let b = [2.0, -0.5, 0.5]; let c = [2.0, 0.0, -0.5]; let dist1 = intersect_triangle(zero, vec3(1.0, 0.0, 0.0), a, b, c); epsilon_eq_option(dist1, Some(2.0)); let dist2 = intersect_triangle(zero, vec3(0.0, 0.0, 1.0), a, b, c); epsilon_eq_option(dist2, None); let dist3 = intersect_triangle(zero, vec3(0.9950371902, 0.09950371902, 0.0), a, b, c); epsilon_eq_option(dist3, Some(2.0099751242)); } fn create_test_input_state() -> InputState { InputState::new("config/testinput.toml", LogConfig::from_file("config/log.toml")) } #[test] fn key_test() { let mut state = create_test_input_state(); state.frame_start(); state.frame_end(); unsafe { state.on_window_event(&Event::WindowEvent{ window_id: WindowId::dummy(), event: WindowEvent::KeyboardInput { device_id: DeviceId::dummy(), input: KeyboardInput { scancode: 1, state: ElementState::Pressed, virtual_keycode: None, modifiers: ModifiersState::empty() }, is_synthetic: true, }}); } state.frame_start(); assert_eq!(state.button_just_pressed("quit"), true); assert_eq!(state.button_down("quit"), true); state.frame_end(); state.frame_start(); assert_eq!(state.button_just_pressed("quit"), false); assert_eq!(state.button_down("quit"), true); state.frame_end(); unsafe { state.on_window_event(&Event::WindowEvent{ window_id: WindowId::dummy(), event: WindowEvent::KeyboardInput { device_id: DeviceId::dummy(), input: KeyboardInput { scancode: 1, state: ElementState::Released, virtual_keycode: None, modifiers: ModifiersState::empty() }, is_synthetic: true, }}); } state.frame_start(); assert_eq!(state.button_down("quit"), false); state.frame_end(); unsafe { state.on_window_event(&Event::WindowEvent{ window_id: WindowId::dummy(), event: WindowEvent::KeyboardInput { device_id: DeviceId::dummy(), input: KeyboardInput { scancode: 32, state: ElementState::Pressed, virtual_keycode: None, modifiers: ModifiersState::empty() }, is_synthetic: true, }}); } state.frame_start(); assert_eq!(state.button_down("button_right"), true); } fn touch_event(state: &mut InputState, phase: TouchPhase, id: u64) { unsafe { state.on_window_event(&Event::WindowEvent{ window_id: WindowId::dummy(), event: WindowEvent::Touch(Touch { device_id: DeviceId::dummy(), phase, location: PhysicalPosition::new(0., 0.), force: Some(Force::Normalized(0.5)), id })}); } } #[test] fn touch_test() { let mut state = create_test_input_state(); state.frame_start(); state.frame_end(); touch_event(&mut state, TouchPhase::Started, 1); state.frame_start(); assert_eq!(state.button_just_pressed("touchclick"), true); assert_eq!(state.button_down("touchclick"), true); state.frame_end(); touch_event(&mut state, TouchPhase::Moved, 1); state.frame_start(); assert_eq!(state.button_just_pressed("touchclick"), false); assert_eq!(state.button_down("touchclick"), true); state.frame_end(); touch_event(&mut state, TouchPhase::Ended, 1); state.frame_start(); assert_eq!(state.button_just_released("touchclick"), true); assert_eq!(state.button_down("touchclick"), false); state.frame_end(); } #[test] fn multi_touch_test() { let mut state = create_test_input_state(); state.frame_start(); state.frame_end(); touch_event(&mut state, TouchPhase::Started, 2); // TODO: add tolerance for delay touch_event(&mut state, TouchPhase::Started, 3); state.frame_start(); assert_eq!(state.button_just_pressed("touchclick"), false); assert_eq!(state.button_down("touchclick"), false); assert_eq!(state.button_just_pressed("doubletouchclick"), true); assert_eq!(state.button_down("doubletouchclick"), true); state.frame_end(); touch_event(&mut state, TouchPhase::Moved, 2); state.frame_start(); assert_eq!(state.button_just_pressed("doubletouchclick"), false); assert_eq!(state.button_down("doubletouchclick"), true); state.frame_end(); touch_event(&mut state, TouchPhase::Ended, 2); state.frame_start(); assert_eq!(state.button_just_released("doubletouchclick"), true); assert_eq!(state.button_down("doubletouchclick"), false); assert_eq!(state.button_just_pressed("touchclick"), false); // TODO: don't enable button_down on release of double touch // assert_eq!(state.button_down("touchclick"), false); state.frame_end(); touch_event(&mut state, TouchPhase::Ended, 3); state.frame_start(); // TODO: only set button_just_released for one frame // assert_eq!(state.button_just_released("doubletouchclick"), false); assert_eq!(state.button_down("doubletouchclick"), false); } #[test] fn vk_input_name_test() { let vk = "VK_ESCAPE"; assert_eq!(vk_to_scan_code(vk), Some(1)); } }