From bf97def398c902d0f6d1d1af5079a3eee587af09 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Thu, 11 Jul 2024 15:38:09 +0200 Subject: [PATCH] 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. --- examples/child_window.rs | 3 +-- examples/control_flow.rs | 3 +-- examples/window.rs | 5 ++--- examples/x11_embed.rs | 3 +-- src/changelog/unreleased.md | 3 +++ src/event_loop.rs | 2 +- src/platform/pump_events.rs | 4 ++-- src/platform/run_on_demand.rs | 10 ++-------- src/platform_impl/android/mod.rs | 12 ++++++------ src/platform_impl/apple/appkit/event_loop.rs | 10 +++++----- src/platform_impl/apple/uikit/event_loop.rs | 8 ++++---- src/platform_impl/linux/mod.rs | 6 +++--- src/platform_impl/linux/wayland/event_loop/mod.rs | 14 +++++++------- src/platform_impl/linux/x11/mod.rs | 14 +++++++------- src/platform_impl/orbital/event_loop.rs | 4 ++-- src/platform_impl/web/event_loop/mod.rs | 5 +++-- src/platform_impl/windows/event_loop.rs | 6 +++--- 17 files changed, 53 insertions(+), 59 deletions(-) diff --git a/examples/child_window.rs b/examples/child_window.rs index 9b0f305b..ee86287f 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -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))))] diff --git a/examples/control_flow.rs b/examples/control_flow.rs index 1dbbe061..1f57dcc2 100644 --- a/examples/control_flow.rs +++ b/examples/control_flow.rs @@ -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)] diff --git a/examples/window.rs b/examples/window.rs index 679100c8..daf1a610 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -57,9 +57,8 @@ fn main() -> Result<(), Box> { } }); - 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. diff --git a/examples/x11_embed.rs b/examples/x11_embed.rs index b012e5f4..7b728d4b 100644 --- a/examples/x11_embed.rs +++ b/examples/x11_embed.rs @@ -58,8 +58,7 @@ fn main() -> Result<(), Box> { 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))] diff --git a/src/changelog/unreleased.md b/src/changelog/unreleased.md index d74090d1..6111d237 100644 --- a/src/changelog/unreleased.md +++ b/src/changelog/unreleased.md @@ -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 diff --git a/src/event_loop.rs b/src/event_loop.rs index b8e0e90e..404acca5 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -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(self, app: &mut A) -> Result<(), EventLoopError> { + pub fn run_app(self, app: A) -> Result<(), EventLoopError> { self.event_loop.run_app(app) } diff --git a/src/platform/pump_events.rs b/src/platform/pump_events.rs index 7c711b56..802e86ee 100644 --- a/src/platform/pump_events.rs +++ b/src/platform/pump_events.rs @@ -102,7 +102,7 @@ pub trait EventLoopExtPumpEvents { fn pump_app_events( &mut self, timeout: Option, - app: &mut A, + app: A, ) -> PumpStatus; } @@ -110,7 +110,7 @@ impl EventLoopExtPumpEvents for EventLoop { fn pump_app_events( &mut self, timeout: Option, - app: &mut A, + app: A, ) -> PumpStatus { self.event_loop.pump_app_events(timeout, app) } diff --git a/src/platform/run_on_demand.rs b/src/platform/run_on_demand.rs index b7b847e6..6a3c5d49 100644 --- a/src/platform/run_on_demand.rs +++ b/src/platform/run_on_demand.rs @@ -58,17 +58,11 @@ pub trait EventLoopExtRunOnDemand { /// /// [`exit()`]: ActiveEventLoop::exit() /// [`set_control_flow()`]: ActiveEventLoop::set_control_flow() - fn run_app_on_demand( - &mut self, - app: &mut A, - ) -> Result<(), EventLoopError>; + fn run_app_on_demand(&mut self, app: A) -> Result<(), EventLoopError>; } impl EventLoopExtRunOnDemand for EventLoop { - fn run_app_on_demand( - &mut self, - app: &mut A, - ) -> Result<(), EventLoopError> { + fn run_app_on_demand(&mut self, app: A) -> Result<(), EventLoopError> { self.event_loop.window_target().clear_exit(); self.event_loop.run_app_on_demand(app) } diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index e471a72c..9bb78302 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -417,16 +417,16 @@ impl EventLoop { input_status } - pub fn run_app(mut self, app: &mut A) -> Result<(), EventLoopError> { + pub fn run_app(mut self, app: A) -> Result<(), EventLoopError> { self.run_app_on_demand(app) } pub fn run_app_on_demand( &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( &mut self, timeout: Option, - 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; diff --git a/src/platform_impl/apple/appkit/event_loop.rs b/src/platform_impl/apple/appkit/event_loop.rs index 23a039a3..8b0fdbc4 100644 --- a/src/platform_impl/apple/appkit/event_loop.rs +++ b/src/platform_impl/apple/appkit/event_loop.rs @@ -243,7 +243,7 @@ impl EventLoop { &self.window_target } - pub fn run_app(mut self, app: &mut A) -> Result<(), EventLoopError> { + pub fn run_app(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( &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( &mut self, timeout: Option, - 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. diff --git a/src/platform_impl/apple/uikit/event_loop.rs b/src/platform_impl/apple/uikit/event_loop.rs index 72e1b485..91f6a516 100644 --- a/src/platform_impl/apple/uikit/event_loop.rs +++ b/src/platform_impl/apple/uikit/event_loop.rs @@ -109,10 +109,10 @@ impl OwnedDisplayHandle { } } -fn map_user_event( - app: &mut A, +fn map_user_event<'a, A: ApplicationHandler + 'a>( + mut app: A, proxy_wake_up: Arc, -) -> 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(self, app: &mut A) -> ! { + pub fn run_app(self, app: A) -> ! { let application: Option> = unsafe { msg_send_id![UIApplication::class(), sharedApplication] }; assert!( diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index c7594521..9601a4c3 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -788,13 +788,13 @@ impl EventLoop { } } - pub fn run_app(self, app: &mut A) -> Result<(), EventLoopError> { + pub fn run_app(self, app: A) -> Result<(), EventLoopError> { x11_or_wayland!(match self; EventLoop(evlp) => evlp.run_app(app)) } pub fn run_app_on_demand( &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( &mut self, timeout: Option, - app: &mut A, + app: A, ) -> PumpStatus { x11_or_wayland!(match self; EventLoop(evlp) => evlp.pump_app_events(timeout, app)) } diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index 1135af8b..f7ac6136 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -160,16 +160,16 @@ impl EventLoop { Ok(event_loop) } - pub fn run_app(mut self, app: &mut A) -> Result<(), EventLoopError> { + pub fn run_app(mut self, app: A) -> Result<(), EventLoopError> { self.run_app_on_demand(app) } pub fn run_app_on_demand( &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( &mut self, timeout: Option, - 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( + fn poll_events_with_timeout( &mut self, mut timeout: Option, app: &mut A, diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 389e1dac..205a3735 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -367,16 +367,16 @@ impl EventLoop { &self.event_processor.target } - pub fn run_app(mut self, app: &mut A) -> Result<(), EventLoopError> { + pub fn run_app(mut self, app: A) -> Result<(), EventLoopError> { self.run_app_on_demand(app) } pub fn run_app_on_demand( &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( &mut self, timeout: Option, - 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( + fn poll_events_with_timeout( &mut self, mut timeout: Option, app: &mut A, diff --git a/src/platform_impl/orbital/event_loop.rs b/src/platform_impl/orbital/event_loop.rs index b709ce73..b3221905 100644 --- a/src/platform_impl/orbital/event_loop.rs +++ b/src/platform_impl/orbital/event_loop.rs @@ -500,7 +500,7 @@ impl EventLoop { } } - pub fn run_app(mut self, app: &mut A) -> Result<(), EventLoopError> { + pub fn run_app(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, ); } diff --git a/src/platform_impl/web/event_loop/mod.rs b/src/platform_impl/web/event_loop/mod.rs index 56742b87..6daa220b 100644 --- a/src/platform_impl/web/event_loop/mod.rs +++ b/src/platform_impl/web/event_loop/mod.rs @@ -28,11 +28,12 @@ impl EventLoop { Ok(EventLoop { elw }) } - pub fn run_app(self, app: &mut A) -> ! { + pub fn run_app(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 = Box::new(|event| handle_event(app, &target, event)); + let handler: Box = + 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 diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 007b06cc..f9ad3fad 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -187,13 +187,13 @@ impl EventLoop { &self.window_target } - pub fn run_app(mut self, app: &mut A) -> Result<(), EventLoopError> { + pub fn run_app(mut self, app: A) -> Result<(), EventLoopError> { self.run_app_on_demand(app) } pub fn run_app_on_demand( &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( &mut self, timeout: Option, - app: &mut A, + mut app: A, ) -> PumpStatus { { let runner = &self.window_target.p.runner_shared;