diff --git a/engine/src/core/panic.rs b/engine/src/core/panic.rs index 92d8ae1..0a3cc23 100644 --- a/engine/src/core/panic.rs +++ b/engine/src/core/panic.rs @@ -46,7 +46,7 @@ fn process_panic(info: &std::panic::PanicHookInfo<'_>) -> Result<(), Box) -> Result<(), Box String { - const HEX_WIDTH: usize = mem::size_of::() * 2 + 2; - const NEXT_SYMBOL_PADDING: usize = HEX_WIDTH + 6; - - let mut backtrace = String::new(); - let bt = Backtrace::new(); - let symbols = bt - .frames() - .iter() - .flat_map(|frame| { - let symbols = frame.symbols(); - if symbols.is_empty() { - vec![(frame, None, "".to_owned())] - } else { - symbols - .iter() - .map(|s| { - ( - frame, - Some(s), - s.name() - .map(|n| n.to_string()) - .unwrap_or_else(|| "".to_owned()), - ) - }) - .collect::>() - } - }) - .collect::>(); - let begin_unwind = "rust_begin_unwind"; - let begin_unwind_start = symbols - .iter() - .position(|(_, _, n)| n == begin_unwind) - .unwrap_or(0); - for (entry_idx, (frame, symbol, name)) in symbols.iter().skip(begin_unwind_start).enumerate() { - let ip = frame.ip(); - let _ = writeln!(backtrace, "{entry_idx:4}: {ip:HEX_WIDTH$?} - {name}"); - if let Some(symbol) = symbol { - if let (Some(file), Some(line)) = (symbol.filename(), symbol.lineno()) { - let _ = writeln!( - backtrace, - "{:3$}at {}:{}", - "", - file.display(), - line, - NEXT_SYMBOL_PADDING - ); - } + .show_confirm() { + error!("Failed to show message dialog: {e}") } - } + + Ok(()) +} +fn capture_backtrace() -> String { + let mut backtrace = String::new(); + let sysinfo = crate::metadata::SystemMetadata::current(); + backtrace.push_str(&sysinfo.verbose_summary()); + + let trace = backtrace::Backtrace::new(); + let message = format!("\nBacktrace:\n\n"); + backtrace.push_str(&message); + backtrace.push_str(&format!("{trace:?}")); + + + backtrace } diff --git a/engine/src/core/render/ctx.rs b/engine/src/core/render/ctx.rs index 596f49b..664c01f 100644 --- a/engine/src/core/render/ctx.rs +++ b/engine/src/core/render/ctx.rs @@ -5,7 +5,6 @@ use std::time::Instant; use cgmath::{Deg, Matrix4, Point3, Rad, SquareMatrix, Vector3, perspective}; use futures::executor::block_on; -use thiserror::Error; use tracing::{debug, error, info, trace}; use wgpu::TextureUsages; use wgpu::{Backends, InstanceDescriptor, util::DeviceExt}; @@ -370,13 +369,12 @@ impl<'window> Renderer<'window> { surface.configure(&device, &surface_config); let (depth_texture, depth_texture_view) = create_depth_texture(&device, surface_config.width, surface_config.height); - let (depth_texture, depth_texture_view) = - create_depth_texture(&device, surface_config.width, surface_config.height); let font_bytes = include_bytes!("DejaVuSans.ttf"); let font = FontRef::try_from_slice(font_bytes).map_err(|e| { - ZenyxError::builder(ZenyxErrorKind::DeviceRequest) + ZenyxError::builder(ZenyxErrorKind::FontLoading) .with_message("Font loading failed") + .with_source(e) .build() })?; diff --git a/engine/src/core/render/mod.rs b/engine/src/core/render/mod.rs index 313e8dc..e4ead8d 100644 --- a/engine/src/core/render/mod.rs +++ b/engine/src/core/render/mod.rs @@ -8,7 +8,6 @@ use std::sync::Arc; use ctx::{Renderer, Vertex}; use image::ImageDecoder; use image::ImageFormat; -use tobj::Mesh; use tobj::{LoadOptions, Model}; use tracing::{debug, error, info, trace, warn}; use wgpu::rwh::HasWindowHandle; @@ -17,7 +16,6 @@ use winit::dpi::LogicalSize; use winit::dpi::Size; use winit::event::{KeyEvent, WindowEvent}; use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop}; -use winit::monitor::MonitorHandle; use winit::platform::windows::WindowAttributesExtWindows; use winit::window::Fullscreen; use winit::window::Icon; @@ -94,15 +92,18 @@ f 6/11/6 5/10/6 1/1/6 2/13/6 "; impl App<'_> { + const ICON: &'static [u8] = + include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/../assets/Badge.png")); + fn create_main_window(&mut self, event_loop: &ActiveEventLoop) { let icon = self.load_icon_from_bytes(Self::ICON).unwrap(); let win_attr = Window::default_attributes() - .with_title("Zenyx") - .with_min_inner_size(Size::Logical(LogicalSize::new(100.0, 100.0))) - .with_window_icon(icon.clone()) - .with_taskbar_icon(icon); - + .with_title("Zenyx") + .with_min_inner_size(Size::Logical(LogicalSize::new(100.0, 100.0))) + .with_window_icon(icon.clone()) + .with_taskbar_icon(icon); + match event_loop.create_window(win_attr) { Ok(window) => { let window = Arc::new(window); @@ -229,14 +230,17 @@ impl App<'_> { warn!("No window found for fullscreen toggle: {:?}", window_id); } } + fn load_icon_from_bytes(&self, bytes: &[u8]) -> Result, String> { - const IMAGE_DIR: &str = env!("CARGO_MANIFEST_DIR"); let cursor = Cursor::new(bytes); let format = image::guess_format(bytes).map_err(|_| "Failed to guess image format")?; let decoder = match format { - ImageFormat::Png => image::codecs::png::PngDecoder::new(cursor).map_err(|e| format!("Failed to decode PNG: {}", e))?, + ImageFormat::Png => image::codecs::png::PngDecoder::new(cursor) + .map_err(|e| format!("Failed to decode PNG: {}", e))?, _ => { - let img = image::load_from_memory(bytes).map_err(|e| format!("Failed to load image: {}", e))?.into_rgba8(); + let img = image::load_from_memory(bytes) + .map_err(|e| format!("Failed to load image: {}", e))? + .into_rgba8(); let (width, height) = img.dimensions(); return Icon::from_rgba(img.into_raw(), width, height) .map(Some) @@ -246,14 +250,15 @@ impl App<'_> { let (width, height) = decoder.dimensions(); let mut image_data = vec![0; decoder.total_bytes() as usize]; - decoder.read_image(&mut image_data).map_err(|e| format!("Failed to read image data: {}", e))?; + decoder + .read_image(&mut image_data) + .map_err(|e| format!("Failed to read image data: {}", e))?; Icon::from_rgba(image_data, width, height) .map(Some) .map_err(|e| format!("Failed to create icon from bytes: {}", e)) } - const ICON: &'static [u8] = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/../assets/Badge.png")); fn spawn_child_window(&mut self, event_loop: &ActiveEventLoop) { if let Some(main_ctx) = self.windows.values().find(|ctx| ctx.is_main_window()) { let title = format!("Zenyx - New Window {}", self.windows.len()); @@ -265,7 +270,7 @@ impl App<'_> { .with_min_inner_size(Size::Logical(LogicalSize::new(100.0, 100.0))) .with_window_icon(icon.clone()) .with_taskbar_icon(icon); - + match main_ctx.window_handle() { Ok(handle) => { if !cfg!(target_os = "windows") { @@ -345,6 +350,11 @@ impl App<'_> { fn handle_resize(&mut self, window_id: WindowId, new_size: winit::dpi::PhysicalSize) { if let Some(window_context) = self.windows.get_mut(&window_id) { + // if we dont ignore size 0 this WILL cause a crash. DO NOT REMOVE + if new_size.height == 0 || new_size.width == 0 { + error!("Attempted to resize a window to 0x0!"); + return; + } window_context.ctx.resize(new_size.into()); window_context.window.request_redraw(); debug!( @@ -435,7 +445,7 @@ impl ApplicationHandler for App<'_> { } pub fn init_renderer(event_loop: EventLoop<()>) { - event_loop.set_control_flow(ControlFlow::Wait); + event_loop.set_control_flow(ControlFlow::Poll); let mut app = App::default(); if let Err(e) = event_loop.run_app(&mut app) { error!("Failed to run application: {}", e); diff --git a/engine/src/metadata.rs b/engine/src/metadata.rs index 1530d1d..1114746 100644 --- a/engine/src/metadata.rs +++ b/engine/src/metadata.rs @@ -556,7 +556,7 @@ impl SystemMetadata { }; format!( - "System Metadata:\n\n{}\n\n{}\n\n{}\n\n{}\n\n{}", + "System Information:\n\n{}\n\n{}\n\n{}\n\n{}\n\n{}", self.cpu.verbose_info(), main_gpu_info, other_gpu_list,