use std::collections::HashMap; use std::sync::Arc; use ctx::WgpuCtx; use tracing::{debug, error, info, trace, warn}; use winit::application::ApplicationHandler; use winit::event::WindowEvent; use winit::event_loop::ControlFlow; use winit::event_loop::{ActiveEventLoop, EventLoop}; use winit::window::{Window, WindowId}; pub mod ctx; struct WindowContext<'window> { window: Arc, ctx: WgpuCtx<'window>, } #[derive(Default)] pub struct App<'window> { windows: HashMap>, } impl ApplicationHandler for App<'_> { fn resumed(&mut self, event_loop: &ActiveEventLoop) { if self.windows.is_empty() { let win_attr = Window::default_attributes().with_title("Zenyx"); let window = Arc::new( event_loop .create_window(win_attr) .expect("create window err."), ); let window_id = window.id(); let wgpu_ctx = WgpuCtx::new_blocking(window.clone()).unwrap(); self.windows.insert(window_id, WindowContext { window, ctx: wgpu_ctx }); } } fn window_event( &mut self, event_loop: &ActiveEventLoop, window_id: WindowId, event: WindowEvent, ) { match event { WindowEvent::CloseRequested => { if let Some(window_context) = self.windows.remove(&window_id) { drop(window_context); println!("Window: {:?} closed, exiting", window_id); } if self.windows.is_empty() { event_loop.exit(); } } WindowEvent::KeyboardInput { device_id, event, is_synthetic, } => match event.physical_key { winit::keyboard::PhysicalKey::Code(code) => { if event.state.is_pressed() == false { return; } match code { winit::keyboard::KeyCode::Space => { debug!("Space key pressed"); if let Some(window_context) = self.windows.values_mut().next() { match window_context.ctx.bg_color() { wgpu::Color::WHITE => window_context.ctx.change_bg_color(wgpu::Color::BLACK), wgpu::Color::BLACK => window_context.ctx.change_bg_color(wgpu::Color::WHITE), _ => window_context.ctx.change_bg_color(wgpu::Color::WHITE), } } } winit::keyboard::KeyCode::Escape => { debug!("Escape key pressed, spawning new window"); let win_attr = Window::default_attributes() .with_title(format!("Zenyx - New Window {}", self.windows.len())); let new_window = Arc::new( event_loop .create_window(win_attr) .expect("create window err."), ); let window_id = new_window.id(); let wgpu_ctx = WgpuCtx::new_blocking(new_window.clone()).unwrap(); self.windows.insert(window_id, WindowContext { window: new_window, ctx: wgpu_ctx }); } _ => info!("Unimplemented keycode: {:?}", code), } } _ => {} }, WindowEvent::RedrawRequested => { if let Some(window_context) = self.windows.get_mut(&window_id) { window_context.ctx.draw(); window_context.window.request_redraw(); } } WindowEvent::Resized(size) => { if let Some(window_context) = self.windows.get_mut(&window_id) { window_context.ctx.resize(size.into()); window_context.window.request_redraw(); let size_str: String = size.height.to_string() + "x" + &size.width.to_string(); debug!("Window resized to {:?}", size_str); } } _ => trace!("Unhandled window event"), } } } pub fn init_renderer(event_loop: EventLoop<()>) { event_loop.set_control_flow(ControlFlow::Poll); let mut app = App::default(); event_loop.run_app(&mut app).unwrap(); }