diff --git a/game/main.ts b/game/main.ts index 97fef854..d044d883 100644 --- a/game/main.ts +++ b/game/main.ts @@ -23,4 +23,5 @@ export function draw() { use_texture(the_texture); spr((320 - 256) / 2, 0, 256, 240, 0, 0); } + // print("FRAME TIME:", since_last_frame()); } diff --git a/src/lib.rs b/src/lib.rs index 9a23cacc..049a9a2c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,9 @@ use bytemuck; use std::collections::HashMap; +use std::sync::mpsc::Receiver; +use std::time::Instant; use wgpu::util::DeviceExt; -use winit::{ - event::*, - event_loop::{ControlFlow, EventLoop}, - window::Window, - window::WindowBuilder, -}; +use winit::{event::*, event_loop::EventLoop, window::Window, window::WindowBuilder}; mod script; use script::graphics::GraphicsCommand; @@ -142,17 +139,12 @@ impl State { format: surface_format, width: size.width, height: size.height, - present_mode: surface_caps.present_modes[0], + present_mode: wgpu::PresentMode::Fifo, alpha_mode: surface_caps.alpha_modes[0], view_formats: vec![], }; surface.configure(&device, &config); - // TODO: DELETE THIS - // let diffuse_bytes = include_bytes!("happy-tree.png"); - // let diffuse_texture = - // texture::Texture::from_bytes(&device, &queue, diffuse_bytes, "happy-tree.png").unwrap(); - let sprite_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { entries: &[ @@ -475,116 +467,96 @@ impl State { self.queue.submit(std::iter::once(encoder.finish())); } - // { - // // BEGIN GARBAGE - // let r: f64 = (self.mouse_x / f64::from(self.size.width)).clamp(0.0, 1.0) * 0.1; - // let g: f64 = (self.mouse_y / f64::from(self.size.height)).clamp(0.0, 1.0) * 0.2; - // // END GARBAGE - - // let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - // label: Some("Render Pass"), - // color_attachments: &[Some(wgpu::RenderPassColorAttachment { - // view: &view, - // resolve_target: None, - // ops: wgpu::Operations { - // load: wgpu::LoadOp::Clear(wgpu::Color { - // r, //0.1, - // g, //0.2, - // b: 0.3, - // a: 1.0, - // }), - // store: true, - // }, - // })], - // depth_stencil_attachment: None, - // }); - - // render_pass.set_pipeline(&self.render_pipeline); - // render_pass.set_bind_group(0, &self.diffuse_bind_group, &[]); - // render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); - // render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); - // render_pass.draw_indexed(0..self.num_indices, 0, 0..1); - // } - output.present(); Ok(()) } } +struct UIEvent { + winit: Event<'static, ()>, + #[allow(unused)] + time: Instant, +} + +// TODO: flume? (https://docs.rs/flume/latest/flume/) + +fn main_thread(state: State, reciever: Receiver) { + let mut state = state; + let mut context = script::ScriptContext::new(); + context.init(); + + loop { + while let Ok(event) = reciever.try_recv() { + match event.winit { + Event::WindowEvent { + ref event, + window_id, + } if window_id == state.window().id() => { + if !state.input(event) { + match event { + WindowEvent::CursorMoved { position, .. } => { + state.mouse_x = position.x; + state.mouse_y = position.y; + } + + WindowEvent::Resized(physical_size) => { + state.resize(*physical_size); + } + + WindowEvent::ScaleFactorChanged { new_inner_size, .. } => { + // new_inner_size is &&mut so we have to dereference it twice + state.resize(**new_inner_size); + } + + _ => {} + } + } + } + + _ => {} + } + } + + context.update(); + state.update(); + + match state.render(context.render()) { + Ok(_) => {} + // Reconfigure the surface if lost + Err(wgpu::SurfaceError::Lost) => state.resize(state.size), + // The system is out of memory, we should probably quit + Err(wgpu::SurfaceError::OutOfMemory) => panic!("Out of memory"), + // All other errors (Outdated, Timeout) should be resolved by the next frame + Err(e) => eprintln!("{:?}", e), + } + + // TODO: FRAME PACING. + } +} + pub async fn run() { env_logger::init(); let event_loop = EventLoop::new(); let window = WindowBuilder::new().build(&event_loop).unwrap(); - let mut state = State::new(window).await; + let state = State::new(window).await; + let (sender, reciever) = std::sync::mpsc::channel(); - let mut context = script::ScriptContext::new(); - context.init(); + std::thread::spawn(move || { + main_thread(state, reciever); + }); event_loop.run(move |event, _, control_flow| { control_flow.set_poll(); - match event { - Event::WindowEvent { - ref event, - window_id, - } if window_id == state.window().id() => { - if !state.input(event) { - match event { - WindowEvent::CloseRequested - | WindowEvent::KeyboardInput { - input: - KeyboardInput { - state: ElementState::Pressed, - virtual_keycode: Some(VirtualKeyCode::Escape), - .. - }, - .. - } => *control_flow = ControlFlow::Exit, - - WindowEvent::CursorMoved { position, .. } => { - state.mouse_x = position.x; - state.mouse_y = position.y; - state.window().request_redraw(); - } - - WindowEvent::Resized(physical_size) => { - state.resize(*physical_size); - } - - WindowEvent::ScaleFactorChanged { new_inner_size, .. } => { - // new_inner_size is &&mut so we have to dereference it twice - state.resize(**new_inner_size); - } - - _ => {} - } - } - } - - Event::RedrawRequested(window_id) if window_id == state.window().id() => { - context.update(); - state.update(); - - match state.render(context.render()) { - Ok(_) => {} - // Reconfigure the surface if lost - Err(wgpu::SurfaceError::Lost) => state.resize(state.size), - // The system is out of memory, we should probably quit - Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit, - // All other errors (Outdated, Timeout) should be resolved by the next frame - Err(e) => eprintln!("{:?}", e), - } - } - - Event::MainEventsCleared => { - // RedrawRequested will only trigger once, unless we manually - // request it. - state.window().request_redraw(); - } - - _ => {} + if let Some(e) = event.to_static() { + sender + .send(UIEvent { + winit: e, + time: Instant::now(), + }) + .unwrap(); } }); }