vertix/
event.rs

1use instant::Duration;
2use winit::{event_loop::{EventLoop, ControlFlow}, event::{Event, DeviceEvent, WindowEvent, KeyboardInput, ElementState, VirtualKeyCode}};
3
4use crate::{state::State, render::render, resources::{WindowEvents, MousePos, DeltaTime}};
5
6pub fn run_event_loop(
7    mut state: State,
8    event_loop: EventLoop<()>,
9    cam_update: Option<fn (&mut State, dt: std::time::Duration)>,
10) {
11    let mut last_render_time = instant::Instant::now();
12    
13    event_loop.run(move |event, _, control_flow| {
14        *control_flow = ControlFlow::Poll;
15        match event {
16            Event::MainEventsCleared => state.window().request_redraw(),
17            Event::DeviceEvent {
18                event: DeviceEvent::MouseMotion{ delta, },
19                .. // We're not using device_id currently
20            } => if state.mouse_pressed || state.mouse_locked {
21                state.camera.camera_controller.process_mouse(delta.0, delta.1)
22            }
23            Event::WindowEvent {
24                ref event,
25                window_id,
26            } if window_id == state.window().id() => {
27                state.input(event);
28                match event {
29                    #[cfg(not(target_arch="wasm32"))]
30                    WindowEvent::CloseRequested
31                    | WindowEvent::KeyboardInput {
32                        input:
33                            KeyboardInput {
34                                state: ElementState::Pressed,
35                                virtual_keycode: Some(VirtualKeyCode::Escape),
36                                ..
37                            },
38                        ..
39                    } => *control_flow = ControlFlow::Exit,
40                    WindowEvent::CursorMoved { position, .. } => {
41                        let mut mouse_pos = state.world.get_resource_mut::<MousePos>().unwrap();
42                        mouse_pos.pos = state.window.normalize_position(position);
43                    }
44                    WindowEvent::Resized(physical_size) => {
45                        state.resize(*physical_size);
46                    }
47                    WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
48                        state.resize(**new_inner_size);
49                    }
50                    _ => {}
51                }
52            }
53            Event::RedrawRequested(window_id) if window_id == state.window().id() => {
54                let now = instant::Instant::now();
55                let dt = now - last_render_time;
56                last_render_time = now;
57                let mut delta_time = state.world.get_resource_mut::<DeltaTime>().unwrap();
58                delta_time.dt = dt;
59                if cam_update.is_some() {
60                    cam_update.unwrap()(&mut state, dt);
61                }
62                state.update();
63                state.schedule.run(&mut state.world);
64                state.world.get_resource_mut::<WindowEvents>().unwrap().keys_pressed = vec![];
65                match render(&mut state) {
66                    Ok(_) => {}
67                    // Reconfigure the surface if it's lost or outdated
68                    Err(wgpu::SurfaceError::Lost | wgpu::SurfaceError::Outdated) => state.resize(state.window.size),
69                    // The system is out of memory, we should probably quit
70                    Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit,
71                    // We're ignoring timeouts
72                    Err(wgpu::SurfaceError::Timeout) => log::warn!("Surface timeout"),
73                }
74            }
75            _ => {}
76        }
77    });
78}
79pub fn delta_time_to_seconds(dt: Duration) -> f32 {
80    dt.as_millis() as f32 * 0.001
81}