1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-31 22:00:03 -04:00

Return errors from run_and_exit

This commit is contained in:
Emil Ernerfeldt
2023-11-27 17:45:59 +01:00
parent c6f0704f00
commit 4491fae002

View File

@@ -224,154 +224,154 @@ fn run_and_return(
returned_result returned_result
} }
fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp + 'static) -> ! { fn run_and_exit(
event_loop: EventLoop<UserEvent>,
mut winit_app: impl WinitApp + 'static,
) -> Result<()> {
use winit::event_loop::ControlFlow; use winit::event_loop::ControlFlow;
log::debug!("Entering the winit event loop (run)…"); log::debug!("Entering the winit event loop (run)…");
// When to repaint what window // When to repaint what window
let mut windows_next_repaint_times = HashMap::default(); let mut windows_next_repaint_times = HashMap::default();
let result = event_loop.run(move |event, event_loop_window_target| { event_loop
crate::profile_scope!("winit_event", short_event_description(&event)); .run(move |event, event_loop_window_target| {
crate::profile_scope!("winit_event", short_event_description(&event));
let event_result = match &event { let event_result = match &event {
winit::event::Event::LoopExiting => { winit::event::Event::LoopExiting => {
log::debug!("Received Event::LoopExiting"); log::debug!("Received Event::LoopExiting");
EventResult::Exit EventResult::Exit
} }
winit::event::Event::WindowEvent { winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::RedrawRequested, event: winit::event::WindowEvent::RedrawRequested,
window_id, window_id,
} => { } => {
windows_next_repaint_times.remove(window_id); windows_next_repaint_times.remove(window_id);
winit_app.run_ui_and_paint(*window_id) winit_app.run_ui_and_paint(*window_id)
} }
winit::event::Event::UserEvent(UserEvent::RequestRepaint { winit::event::Event::UserEvent(UserEvent::RequestRepaint {
when, when,
frame_nr, frame_nr,
viewport_id, viewport_id,
}) => { }) => {
let current_frame_nr = winit_app.frame_nr(*viewport_id); let current_frame_nr = winit_app.frame_nr(*viewport_id);
if current_frame_nr == *frame_nr || current_frame_nr == *frame_nr + 1 { if current_frame_nr == *frame_nr || current_frame_nr == *frame_nr + 1 {
if let Some(window_id) = winit_app.window_id_from_viewport_id(*viewport_id) { if let Some(window_id) = winit_app.window_id_from_viewport_id(*viewport_id)
EventResult::RepaintAt(window_id, *when) {
EventResult::RepaintAt(window_id, *when)
} else {
EventResult::Wait
}
} else { } else {
EventResult::Wait log::trace!("Got outdated UserEvent::RequestRepaint");
EventResult::Wait // old request - we've already repainted
} }
} else {
log::trace!("Got outdated UserEvent::RequestRepaint");
EventResult::Wait // old request - we've already repainted
} }
}
winit::event::Event::NewEvents(winit::event::StartCause::ResumeTimeReached { winit::event::Event::NewEvents(winit::event::StartCause::ResumeTimeReached {
.. ..
}) => { }) => {
log::trace!("Woke up to check next_repaint_time"); log::trace!("Woke up to check next_repaint_time");
EventResult::Wait EventResult::Wait
}
event => match winit_app.on_event(event_loop_window_target, event) {
Ok(event_result) => event_result,
Err(err) => {
panic!("eframe encountered a fatal error: {err} during event {event:?}");
} }
},
};
match event_result { event => match winit_app.on_event(event_loop_window_target, event) {
EventResult::Wait => { Ok(event_result) => event_result,
event_loop_window_target.set_control_flow(ControlFlow::Wait); Err(err) => {
} panic!("eframe encountered a fatal error: {err} during event {event:?}");
EventResult::RepaintNow(window_id) => { }
log::trace!("Repaint caused by {}", short_event_description(&event)); },
if cfg!(target_os = "windows") { };
// Fix flickering on Windows, see https://github.com/emilk/egui/pull/2280
windows_next_repaint_times.remove(&window_id);
winit_app.run_ui_and_paint(window_id); match event_result {
} else { EventResult::Wait => {
// Fix for https://github.com/emilk/egui/issues/2425 event_loop_window_target.set_control_flow(ControlFlow::Wait);
}
EventResult::RepaintNow(window_id) => {
log::trace!("Repaint caused by {}", short_event_description(&event));
if cfg!(target_os = "windows") {
// Fix flickering on Windows, see https://github.com/emilk/egui/pull/2280
windows_next_repaint_times.remove(&window_id);
winit_app.run_ui_and_paint(window_id);
} else {
// Fix for https://github.com/emilk/egui/issues/2425
windows_next_repaint_times.insert(window_id, Instant::now());
}
}
EventResult::RepaintNext(window_id) => {
log::trace!("Repaint caused by {}", short_event_description(&event));
windows_next_repaint_times.insert(window_id, Instant::now()); windows_next_repaint_times.insert(window_id, Instant::now());
} }
} EventResult::RepaintAt(window_id, repaint_time) => {
EventResult::RepaintNext(window_id) => { windows_next_repaint_times.insert(
log::trace!("Repaint caused by {}", short_event_description(&event)); window_id,
windows_next_repaint_times.insert(window_id, Instant::now()); windows_next_repaint_times
} .get(&window_id)
EventResult::RepaintAt(window_id, repaint_time) => { .map_or(repaint_time, |last| (*last).min(repaint_time)),
windows_next_repaint_times.insert( );
window_id,
windows_next_repaint_times
.get(&window_id)
.map_or(repaint_time, |last| (*last).min(repaint_time)),
);
}
EventResult::Exit => {
log::debug!("Quitting - saving app state…");
winit_app.save_and_destroy();
#[allow(clippy::exit)]
std::process::exit(0);
}
}
let mut next_repaint_time = windows_next_repaint_times.values().min().copied();
// This is for not duplicating redraw requests
use winit::event::Event;
if matches!(
event,
Event::WindowEvent {
event: winit::event::WindowEvent::RedrawRequested,
..
} | Event::Resumed
) {
windows_next_repaint_times.retain(|window_id, repaint_time| {
if Instant::now() < *repaint_time {
return true;
} }
EventResult::Exit => {
next_repaint_time = None; log::debug!("Quitting - saving app state…");
event_loop_window_target.set_control_flow(ControlFlow::Poll); winit_app.save_and_destroy();
#[allow(clippy::exit)]
if let Some(window) = winit_app.window(*window_id) { std::process::exit(0);
log::trace!("request_redraw for {window_id:?}");
window.request_redraw();
true
} else {
false
} }
});
}
if let Some(next_repaint_time) = next_repaint_time {
let time_until_next = next_repaint_time.saturating_duration_since(Instant::now());
if time_until_next < std::time::Duration::from_secs(10_000) {
log::trace!("WaitUntil {time_until_next:?}");
} }
// WaitUntil seems to not work on iOS let mut next_repaint_time = windows_next_repaint_times.values().min().copied();
#[cfg(target_os = "ios")]
winit_app // This is for not duplicating redraw requests
.get_window_winit_id(ViewportId::ROOT) use winit::event::Event;
.map(|window_id| { if matches!(
winit_app event,
.window(window_id) Event::WindowEvent {
.map(|window| window.request_redraw()) event: winit::event::WindowEvent::RedrawRequested,
..
} | Event::Resumed
) {
windows_next_repaint_times.retain(|window_id, repaint_time| {
if Instant::now() < *repaint_time {
return true;
}
next_repaint_time = None;
event_loop_window_target.set_control_flow(ControlFlow::Poll);
if let Some(window) = winit_app.window(*window_id) {
log::trace!("request_redraw for {window_id:?}");
window.request_redraw();
true
} else {
false
}
}); });
}
event_loop_window_target.set_control_flow(ControlFlow::WaitUntil(next_repaint_time)); if let Some(next_repaint_time) = next_repaint_time {
}; let time_until_next = next_repaint_time.saturating_duration_since(Instant::now());
}); if time_until_next < std::time::Duration::from_secs(10_000) {
log::trace!("WaitUntil {time_until_next:?}");
}
std::process::exit(if let Err(e) = result { // WaitUntil seems to not work on iOS
log::warn!("Error from event loop: {e}"); #[cfg(target_os = "ios")]
1 winit_app
} else { .get_window_winit_id(ViewportId::ROOT)
0 .map(|window_id| {
}); winit_app
.window(window_id)
.map(|window| window.request_redraw())
});
event_loop_window_target
.set_control_flow(ControlFlow::WaitUntil(next_repaint_time));
};
})
.map_err(|e| e.into())
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -394,7 +394,7 @@ pub fn run_glow(
let event_loop = create_event_loop(&mut native_options); let event_loop = create_event_loop(&mut native_options);
let glow_eframe = GlowWinitApp::new(&event_loop, app_name, native_options, app_creator); let glow_eframe = GlowWinitApp::new(&event_loop, app_name, native_options, app_creator);
run_and_exit(event_loop, glow_eframe); run_and_exit(event_loop, glow_eframe)
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -417,5 +417,5 @@ pub fn run_wgpu(
let event_loop = create_event_loop(&mut native_options); let event_loop = create_event_loop(&mut native_options);
let wgpu_eframe = WgpuWinitApp::new(&event_loop, app_name, native_options, app_creator); let wgpu_eframe = WgpuWinitApp::new(&event_loop, app_name, native_options, app_creator);
run_and_exit(event_loop, wgpu_eframe); run_and_exit(event_loop, wgpu_eframe)
} }