From fda342ebb8c60286e3714adca9fa0684587cfadc Mon Sep 17 00:00:00 2001 From: Stephen Sherratt Date: Tue, 6 Feb 2024 22:29:15 +1100 Subject: [PATCH] Update wgpu deps --- wgpu/Cargo.toml | 7 +- wgpu/src/input.rs | 238 ++++++++++++-------------- wgpu/src/wgpu_context.rs | 358 ++++++++++++++++++++------------------- 3 files changed, 296 insertions(+), 307 deletions(-) diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index 960e3bf..aec5f30 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -18,11 +18,10 @@ gamepad = ["chargrid_gamepad", "chargrid_input/gamepad", "chargrid_runtime/gamep chargrid_input = { path = "../input", version = "0.5" } chargrid_gamepad = { path = "../gamepad", version = "0.5", optional = true } chargrid_runtime = { path = "../runtime", version = "0.3" } -wgpu = { version = "0.17", features = ["spirv"] } -wgpu_glyph = "0.21" -winit = "0.28" +wgpu = { version = "0.18", features = ["spirv"] } +wgpu_glyph = "0.22" +winit = { version = "0.29", features = ["rwh_05"] } zerocopy = { version = "0.7", features = ["derive"] } log = "0.4" grid_2d = "0.15" pollster = "0.3" -async-executor = "1.0" diff --git a/wgpu/src/input.rs b/wgpu/src/input.rs index 16ec845..c0513e5 100644 --- a/wgpu/src/input.rs +++ b/wgpu/src/input.rs @@ -1,12 +1,12 @@ use crate::Dimensions; use chargrid_input::{ - keys, Coord, Input, Key, KeyboardEvent, KeyboardInput, MouseButton as ChargridMouseButton, - MouseButton, MouseInput, ScrollDirection, + keys, Coord, Input, Key, KeyboardInput, MouseButton as ChargridMouseButton, MouseButton, + MouseInput, ScrollDirection, }; -use winit::dpi::{LogicalPosition, PhysicalSize}; -use winit::event::{ - ElementState, ModifiersState, MouseButton as GlutinMouseButton, MouseScrollDelta, - VirtualKeyCode, WindowEvent, +use winit::{ + dpi::{LogicalPosition, PhysicalSize}, + event::{ElementState, MouseButton as GlutinMouseButton, MouseScrollDelta, WindowEvent}, + keyboard::{KeyCode, ModifiersState, PhysicalKey}, }; pub enum Event { @@ -21,119 +21,106 @@ macro_rules! convert_char_shift { } #[allow(clippy::cognitive_complexity)] -fn convert_keycode_keyboard_input(code: VirtualKeyCode, shift: bool) -> Option { +fn convert_keycode_keyboard_input(code: KeyCode, shift: bool) -> Option { let keyboard_input = match code { - VirtualKeyCode::Space => Key::Char(' '), - VirtualKeyCode::A => convert_char_shift!('a', 'A', shift), - VirtualKeyCode::B => convert_char_shift!('b', 'B', shift), - VirtualKeyCode::C => convert_char_shift!('c', 'C', shift), - VirtualKeyCode::D => convert_char_shift!('d', 'D', shift), - VirtualKeyCode::E => convert_char_shift!('e', 'E', shift), - VirtualKeyCode::F => convert_char_shift!('f', 'F', shift), - VirtualKeyCode::G => convert_char_shift!('g', 'G', shift), - VirtualKeyCode::H => convert_char_shift!('h', 'H', shift), - VirtualKeyCode::I => convert_char_shift!('i', 'I', shift), - VirtualKeyCode::J => convert_char_shift!('j', 'J', shift), - VirtualKeyCode::K => convert_char_shift!('k', 'K', shift), - VirtualKeyCode::L => convert_char_shift!('l', 'L', shift), - VirtualKeyCode::M => convert_char_shift!('m', 'M', shift), - VirtualKeyCode::N => convert_char_shift!('n', 'N', shift), - VirtualKeyCode::O => convert_char_shift!('o', 'O', shift), - VirtualKeyCode::P => convert_char_shift!('p', 'P', shift), - VirtualKeyCode::Q => convert_char_shift!('q', 'Q', shift), - VirtualKeyCode::R => convert_char_shift!('r', 'R', shift), - VirtualKeyCode::S => convert_char_shift!('s', 'S', shift), - VirtualKeyCode::T => convert_char_shift!('t', 'T', shift), - VirtualKeyCode::U => convert_char_shift!('u', 'U', shift), - VirtualKeyCode::V => convert_char_shift!('v', 'V', shift), - VirtualKeyCode::W => convert_char_shift!('w', 'W', shift), - VirtualKeyCode::X => convert_char_shift!('x', 'X', shift), - VirtualKeyCode::Y => convert_char_shift!('y', 'Y', shift), - VirtualKeyCode::Z => convert_char_shift!('z', 'Z', shift), - VirtualKeyCode::Key1 => convert_char_shift!('1', '!', shift), - VirtualKeyCode::Key2 => Key::Char('2'), - VirtualKeyCode::Key3 => convert_char_shift!('3', '#', shift), - VirtualKeyCode::Key4 => convert_char_shift!('4', '$', shift), - VirtualKeyCode::Key5 => convert_char_shift!('5', '%', shift), - VirtualKeyCode::Key6 => convert_char_shift!('6', '^', shift), - VirtualKeyCode::Key7 => convert_char_shift!('7', '&', shift), - VirtualKeyCode::Key8 => convert_char_shift!('8', '*', shift), - VirtualKeyCode::Key9 => convert_char_shift!('9', '(', shift), - VirtualKeyCode::Key0 => convert_char_shift!('0', ')', shift), - VirtualKeyCode::Numpad1 => Key::Char('1'), - VirtualKeyCode::Numpad2 => Key::Char('2'), - VirtualKeyCode::Numpad3 => Key::Char('3'), - VirtualKeyCode::Numpad4 => Key::Char('4'), - VirtualKeyCode::Numpad5 => Key::Char('5'), - VirtualKeyCode::Numpad6 => Key::Char('6'), - VirtualKeyCode::Numpad7 => Key::Char('7'), - VirtualKeyCode::Numpad8 => Key::Char('8'), - VirtualKeyCode::Numpad9 => Key::Char('9'), - VirtualKeyCode::Numpad0 => Key::Char('0'), - VirtualKeyCode::Left => Key::Left, - VirtualKeyCode::Right => Key::Right, - VirtualKeyCode::Up => Key::Up, - VirtualKeyCode::Down => Key::Down, - VirtualKeyCode::Escape => keys::ESCAPE, - VirtualKeyCode::Return => keys::RETURN, - VirtualKeyCode::At => Key::Char('@'), - VirtualKeyCode::Plus => Key::Char('+'), - VirtualKeyCode::Minus => Key::Char('-'), - VirtualKeyCode::Equals => convert_char_shift!('=', '+', shift), - VirtualKeyCode::Backslash => convert_char_shift!('\\', '|', shift), - VirtualKeyCode::Grave => convert_char_shift!('`', '~', shift), - VirtualKeyCode::Apostrophe => convert_char_shift!('\'', '"', shift), - VirtualKeyCode::LBracket => convert_char_shift!('[', '{', shift), - VirtualKeyCode::RBracket => convert_char_shift!(']', '}', shift), - VirtualKeyCode::PageUp => Key::PageUp, - VirtualKeyCode::PageDown => Key::PageDown, - VirtualKeyCode::Home => Key::Home, - VirtualKeyCode::End => Key::End, - VirtualKeyCode::F1 => Key::Function(1), - VirtualKeyCode::F2 => Key::Function(2), - VirtualKeyCode::F3 => Key::Function(3), - VirtualKeyCode::F4 => Key::Function(4), - VirtualKeyCode::F5 => Key::Function(5), - VirtualKeyCode::F6 => Key::Function(6), - VirtualKeyCode::F7 => Key::Function(7), - VirtualKeyCode::F8 => Key::Function(8), - VirtualKeyCode::F9 => Key::Function(9), - VirtualKeyCode::F10 => Key::Function(10), - VirtualKeyCode::F11 => Key::Function(11), - VirtualKeyCode::F12 => Key::Function(12), - VirtualKeyCode::F13 => Key::Function(13), - VirtualKeyCode::F14 => Key::Function(14), - VirtualKeyCode::F15 => Key::Function(15), - VirtualKeyCode::F16 => Key::Function(16), - VirtualKeyCode::F17 => Key::Function(17), - VirtualKeyCode::F18 => Key::Function(18), - VirtualKeyCode::F19 => Key::Function(19), - VirtualKeyCode::F20 => Key::Function(20), - VirtualKeyCode::F21 => Key::Function(21), - VirtualKeyCode::F22 => Key::Function(22), - VirtualKeyCode::F23 => Key::Function(23), - VirtualKeyCode::F24 => Key::Function(24), - VirtualKeyCode::Back => keys::BACKSPACE, - VirtualKeyCode::Delete => Key::Delete, + KeyCode::Space => Key::Char(' '), + KeyCode::KeyA => convert_char_shift!('a', 'A', shift), + KeyCode::KeyB => convert_char_shift!('b', 'B', shift), + KeyCode::KeyC => convert_char_shift!('c', 'C', shift), + KeyCode::KeyD => convert_char_shift!('d', 'D', shift), + KeyCode::KeyE => convert_char_shift!('e', 'E', shift), + KeyCode::KeyF => convert_char_shift!('f', 'F', shift), + KeyCode::KeyG => convert_char_shift!('g', 'G', shift), + KeyCode::KeyH => convert_char_shift!('h', 'H', shift), + KeyCode::KeyI => convert_char_shift!('i', 'I', shift), + KeyCode::KeyJ => convert_char_shift!('j', 'J', shift), + KeyCode::KeyK => convert_char_shift!('k', 'K', shift), + KeyCode::KeyL => convert_char_shift!('l', 'L', shift), + KeyCode::KeyM => convert_char_shift!('m', 'M', shift), + KeyCode::KeyN => convert_char_shift!('n', 'N', shift), + KeyCode::KeyO => convert_char_shift!('o', 'O', shift), + KeyCode::KeyP => convert_char_shift!('p', 'P', shift), + KeyCode::KeyQ => convert_char_shift!('q', 'Q', shift), + KeyCode::KeyR => convert_char_shift!('r', 'R', shift), + KeyCode::KeyS => convert_char_shift!('s', 'S', shift), + KeyCode::KeyT => convert_char_shift!('t', 'T', shift), + KeyCode::KeyU => convert_char_shift!('u', 'U', shift), + KeyCode::KeyV => convert_char_shift!('v', 'V', shift), + KeyCode::KeyW => convert_char_shift!('w', 'W', shift), + KeyCode::KeyX => convert_char_shift!('x', 'X', shift), + KeyCode::KeyY => convert_char_shift!('y', 'Y', shift), + KeyCode::KeyZ => convert_char_shift!('z', 'Z', shift), + KeyCode::Digit1 => convert_char_shift!('1', '!', shift), + KeyCode::Digit2 => convert_char_shift!('2', '@', shift), + KeyCode::Digit3 => convert_char_shift!('3', '#', shift), + KeyCode::Digit4 => convert_char_shift!('4', '$', shift), + KeyCode::Digit5 => convert_char_shift!('5', '%', shift), + KeyCode::Digit6 => convert_char_shift!('6', '^', shift), + KeyCode::Digit7 => convert_char_shift!('7', '&', shift), + KeyCode::Digit8 => convert_char_shift!('8', '*', shift), + KeyCode::Digit9 => convert_char_shift!('9', '(', shift), + KeyCode::Digit0 => convert_char_shift!('0', ')', shift), + KeyCode::Numpad1 => Key::Char('1'), + KeyCode::Numpad2 => Key::Char('2'), + KeyCode::Numpad3 => Key::Char('3'), + KeyCode::Numpad4 => Key::Char('4'), + KeyCode::Numpad5 => Key::Char('5'), + KeyCode::Numpad6 => Key::Char('6'), + KeyCode::Numpad7 => Key::Char('7'), + KeyCode::Numpad8 => Key::Char('8'), + KeyCode::Numpad9 => Key::Char('9'), + KeyCode::Numpad0 => Key::Char('0'), + KeyCode::ArrowLeft => Key::Left, + KeyCode::ArrowRight => Key::Right, + KeyCode::ArrowUp => Key::Up, + KeyCode::ArrowDown => Key::Down, + KeyCode::Escape => keys::ESCAPE, + KeyCode::Enter => keys::RETURN, + KeyCode::Minus => Key::Char('-'), + KeyCode::Equal => convert_char_shift!('=', '+', shift), + KeyCode::Backslash => convert_char_shift!('\\', '|', shift), + KeyCode::Backquote => convert_char_shift!('`', '~', shift), + KeyCode::Quote => convert_char_shift!('\'', '"', shift), + KeyCode::BracketLeft => convert_char_shift!('[', '{', shift), + KeyCode::BracketRight => convert_char_shift!(']', '}', shift), + KeyCode::PageUp => Key::PageUp, + KeyCode::PageDown => Key::PageDown, + KeyCode::Home => Key::Home, + KeyCode::End => Key::End, + KeyCode::F1 => Key::Function(1), + KeyCode::F2 => Key::Function(2), + KeyCode::F3 => Key::Function(3), + KeyCode::F4 => Key::Function(4), + KeyCode::F5 => Key::Function(5), + KeyCode::F6 => Key::Function(6), + KeyCode::F7 => Key::Function(7), + KeyCode::F8 => Key::Function(8), + KeyCode::F9 => Key::Function(9), + KeyCode::F10 => Key::Function(10), + KeyCode::F11 => Key::Function(11), + KeyCode::F12 => Key::Function(12), + KeyCode::F13 => Key::Function(13), + KeyCode::F14 => Key::Function(14), + KeyCode::F15 => Key::Function(15), + KeyCode::F16 => Key::Function(16), + KeyCode::F17 => Key::Function(17), + KeyCode::F18 => Key::Function(18), + KeyCode::F19 => Key::Function(19), + KeyCode::F20 => Key::Function(20), + KeyCode::F21 => Key::Function(21), + KeyCode::F22 => Key::Function(22), + KeyCode::F23 => Key::Function(23), + KeyCode::F24 => Key::Function(24), + KeyCode::Backspace => keys::BACKSPACE, + KeyCode::Delete => Key::Delete, + KeyCode::Comma => convert_char_shift!(',', '<', shift), + KeyCode::Period => convert_char_shift!('.', '>', shift), + KeyCode::Slash => convert_char_shift!('/', '?', shift), _ => return None, }; Some(keyboard_input) } -fn convert_keycode(code: VirtualKeyCode, keymod: ModifiersState) -> Option { - convert_keycode_keyboard_input(code, keymod.shift()) -} - -fn convert_char(ch: char) -> Option { - match ch { - '>' | '.' | ',' | '<' | '/' | '?' => Some(Event::Input(Input::Keyboard(KeyboardInput { - key: Key::Char(ch), - event: KeyboardEvent::KeyPress, - }))), - _ => None, - } -} - pub fn convert_event( event: WindowEvent, cell_dimensions: Dimensions, @@ -148,22 +135,13 @@ pub fn convert_event( KeyboardInput::key_press(chargrid_input::keys::ETX), ))), WindowEvent::Resized(physical_size) => Some(Event::Resize(physical_size)), - WindowEvent::ScaleFactorChanged { - scale_factor: new_scale_factor, - new_inner_size, - } => { - *scale_factor = new_scale_factor; - Some(Event::Resize(*new_inner_size)) - } - WindowEvent::ReceivedCharacter(ch) => convert_char(ch), - WindowEvent::KeyboardInput { input, .. } => { - if let Some(virtual_keycode) = input.virtual_keycode { - if let Some(key) = convert_keycode(virtual_keycode, modifier_state) { - match input.state { - ElementState::Pressed => { - return Some(Event::Input(Input::key_press(key))); - } - ElementState::Released => return None, + WindowEvent::KeyboardInput { event, .. } => { + if event.state == ElementState::Pressed { + if let PhysicalKey::Code(key_code) = event.physical_key { + if let Some(key) = + convert_keycode_keyboard_input(key_code, modifier_state.shift_key()) + { + return Some(Event::Input(Input::key_press(key))); } } } @@ -189,7 +167,7 @@ pub fn convert_event( GlutinMouseButton::Left => ChargridMouseButton::Left, GlutinMouseButton::Middle => ChargridMouseButton::Middle, GlutinMouseButton::Right => ChargridMouseButton::Right, - GlutinMouseButton::Other(_) => return None, + _ => return None, }; let input = match state { ElementState::Pressed => { diff --git a/wgpu/src/wgpu_context.rs b/wgpu/src/wgpu_context.rs index 1e4750e..0ef7b35 100644 --- a/wgpu/src/wgpu_context.rs +++ b/wgpu/src/wgpu_context.rs @@ -87,7 +87,7 @@ struct WgpuContext { global_uniforms_buffer: wgpu::Buffer, window_size: winit::dpi::LogicalSize, scale_factor: f64, - modifier_state: winit::event::ModifiersState, + modifier_state: winit::keyboard::ModifiersState, global_uniforms_to_sync: Option, } @@ -146,6 +146,8 @@ async fn request_adapter_for_backend( let instance_descriptor = wgpu::InstanceDescriptor { backends, dx12_shader_compiler: wgpu::Dx12Compiler::default(), + flags: wgpu::InstanceFlags::default(), + gles_minor_version: wgpu::Gles3MinorVersion::Automatic, }; let instance = wgpu::Instance::new(instance_descriptor); let surface = unsafe { instance.create_surface(window) } @@ -173,7 +175,7 @@ async fn setup( resizable: bool, force_secondary_adapter: bool, ) -> Setup { - let event_loop = winit::event_loop::EventLoop::new(); + let event_loop = winit::event_loop::EventLoop::new().unwrap(); let window_builder = winit::window::WindowBuilder::new().with_title(title); let window_builder = { let logical_size = @@ -439,7 +441,7 @@ impl WgpuContext { wgpu_glyph::GlyphBrushBuilder::using_fonts(font_bytes_to_fonts(font_bytes)) .texture_filter_method(wgpu::FilterMode::Nearest) .build(&mut device, surface_configuration.format); - let modifier_state = winit::event::ModifiersState::default(); + let modifier_state = winit::keyboard::ModifiersState::default(); Ok(Self { device, surface, @@ -724,7 +726,7 @@ impl Context { * is passed to the component's `update` method. When the component yields `Some(app::Exit)`, * the program will exit. This method never returns. */ - pub fn run(self, mut component: C) -> ! + pub fn run(self, mut component: C) where C: 'static + Component, { @@ -746,187 +748,197 @@ impl Context { log::info!("Entering main event loop"); let mut current_window_dimensions = size_context.native_window_dimensions; let mut staging_belt = wgpu::util::StagingBelt::new(1024); - let executor = async_executor::LocalExecutor::new(); - event_loop.run(move |event, _, control_flow| { - let _ = (&instance, &adapter); // force ownership by the closure - if exited { - *control_flow = winit::event_loop::ControlFlow::Exit; - return; - } else { - *control_flow = winit::event_loop::ControlFlow::Poll; - }; - #[cfg(feature = "gamepad")] - for input in gamepad.drain_input() { - if let Some(app::Exit) = on_input( - &mut component, - chargrid_input::Input::Gamepad(input), - &wgpu_context.chargrid_frame_buffer, - ) { - exited = true; + event_loop + .run(move |event, elwt| { + let _ = (&instance, &adapter); // force ownership by the closure + if exited { + elwt.exit(); return; + } else { + elwt.set_control_flow(winit::event_loop::ControlFlow::Poll); + }; + let target_frametime = Duration::from_secs_f64(1.0 / 60.0); + let time_since_last_frame = last_update_inst.elapsed(); + if time_since_last_frame >= target_frametime { + window.request_redraw(); + last_update_inst = Instant::now(); + } else { + elwt.set_control_flow(winit::event_loop::ControlFlow::WaitUntil( + Instant::now() + target_frametime - time_since_last_frame, + )); } - } - match event { - winit::event::Event::WindowEvent { - event: window_event, - .. - } => match window_event { - winit::event::WindowEvent::ModifiersChanged(modifier_state) => { - wgpu_context.modifier_state = modifier_state; - } - other => { - if let Some(event) = input::convert_event( - other, - size_context.scaled_cell_dimensions(current_window_dimensions), - size_context - .pixel_offset_to_centre_native_window(current_window_dimensions), - &mut input_context.last_mouse_coord, - &mut input_context.last_mouse_button, - &mut wgpu_context.scale_factor, - wgpu_context.modifier_state, - ) { - match event { - input::Event::Input(input) => { - if let Some(app::Exit) = on_input( - &mut component, - input, - &wgpu_context.chargrid_frame_buffer, - ) { - exited = true; - return; - } - } - input::Event::Resize(size) => { - wgpu_context.resize(&size_context, size); - current_window_dimensions = - dimensions_from_logical_size(wgpu_context.window_size); - } - } - } - } - }, - winit::event::Event::RedrawRequested(_) => { - let frame_duration = frame_instant.elapsed(); - frame_instant = Instant::now(); - if let Some(app::Exit) = on_frame( + #[cfg(feature = "gamepad")] + for input in gamepad.drain_input() { + if let Some(app::Exit) = on_input( &mut component, - frame_duration, - &mut wgpu_context.chargrid_frame_buffer, + chargrid_input::Input::Gamepad(input), + &wgpu_context.chargrid_frame_buffer, ) { exited = true; return; } - wgpu_context.render_background(); - if let Ok(frame) = wgpu_context.surface.get_current_texture() { - let mut encoder = wgpu_context.device.create_command_encoder( - &wgpu::CommandEncoderDescriptor { label: None }, - ); - wgpu_context.sync_global_uniforms(&mut encoder); - let view = frame - .texture - .create_view(&wgpu::TextureViewDescriptor::default()); - - { - let mut render_pass = - encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: None, - color_attachments: &[Some(wgpu::RenderPassColorAttachment { - view: &view, - resolve_target: None, - ops: wgpu::Operations { - load: wgpu::LoadOp::Clear(wgpu::Color::BLACK), - store: true, - }, - })], - depth_stencil_attachment: None, - }); - render_pass.set_pipeline(&wgpu_context.render_pipeline); - render_pass.set_bind_group(0, &wgpu_context.bind_group, &[]); - render_pass.set_vertex_buffer( - 0, - wgpu_context.background_cell_instance_buffer.slice(..), - ); - render_pass.draw( - 0..6, - 0..wgpu_context.chargrid_frame_buffer.size().count() as u32, - ); + } + match event { + winit::event::Event::WindowEvent { + event: window_event, + .. + } => match window_event { + winit::event::WindowEvent::ModifiersChanged(modifiers) => { + wgpu_context.modifier_state = modifiers.state(); } - let offset_to_centre = size_context - .pixel_offset_to_centre_native_window(current_window_dimensions); - let font_scale = size_context.font_source_scale; - text_buffer.clear(); - for row in wgpu_context.chargrid_frame_buffer.rows() { - for cell in row { - text_buffer.push(cell.character); + winit::event::WindowEvent::RedrawRequested => { + let frame_duration = frame_instant.elapsed(); + frame_instant = Instant::now(); + if let Some(app::Exit) = on_frame( + &mut component, + frame_duration, + &mut wgpu_context.chargrid_frame_buffer, + ) { + exited = true; + return; } - } - let mut section = wgpu_glyph::Section::default().with_screen_position(( - offset_to_centre.width as f32, - offset_to_centre.height as f32, - )); - let mut char_start = 0; - for (ch, (coord, cell)) in text_buffer - .chars() - .zip(wgpu_context.chargrid_frame_buffer.enumerate()) - { - let char_end = char_start + ch.len_utf8(); - let str_slice = &text_buffer[char_start..char_end]; - let font_id = if cell.bold { - FONT_ID_BOLD + wgpu_context.render_background(); + if let Ok(frame) = wgpu_context.surface.get_current_texture() { + let mut encoder = wgpu_context.device.create_command_encoder( + &wgpu::CommandEncoderDescriptor { label: None }, + ); + wgpu_context.sync_global_uniforms(&mut encoder); + let view = frame + .texture + .create_view(&wgpu::TextureViewDescriptor::default()); + + { + let mut render_pass = + encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: None, + color_attachments: &[Some( + wgpu::RenderPassColorAttachment { + view: &view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear( + wgpu::Color::BLACK, + ), + store: wgpu::StoreOp::Store, + }, + }, + )], + depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, + }); + render_pass.set_pipeline(&wgpu_context.render_pipeline); + render_pass.set_bind_group(0, &wgpu_context.bind_group, &[]); + render_pass.set_vertex_buffer( + 0, + wgpu_context.background_cell_instance_buffer.slice(..), + ); + render_pass.draw( + 0..6, + 0..wgpu_context.chargrid_frame_buffer.size().count() as u32, + ); + } + let offset_to_centre = size_context + .pixel_offset_to_centre_native_window( + current_window_dimensions, + ); + let font_scale = size_context.font_source_scale; + text_buffer.clear(); + for row in wgpu_context.chargrid_frame_buffer.rows() { + for cell in row { + text_buffer.push(cell.character); + } + } + let mut section = wgpu_glyph::Section::default() + .with_screen_position(( + offset_to_centre.width as f32, + offset_to_centre.height as f32, + )); + let mut char_start = 0; + for (ch, (coord, cell)) in text_buffer + .chars() + .zip(wgpu_context.chargrid_frame_buffer.enumerate()) + { + let char_end = char_start + ch.len_utf8(); + let str_slice = &text_buffer[char_start..char_end]; + let font_id = if cell.bold { + FONT_ID_BOLD + } else { + FONT_ID_NORMAL + }; + section = section.add_text( + wgpu_glyph::Text::new(str_slice) + .with_scale(font_scale) + .with_font_id(font_id) + .with_color(rgba_to_srgb( + cell.foreground.to_f32_array_01(), + )), + ); + char_start = char_end; + if coord.x as u32 + == wgpu_context.chargrid_frame_buffer.size().width() - 1 + { + section = section.add_text( + wgpu_glyph::Text::new("\n").with_scale(font_scale), + ); + } + } + wgpu_context.glyph_brush.queue(section); + wgpu_context + .glyph_brush + .draw_queued( + &wgpu_context.device, + &mut staging_belt, + &mut encoder, + &view, + wgpu_context.window_size.width as u32, + wgpu_context.window_size.height as u32, + ) + .unwrap(); + staging_belt.finish(); + wgpu_context.queue.submit(std::iter::once(encoder.finish())); + staging_belt.recall(); + frame.present(); } else { - FONT_ID_NORMAL - }; - section = section.add_text( - wgpu_glyph::Text::new(str_slice) - .with_scale(font_scale) - .with_font_id(font_id) - .with_color(rgba_to_srgb(cell.foreground.to_f32_array_01())), - ); - char_start = char_end; - if coord.x as u32 - == wgpu_context.chargrid_frame_buffer.size().width() - 1 - { - section = section - .add_text(wgpu_glyph::Text::new("\n").with_scale(font_scale)); + log::warn!("timeout when acquiring next swapchain texture"); + thread::sleep(Duration::from_millis(100)); } } - wgpu_context.glyph_brush.queue(section); - wgpu_context - .glyph_brush - .draw_queued( - &wgpu_context.device, - &mut staging_belt, - &mut encoder, - &view, - wgpu_context.window_size.width as u32, - wgpu_context.window_size.height as u32, - ) - .unwrap(); - staging_belt.finish(); - wgpu_context.queue.submit(std::iter::once(encoder.finish())); - staging_belt.recall(); - frame.present(); - } else { - log::warn!("timeout when acquiring next swapchain texture"); - thread::sleep(Duration::from_millis(100)); - } - } - winit::event::Event::RedrawEventsCleared => { - let target_frametime = Duration::from_secs_f64(1.0 / 60.0); - let time_since_last_frame = last_update_inst.elapsed(); - if time_since_last_frame >= target_frametime { - window.request_redraw(); - last_update_inst = Instant::now(); - } else { - *control_flow = winit::event_loop::ControlFlow::WaitUntil( - Instant::now() + target_frametime - time_since_last_frame, - ); - } - - while executor.try_tick() {} + other => { + if let Some(event) = input::convert_event( + other, + size_context.scaled_cell_dimensions(current_window_dimensions), + size_context.pixel_offset_to_centre_native_window( + current_window_dimensions, + ), + &mut input_context.last_mouse_coord, + &mut input_context.last_mouse_button, + &mut wgpu_context.scale_factor, + wgpu_context.modifier_state, + ) { + match event { + input::Event::Input(input) => { + if let Some(app::Exit) = on_input( + &mut component, + input, + &wgpu_context.chargrid_frame_buffer, + ) { + exited = true; + return; + } + } + input::Event::Resize(size) => { + wgpu_context.resize(&size_context, size); + current_window_dimensions = + dimensions_from_logical_size(wgpu_context.window_size); + } + } + } + } + }, + _ => (), } - _ => (), - } - }) + }) + .expect("Run loop exitted with error") } }