1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
use gapp::{Render, Update}; use glutin::{PossiblyCurrent, WindowedContext}; use instant::Instant; use std::{thread, time}; use winit::{ event::{Event, WindowEvent}, event_loop::{ControlFlow, EventLoop}, }; pub trait WindowInput<C> { fn input<'a>(&mut self, event: &WindowEvent<'a>, context: &mut C) -> bool; } pub trait Resize { fn resize(&mut self, w: u32, h: u32); } pub fn run<I: 'static, R: Resize + 'static, T, E: WindowInput<I> + Render<R> + Update + 'static>( mut application: E, event_loop: EventLoop<T>, fps: u64, windowed_context: WindowedContext<PossiblyCurrent>, mut input_context: I, mut renderer: R, ) { let timestep = time::Duration::from_nanos(1000000000 / fps); let start = Instant::now(); let mut prev_time = start; event_loop.run(move |event, _, control_flow| { let window = windowed_context.window(); *control_flow = ControlFlow::Poll; match event { Event::WindowEvent { ref event, .. } => { match event { WindowEvent::Resized(physical_size) => { windowed_context.resize(*physical_size); renderer.resize(physical_size.width, physical_size.height); } _ => (), } if application.input(event, &mut input_context) { *control_flow = ControlFlow::Exit; } } Event::RedrawRequested(_) => { application.render(&mut renderer); windowed_context.swap_buffers().unwrap(); } Event::MainEventsCleared => { let frame_duration = prev_time.elapsed(); application.update(timestep.as_secs_f32()); if frame_duration < timestep { thread::sleep(timestep - frame_duration); } window.request_redraw(); prev_time = Instant::now(); } _ => (), } }); }