diff --git a/client/Cargo.toml b/client/Cargo.toml index b67bfecf..7903b7a3 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -16,7 +16,7 @@ ash = { version = "0.38.0", default-features = false, features = ["loaded", "deb lahar = { git = "https://github.com/Ralith/lahar", rev = "7963ae5750ea61fa0a894dbb73d3be0ac77255d2" } yakui = { git = "https://github.com/SecondHalfGames/yakui", rev = "273a4a1020803066b84ac69a7646893419c31385" } yakui-vulkan = { git = "https://github.com/SecondHalfGames/yakui", rev = "273a4a1020803066b84ac69a7646893419c31385" } -winit = "0.29.10" +winit = "0.30.4" ash-window = "0.13" raw-window-handle = "0.6" directories = "5.0.1" diff --git a/client/src/graphics/window.rs b/client/src/graphics/window.rs index e77ceb29..a40a569f 100644 --- a/client/src/graphics/window.rs +++ b/client/src/graphics/window.rs @@ -7,13 +7,12 @@ use lahar::DedicatedImage; use raw_window_handle::{HasDisplayHandle, HasWindowHandle}; use tracing::{error, info}; use winit::event::KeyEvent; -use winit::event_loop::EventLoopWindowTarget; +use winit::event_loop::ActiveEventLoop; use winit::keyboard::{KeyCode, PhysicalKey}; use winit::{ dpi::PhysicalSize, event::{DeviceEvent, ElementState, MouseButton, WindowEvent}, - event_loop::EventLoop, - window::{CursorGrabMode, Window as WinitWindow, WindowBuilder}, + window::{CursorGrabMode, Window as WinitWindow}, }; use super::gui::GuiState; @@ -28,11 +27,10 @@ pub struct EarlyWindow { } impl EarlyWindow { - pub fn new(event_loop: &EventLoop<()>) -> Self { - let window = WindowBuilder::new() - .with_title("hypermine") - .build(&event_loop) - .unwrap(); + pub fn new(event_loop: &ActiveEventLoop) -> Self { + let mut attrs = WinitWindow::default_attributes(); + attrs.title = "hypermine".into(); + let window = event_loop.create_window(attrs).unwrap(); Self { window, required_extensions: ash_window::enumerate_required_extensions( @@ -111,7 +109,7 @@ impl Window { pub fn init_rendering(&mut self, gfx: Arc) { // Allocate the presentable images we'll be rendering to self.swapchain = Some(SwapchainMgr::new( - &self, + self, gfx.clone(), self.window.inner_size(), )); @@ -135,7 +133,7 @@ impl Window { } } - pub fn handle_event(&mut self, event: WindowEvent, window_target: &EventLoopWindowTarget<()>) { + pub fn handle_event(&mut self, event: WindowEvent, event_loop: &ActiveEventLoop) { match event { WindowEvent::RedrawRequested => { while let Ok(msg) = self.net.incoming.try_recv() { @@ -165,7 +163,7 @@ impl Window { } WindowEvent::CloseRequested => { info!("exiting due to closed window"); - window_target.exit(); + event_loop.exit(); } WindowEvent::MouseInput { button: MouseButton::Left, diff --git a/client/src/main.rs b/client/src/main.rs index 37039cf8..0e5540fa 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -9,7 +9,10 @@ use save::Save; use ash::khr; use tracing::{error, error_span, info}; -use winit::{event::Event, event_loop::EventLoop}; +use winit::{ + application::ApplicationHandler, + event_loop::{ActiveEventLoop, EventLoop}, +}; fn main() { // Set up logging @@ -58,49 +61,88 @@ fn main() { } }); } - let config = Arc::new(config); + let mut app = App { + config: Arc::new(config), + dirs, + metrics, + window: None, + }; - // Create the OS window let event_loop = EventLoop::new().unwrap(); - let window = graphics::EarlyWindow::new(&event_loop); - // Initialize Vulkan with the extensions needed to render to the window - let core = Arc::new(graphics::Core::new(window.required_extensions())); - - // Kick off networking - let net = net::spawn(config.clone()); - - // Finish creating the window, including the Vulkan resources used to render to it - let mut window = graphics::Window::new(window, core.clone(), config, net); - - // Initialize widely-shared graphics resources - let gfx = Arc::new( - graphics::Base::new( - core, - Some(dirs.cache_dir().join("pipeline_cache")), - &[khr::swapchain::NAME], - |physical, queue_family| window.supports(physical, queue_family), - ) - .unwrap(), - ); - - window.init_rendering(gfx); - - // Run the window's event loop - event_loop - .run(|event, window_target| match event { - Event::AboutToWait => { - window.window.request_redraw(); - } - Event::DeviceEvent { event, .. } => { - window.handle_device_event(event); - } - Event::WindowEvent { event, .. } => { - window.handle_event(event, window_target); - } - Event::LoopExiting => { - metrics.report(); - } - _ => {} - }) - .unwrap(); + event_loop.set_control_flow(winit::event_loop::ControlFlow::Poll); + event_loop.run_app(&mut app).unwrap(); +} + +struct App { + config: Arc, + dirs: directories::ProjectDirs, + metrics: Arc, + window: Option, +} + +impl ApplicationHandler for App { + fn resumed(&mut self, event_loop: &ActiveEventLoop) { + // Create the OS window + let window = graphics::EarlyWindow::new(event_loop); + // Initialize Vulkan with the extensions needed to render to the window + let core = Arc::new(graphics::Core::new(window.required_extensions())); + + // Kick off networking + let net = net::spawn(self.config.clone()); + + // Finish creating the window, including the Vulkan resources used to render to it + let mut window = graphics::Window::new(window, core.clone(), self.config.clone(), net); + + // Initialize widely-shared graphics resources + let gfx = Arc::new( + graphics::Base::new( + core, + Some(self.dirs.cache_dir().join("pipeline_cache")), + &[khr::swapchain::NAME], + |physical, queue_family| window.supports(physical, queue_family), + ) + .unwrap(), + ); + window.init_rendering(gfx.clone()); + self.window = Some(window); + } + + fn suspended(&mut self, _event_loop: &ActiveEventLoop) { + self.window = None; + } + + fn window_event( + &mut self, + event_loop: &ActiveEventLoop, + _window_id: winit::window::WindowId, + event: winit::event::WindowEvent, + ) { + let Some(window) = self.window.as_mut() else { + return; + }; + window.handle_event(event, event_loop); + } + + fn device_event( + &mut self, + _event_loop: &ActiveEventLoop, + _device_id: winit::event::DeviceId, + event: winit::event::DeviceEvent, + ) { + let Some(window) = self.window.as_mut() else { + return; + }; + window.handle_device_event(event); + } + + fn about_to_wait(&mut self, _event_loop: &ActiveEventLoop) { + let Some(window) = self.window.as_mut() else { + return; + }; + window.window.request_redraw(); + } + + fn exiting(&mut self, _event_loop: &ActiveEventLoop) { + self.metrics.report(); + } }