Change `run_app(app: &mut A)` to `run_app(app: A)` (#3721)

This allows the user more control over how they pass their application state
to Winit, and will hopefully allow `Drop` implementations on the application
handler to work in the future on all platforms.
This commit is contained in:
Mads Marquart 2024-07-11 15:38:09 +02:00 committed by GitHub
parent d5fd8682eb
commit bf97def398
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 53 additions and 59 deletions

View File

@ -86,8 +86,7 @@ fn main() -> Result<(), impl std::error::Error> {
}
let event_loop = EventLoop::new().unwrap();
let mut app = Application::default();
event_loop.run_app(&mut app)
event_loop.run_app(Application::default())
}
#[cfg(all(feature = "rwh_06", not(any(x11_platform, macos_platform, windows_platform))))]

View File

@ -43,8 +43,7 @@ fn main() -> Result<(), impl std::error::Error> {
let event_loop = EventLoop::new().unwrap();
let mut app = ControlFlowDemo::default();
event_loop.run_app(&mut app)
event_loop.run_app(ControlFlowDemo::default())
}
#[derive(Default)]

View File

@ -57,9 +57,8 @@ fn main() -> Result<(), Box<dyn Error>> {
}
});
let mut state = Application::new(&event_loop);
event_loop.run_app(&mut state).map_err(Into::into)
let app = Application::new(&event_loop);
Ok(event_loop.run_app(app)?)
}
/// Application state and event handling.

View File

@ -58,8 +58,7 @@ fn main() -> Result<(), Box<dyn Error>> {
tracing_subscriber::fmt::init();
let event_loop = EventLoop::new()?;
let mut app = XEmbedDemo { parent_window_id, window: None };
event_loop.run_app(&mut app).map_err(Into::into)
Ok(event_loop.run_app(XEmbedDemo { parent_window_id, window: None })?)
}
#[cfg(not(x11_platform))]

View File

@ -65,6 +65,9 @@ changelog entry.
`ApplicationHandler::resumed/suspended()` are now only emitted by iOS and Web
and now signify actually resuming/suspending the application.
- Rename `platform::web::*ExtWebSys` to `*ExtWeb`.
- Change signature of `EventLoop::run_app`, `EventLoopExtPumpEvents::pump_app_events` and
`EventLoopExtRunOnDemand::run_app_on_demand` to accept a `impl ApplicationHandler` directly,
instead of requiring a `&mut` reference to it.
### Removed

View File

@ -241,7 +241,7 @@ impl EventLoop {
/// [`run_app()`]: Self::run_app()
#[inline]
#[cfg(not(all(web_platform, target_feature = "exception-handling")))]
pub fn run_app<A: ApplicationHandler>(self, app: &mut A) -> Result<(), EventLoopError> {
pub fn run_app<A: ApplicationHandler>(self, app: A) -> Result<(), EventLoopError> {
self.event_loop.run_app(app)
}

View File

@ -102,7 +102,7 @@ pub trait EventLoopExtPumpEvents {
fn pump_app_events<A: ApplicationHandler>(
&mut self,
timeout: Option<Duration>,
app: &mut A,
app: A,
) -> PumpStatus;
}
@ -110,7 +110,7 @@ impl EventLoopExtPumpEvents for EventLoop {
fn pump_app_events<A: ApplicationHandler>(
&mut self,
timeout: Option<Duration>,
app: &mut A,
app: A,
) -> PumpStatus {
self.event_loop.pump_app_events(timeout, app)
}

View File

@ -58,17 +58,11 @@ pub trait EventLoopExtRunOnDemand {
///
/// [`exit()`]: ActiveEventLoop::exit()
/// [`set_control_flow()`]: ActiveEventLoop::set_control_flow()
fn run_app_on_demand<A: ApplicationHandler>(
&mut self,
app: &mut A,
) -> Result<(), EventLoopError>;
fn run_app_on_demand<A: ApplicationHandler>(&mut self, app: A) -> Result<(), EventLoopError>;
}
impl EventLoopExtRunOnDemand for EventLoop {
fn run_app_on_demand<A: ApplicationHandler>(
&mut self,
app: &mut A,
) -> Result<(), EventLoopError> {
fn run_app_on_demand<A: ApplicationHandler>(&mut self, app: A) -> Result<(), EventLoopError> {
self.event_loop.window_target().clear_exit();
self.event_loop.run_app_on_demand(app)
}

View File

@ -417,16 +417,16 @@ impl EventLoop {
input_status
}
pub fn run_app<A: ApplicationHandler>(mut self, app: &mut A) -> Result<(), EventLoopError> {
pub fn run_app<A: ApplicationHandler>(mut self, app: A) -> Result<(), EventLoopError> {
self.run_app_on_demand(app)
}
pub fn run_app_on_demand<A: ApplicationHandler>(
&mut self,
app: &mut A,
mut app: A,
) -> Result<(), EventLoopError> {
loop {
match self.pump_app_events(None, app) {
match self.pump_app_events(None, &mut app) {
PumpStatus::Exit(0) => {
break Ok(());
},
@ -443,7 +443,7 @@ impl EventLoop {
pub fn pump_app_events<A: ApplicationHandler>(
&mut self,
timeout: Option<Duration>,
app: &mut A,
mut app: A,
) -> PumpStatus {
if !self.loop_running {
self.loop_running = true;
@ -455,13 +455,13 @@ impl EventLoop {
self.cause = StartCause::Init;
// run the initial loop iteration
self.single_iteration(None, app);
self.single_iteration(None, &mut app);
}
// Consider the possibility that the `StartCause::Init` iteration could
// request to Exit
if !self.exiting() {
self.poll_events_with_timeout(timeout, app);
self.poll_events_with_timeout(timeout, &mut app);
}
if self.exiting() {
self.loop_running = false;

View File

@ -243,7 +243,7 @@ impl EventLoop {
&self.window_target
}
pub fn run_app<A: ApplicationHandler>(mut self, app: &mut A) -> Result<(), EventLoopError> {
pub fn run_app<A: ApplicationHandler>(mut self, app: A) -> Result<(), EventLoopError> {
self.run_app_on_demand(app)
}
@ -253,9 +253,9 @@ impl EventLoop {
// redundant wake ups.
pub fn run_app_on_demand<A: ApplicationHandler>(
&mut self,
app: &mut A,
mut app: A,
) -> Result<(), EventLoopError> {
self.delegate.set_event_handler(app, || {
self.delegate.set_event_handler(&mut app, || {
autoreleasepool(|_| {
// clear / normalize pump_events state
self.delegate.set_wait_timeout(None);
@ -291,9 +291,9 @@ impl EventLoop {
pub fn pump_app_events<A: ApplicationHandler>(
&mut self,
timeout: Option<Duration>,
app: &mut A,
mut app: A,
) -> PumpStatus {
self.delegate.set_event_handler(app, || {
self.delegate.set_event_handler(&mut app, || {
autoreleasepool(|_| {
// As a special case, if the application hasn't been launched yet then we at least
// run the loop until it has fully launched.

View File

@ -109,10 +109,10 @@ impl OwnedDisplayHandle {
}
}
fn map_user_event<A: ApplicationHandler>(
app: &mut A,
fn map_user_event<'a, A: ApplicationHandler + 'a>(
mut app: A,
proxy_wake_up: Arc<AtomicBool>,
) -> impl FnMut(Event, &RootActiveEventLoop) + '_ {
) -> impl FnMut(Event, &RootActiveEventLoop) + 'a {
move |event, window_target| match event {
Event::NewEvents(cause) => app.new_events(window_target, cause),
Event::WindowEvent { window_id, event } => {
@ -168,7 +168,7 @@ impl EventLoop {
})
}
pub fn run_app<A: ApplicationHandler>(self, app: &mut A) -> ! {
pub fn run_app<A: ApplicationHandler>(self, app: A) -> ! {
let application: Option<Retained<UIApplication>> =
unsafe { msg_send_id![UIApplication::class(), sharedApplication] };
assert!(

View File

@ -788,13 +788,13 @@ impl EventLoop {
}
}
pub fn run_app<A: ApplicationHandler>(self, app: &mut A) -> Result<(), EventLoopError> {
pub fn run_app<A: ApplicationHandler>(self, app: A) -> Result<(), EventLoopError> {
x11_or_wayland!(match self; EventLoop(evlp) => evlp.run_app(app))
}
pub fn run_app_on_demand<A: ApplicationHandler>(
&mut self,
app: &mut A,
app: A,
) -> Result<(), EventLoopError> {
x11_or_wayland!(match self; EventLoop(evlp) => evlp.run_app_on_demand(app))
}
@ -802,7 +802,7 @@ impl EventLoop {
pub fn pump_app_events<A: ApplicationHandler>(
&mut self,
timeout: Option<Duration>,
app: &mut A,
app: A,
) -> PumpStatus {
x11_or_wayland!(match self; EventLoop(evlp) => evlp.pump_app_events(timeout, app))
}

View File

@ -160,16 +160,16 @@ impl EventLoop {
Ok(event_loop)
}
pub fn run_app<A: ApplicationHandler>(mut self, app: &mut A) -> Result<(), EventLoopError> {
pub fn run_app<A: ApplicationHandler>(mut self, app: A) -> Result<(), EventLoopError> {
self.run_app_on_demand(app)
}
pub fn run_app_on_demand<A: ApplicationHandler>(
&mut self,
app: &mut A,
mut app: A,
) -> Result<(), EventLoopError> {
let exit = loop {
match self.pump_app_events(None, app) {
match self.pump_app_events(None, &mut app) {
PumpStatus::Exit(0) => {
break Ok(());
},
@ -194,19 +194,19 @@ impl EventLoop {
pub fn pump_app_events<A: ApplicationHandler>(
&mut self,
timeout: Option<Duration>,
app: &mut A,
mut app: A,
) -> PumpStatus {
if !self.loop_running {
self.loop_running = true;
// Run the initial loop iteration.
self.single_iteration(app, StartCause::Init);
self.single_iteration(&mut app, StartCause::Init);
}
// Consider the possibility that the `StartCause::Init` iteration could
// request to Exit.
if !self.exiting() {
self.poll_events_with_timeout(timeout, app);
self.poll_events_with_timeout(timeout, &mut app);
}
if let Some(code) = self.exit_code() {
self.loop_running = false;
@ -219,7 +219,7 @@ impl EventLoop {
}
}
pub fn poll_events_with_timeout<A: ApplicationHandler>(
fn poll_events_with_timeout<A: ApplicationHandler>(
&mut self,
mut timeout: Option<Duration>,
app: &mut A,

View File

@ -367,16 +367,16 @@ impl EventLoop {
&self.event_processor.target
}
pub fn run_app<A: ApplicationHandler>(mut self, app: &mut A) -> Result<(), EventLoopError> {
pub fn run_app<A: ApplicationHandler>(mut self, app: A) -> Result<(), EventLoopError> {
self.run_app_on_demand(app)
}
pub fn run_app_on_demand<A: ApplicationHandler>(
&mut self,
app: &mut A,
mut app: A,
) -> Result<(), EventLoopError> {
let exit = loop {
match self.pump_app_events(None, app) {
match self.pump_app_events(None, &mut app) {
PumpStatus::Exit(0) => {
break Ok(());
},
@ -404,19 +404,19 @@ impl EventLoop {
pub fn pump_app_events<A: ApplicationHandler>(
&mut self,
timeout: Option<Duration>,
app: &mut A,
mut app: A,
) -> PumpStatus {
if !self.loop_running {
self.loop_running = true;
// run the initial loop iteration
self.single_iteration(app, StartCause::Init);
self.single_iteration(&mut app, StartCause::Init);
}
// Consider the possibility that the `StartCause::Init` iteration could
// request to Exit.
if !self.exiting() {
self.poll_events_with_timeout(timeout, app);
self.poll_events_with_timeout(timeout, &mut app);
}
if let Some(code) = self.exit_code() {
self.loop_running = false;
@ -435,7 +435,7 @@ impl EventLoop {
|| self.redraw_receiver.has_incoming()
}
pub fn poll_events_with_timeout<A: ApplicationHandler>(
fn poll_events_with_timeout<A: ApplicationHandler>(
&mut self,
mut timeout: Option<Duration>,
app: &mut A,

View File

@ -500,7 +500,7 @@ impl EventLoop {
}
}
pub fn run_app<A: ApplicationHandler>(mut self, app: &mut A) -> Result<(), EventLoopError> {
pub fn run_app<A: ApplicationHandler>(mut self, mut app: A) -> Result<(), EventLoopError> {
let mut start_cause = StartCause::Init;
loop {
app.new_events(&self.window_target, start_cause);
@ -567,7 +567,7 @@ impl EventLoop {
orbital_event.to_option(),
event_state,
&self.window_target,
app,
&mut app,
);
}

View File

@ -28,11 +28,12 @@ impl EventLoop {
Ok(EventLoop { elw })
}
pub fn run_app<A: ApplicationHandler>(self, app: &mut A) -> ! {
pub fn run_app<A: ApplicationHandler>(self, mut app: A) -> ! {
let target = RootActiveEventLoop { p: self.elw.p.clone(), _marker: PhantomData };
// SAFETY: Don't use `move` to make sure we leak the `event_handler` and `target`.
let handler: Box<dyn FnMut(Event)> = Box::new(|event| handle_event(app, &target, event));
let handler: Box<dyn FnMut(Event)> =
Box::new(|event| handle_event(&mut app, &target, event));
// SAFETY: The `transmute` is necessary because `run()` requires `'static`. This is safe
// because this function will never return and all resources not cleaned up by the point we

View File

@ -187,13 +187,13 @@ impl EventLoop {
&self.window_target
}
pub fn run_app<A: ApplicationHandler>(mut self, app: &mut A) -> Result<(), EventLoopError> {
pub fn run_app<A: ApplicationHandler>(mut self, app: A) -> Result<(), EventLoopError> {
self.run_app_on_demand(app)
}
pub fn run_app_on_demand<A: ApplicationHandler>(
&mut self,
app: &mut A,
mut app: A,
) -> Result<(), EventLoopError> {
{
let runner = &self.window_target.p.runner_shared;
@ -254,7 +254,7 @@ impl EventLoop {
pub fn pump_app_events<A: ApplicationHandler>(
&mut self,
timeout: Option<Duration>,
app: &mut A,
mut app: A,
) -> PumpStatus {
{
let runner = &self.window_target.p.runner_shared;