Re-work event loop run() API so it can return a Result
This re-works the portable `run()` API that consumes the `EventLoop` and runs the loop on the calling thread until the app exits. This can be supported across _all_ platforms and compared to the previous `run() -> !` API is now able to return a `Result` status on all platforms except iOS and Web. Fixes: #2709 By moving away from `run() -> !` we stop calling `std::process::exit()` internally as a means to kill the process without returning which means it's possible to return an exit status and applications can return from their `main()` function normally. This also fixes Android support where an Activity runs in a thread but we can't assume to have full ownership of the process (other services could be running in separate threads). Additionally all examples have generally been updated so that `main()` returns a `Result` from `run()` Fixes: #2709
This commit is contained in:
parent
a6f414d732
commit
0d366ffbda
39 changed files with 99 additions and 123 deletions
|
|
@ -526,17 +526,12 @@ impl<T: 'static> EventLoop<T> {
|
|||
self.pending_redraw = pending_redraw;
|
||||
}
|
||||
|
||||
pub fn run<F>(mut self, event_handler: F) -> !
|
||||
pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError>
|
||||
where
|
||||
F: 'static
|
||||
+ FnMut(event::Event<'_, T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
||||
{
|
||||
let exit_code = match self.run_ondemand(event_handler) {
|
||||
Err(RunLoopError::ExitFailure(code)) => code,
|
||||
Err(_err) => 1,
|
||||
Ok(_) => 0,
|
||||
};
|
||||
::std::process::exit(exit_code);
|
||||
self.run_ondemand(event_handler)
|
||||
}
|
||||
|
||||
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
||||
|
|
|
|||
|
|
@ -830,11 +830,11 @@ impl<T: 'static> EventLoop<T> {
|
|||
x11_or_wayland!(match self; EventLoop(evlp) => evlp.create_proxy(); as EventLoopProxy)
|
||||
}
|
||||
|
||||
pub fn run<F>(self, callback: F) -> !
|
||||
pub fn run<F>(mut self, callback: F) -> Result<(), RunLoopError>
|
||||
where
|
||||
F: 'static + FnMut(crate::event::Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
||||
F: FnMut(crate::event::Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
||||
{
|
||||
x11_or_wayland!(match self; EventLoop(evlp) => evlp.run(callback))
|
||||
self.run_ondemand(callback)
|
||||
}
|
||||
|
||||
pub fn run_ondemand<F>(&mut self, callback: F) -> Result<(), RunLoopError>
|
||||
|
|
|
|||
|
|
@ -145,18 +145,6 @@ impl<T: 'static> EventLoop<T> {
|
|||
Ok(event_loop)
|
||||
}
|
||||
|
||||
pub fn run<F>(mut self, callback: F) -> !
|
||||
where
|
||||
F: FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow) + 'static,
|
||||
{
|
||||
let exit_code = match self.run_ondemand(callback) {
|
||||
Err(RunLoopError::ExitFailure(code)) => code,
|
||||
Err(_err) => 1,
|
||||
Ok(_) => 0,
|
||||
};
|
||||
::std::process::exit(exit_code)
|
||||
}
|
||||
|
||||
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
||||
where
|
||||
F: FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||
|
|
|
|||
|
|
@ -432,18 +432,6 @@ impl<T: 'static> EventLoop<T> {
|
|||
&self.target
|
||||
}
|
||||
|
||||
pub fn run<F>(mut self, callback: F) -> !
|
||||
where
|
||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow) + 'static,
|
||||
{
|
||||
let exit_code = match self.run_ondemand(callback) {
|
||||
Err(RunLoopError::ExitFailure(code)) => code,
|
||||
Err(_err) => 1,
|
||||
Ok(_) => 0,
|
||||
};
|
||||
::std::process::exit(exit_code)
|
||||
}
|
||||
|
||||
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
||||
where
|
||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use std::{
|
|||
mem,
|
||||
os::raw::c_void,
|
||||
panic::{catch_unwind, resume_unwind, AssertUnwindSafe, RefUnwindSafe, UnwindSafe},
|
||||
process, ptr,
|
||||
ptr,
|
||||
rc::{Rc, Weak},
|
||||
sync::mpsc,
|
||||
};
|
||||
|
|
@ -192,16 +192,11 @@ impl<T> EventLoop<T> {
|
|||
&self.window_target
|
||||
}
|
||||
|
||||
pub fn run<F>(mut self, callback: F) -> !
|
||||
pub fn run<F>(mut self, callback: F) -> Result<(), RunLoopError>
|
||||
where
|
||||
F: 'static + FnMut(Event<'_, T>, &RootWindowTarget<T>, &mut ControlFlow),
|
||||
{
|
||||
let exit_code = match self.run_ondemand(callback) {
|
||||
Err(RunLoopError::ExitFailure(code)) => code,
|
||||
Err(_err) => 1,
|
||||
Ok(_) => 0,
|
||||
};
|
||||
process::exit(exit_code);
|
||||
self.run_ondemand(callback)
|
||||
}
|
||||
|
||||
// NB: we don't base this on `pump_events` because for `MacOs` we can't support
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use orbclient::{
|
|||
use raw_window_handle::{OrbitalDisplayHandle, RawDisplayHandle};
|
||||
|
||||
use crate::{
|
||||
error::RunLoopError,
|
||||
event::{self, Ime, Modifiers, StartCause},
|
||||
event_loop::{self, ControlFlow},
|
||||
keyboard::{
|
||||
|
|
@ -442,7 +443,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn run<F>(mut self, event_handler: F) -> !
|
||||
pub fn run<F>(mut self, mut event_handler_inner: F) -> Result<(), RunLoopError>
|
||||
where
|
||||
F: 'static
|
||||
+ FnMut(event::Event<'_, T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
||||
|
|
@ -688,7 +689,11 @@ impl<T: 'static> EventLoop<T> {
|
|||
&mut control_flow,
|
||||
);
|
||||
|
||||
::std::process::exit(code);
|
||||
if code == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(RunLoopError::ExitFailure(code))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &event_loop::EventLoopWindowTarget<T> {
|
||||
|
|
|
|||
|
|
@ -243,16 +243,11 @@ impl<T: 'static> EventLoop<T> {
|
|||
&self.window_target
|
||||
}
|
||||
|
||||
pub fn run<F>(mut self, event_handler: F) -> !
|
||||
pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError>
|
||||
where
|
||||
F: 'static + FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
||||
{
|
||||
let exit_code = match self.run_ondemand(event_handler) {
|
||||
Err(RunLoopError::ExitFailure(code)) => code,
|
||||
Err(_err) => 1,
|
||||
Ok(_) => 0,
|
||||
};
|
||||
::std::process::exit(exit_code);
|
||||
self.run_ondemand(event_handler)
|
||||
}
|
||||
|
||||
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue