diff options
Diffstat (limited to 'engine/src')
| -rw-r--r-- | engine/src/windowing.rs | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/engine/src/windowing.rs b/engine/src/windowing.rs index a0201db..bf29453 100644 --- a/engine/src/windowing.rs +++ b/engine/src/windowing.rs @@ -1,6 +1,7 @@ use std::borrow::Cow; use std::env::consts::EXE_SUFFIX; use std::hint::cold_path; +use std::panic::catch_unwind; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Weak}; use std::thread::Builder as ThreadBuilder; @@ -184,6 +185,7 @@ fn update_stuff( ref message_from_app_queue, ref mut display_handle, ref mut windows, + ref thread_panicked, .. } = *context; @@ -288,6 +290,11 @@ fn update_stuff( } } } + + if thread_panicked.load(Ordering::Relaxed) { + cold_path(); + actions.stop(); + } } fn handle_window_changed( @@ -344,6 +351,7 @@ pub struct Context message_from_app_queue: Arc<ArrayQueue<MessageFromApp>>, message_to_app_queue: Arc<ArrayQueue<MessageToApp>>, shared_state: Arc<SharedState>, + thread_panicked: Arc<AtomicBool>, display_handle: Option<OwnedDisplayHandle>, windows: MapVec<WindowId, (Arc<winit::window::Window>, Uid)>, } @@ -420,28 +428,22 @@ impl Context let shared_state = Arc::new(SharedState::default()); let shared_state_b = shared_state.clone(); + let thread_panicked = Arc::new(AtomicBool::new(false)); + let thread_panicked_b = thread_panicked.clone(); + ThreadBuilder::new() .name("windowing app".to_string()) .spawn(move || { - let mut app = App { - message_from_app_queue: message_from_app_queue_b, - message_to_app_queue: message_to_app_queue_b, - shared_state: shared_state_b, - windows: MapVec::default(), - }; - - let event_loop = match create_event_loop() { - Ok(event_loop) => event_loop, - Err(err) => { - tracing::error!("Failed to create event loop: {err}"); - return; - } - }; - - event_loop.set_control_flow(EventLoopControlFlow::Poll); - - if let Err(err) = event_loop.run_app(&mut app) { - tracing::error!("Event loop error occurred: {err}"); + if catch_unwind(move || { + start_app( + message_from_app_queue_b, + message_to_app_queue_b, + shared_state_b, + ); + }) + .is_err() + { + thread_panicked_b.store(true, Ordering::Relaxed); } }) .expect("Failed to create windowing thread"); @@ -450,6 +452,7 @@ impl Context message_from_app_queue, message_to_app_queue, shared_state, + thread_panicked, display_handle: None, windows: MapVec::default(), } @@ -464,6 +467,34 @@ impl Drop for Context } } +fn start_app( + message_from_app_queue_b: Arc<ArrayQueue<MessageFromApp>>, + message_to_app_queue_b: Arc<ArrayQueue<MessageToApp>>, + shared_state_b: Arc<SharedState>, +) +{ + let mut app = App { + message_from_app_queue: message_from_app_queue_b, + message_to_app_queue: message_to_app_queue_b, + shared_state: shared_state_b, + windows: MapVec::default(), + }; + + let event_loop = match create_event_loop() { + Ok(event_loop) => event_loop, + Err(err) => { + tracing::error!("Failed to create event loop: {err}"); + return; + } + }; + + event_loop.set_control_flow(EventLoopControlFlow::Poll); + + if let Err(err) = event_loop.run_app(&mut app) { + tracing::error!("Event loop error occurred: {err}"); + } +} + fn create_event_loop() -> Result<EventLoop<()>, EventLoopError> { let mut event_loop_builder = EventLoop::builder(); |
