From 374014880b0606af9796a0ecfaff00f31a3312e5 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sat, 10 Aug 2024 18:19:15 +0200 Subject: [PATCH] Remove `ApplicationHandler::as_any()` --- examples/window.rs | 14 ++- src/application.rs | 103 ++++-------------- src/platform/pump_events.rs | 4 +- src/platform/run_on_demand.rs | 4 +- src/platform/wayland.rs | 6 +- src/platform_impl/linux/mod.rs | 4 +- .../linux/wayland/event_loop/mod.rs | 15 +-- src/platform_impl/linux/x11/mod.rs | 14 +-- 8 files changed, 54 insertions(+), 110 deletions(-) diff --git a/examples/window.rs b/examples/window.rs index 35333ac0f2..1bbc3c92c2 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -67,8 +67,15 @@ fn main() -> Result<(), Box> { }); } - let app = Application::new(&event_loop, receiver, sender); + let mut app = Application::new(&event_loop, receiver, sender); event_loop.register_wayland_callback::(); + + fn test(app: &mut dyn ApplicationHandler) { + app.as_any_mut().downcast_mut::().unwrap().wayland_callback(); + } + + test::(&mut app); + Ok(event_loop.run_app(app)?) } @@ -373,11 +380,6 @@ impl Application { } impl ApplicationHandler for Application { - fn as_any(&mut self) -> Option<&mut dyn std::any::Any> { - println!("Called"); - Some(self) - } - fn proxy_wake_up(&mut self, event_loop: &dyn ActiveEventLoop) { while let Ok(action) = self.receiver.try_recv() { self.handle_action_from_proxy(event_loop, action) diff --git a/src/application.rs b/src/application.rs index bb3f434716..038e2feb1d 100644 --- a/src/application.rs +++ b/src/application.rs @@ -7,7 +7,7 @@ use crate::event_loop::ActiveEventLoop; use crate::window::WindowId; /// The handler of the application events. -pub trait ApplicationHandler { +pub trait ApplicationHandler: AsAny { /// Emitted when new events arrive from the OS to be processed. /// /// This is a useful place to put code that should be done before you start processing @@ -327,23 +327,10 @@ pub trait ApplicationHandler { fn memory_warning(&mut self, event_loop: &dyn ActiveEventLoop) { let _ = event_loop; } - - /// Get the [`ApplicationHandler`] as [`Any`]. - /// - /// This is useful for downcasting to a concrete application type. - #[inline(always)] - fn as_any(&mut self) -> Option<&mut dyn Any> { - None - } } #[deny(clippy::missing_trait_methods)] -impl ApplicationHandler for &mut A { - #[inline(always)] - fn as_any(&mut self) -> Option<&mut dyn Any> { - (**self).as_any() - } - +impl ApplicationHandler for Box { #[inline] fn new_events(&mut self, event_loop: &dyn ActiveEventLoop, cause: StartCause) { (**self).new_events(event_loop, cause); @@ -410,75 +397,33 @@ impl ApplicationHandler for &mut A { } } -#[deny(clippy::missing_trait_methods)] -impl ApplicationHandler for Box { - #[inline(always)] - fn as_any(&mut self) -> Option<&mut dyn Any> { - (**self).as_any() - } - - #[inline] - fn new_events(&mut self, event_loop: &dyn ActiveEventLoop, cause: StartCause) { - (**self).new_events(event_loop, cause); - } - - #[inline] - fn resumed(&mut self, event_loop: &dyn ActiveEventLoop) { - (**self).resumed(event_loop); - } - - #[inline] - fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) { - (**self).can_create_surfaces(event_loop); - } - - #[inline] - fn proxy_wake_up(&mut self, event_loop: &dyn ActiveEventLoop) { - (**self).proxy_wake_up(event_loop); - } - - #[inline] - fn window_event( - &mut self, - event_loop: &dyn ActiveEventLoop, - window_id: WindowId, - event: WindowEvent, - ) { - (**self).window_event(event_loop, window_id, event); - } - - #[inline] - fn device_event( - &mut self, - event_loop: &dyn ActiveEventLoop, - device_id: DeviceId, - event: DeviceEvent, - ) { - (**self).device_event(event_loop, device_id, event); - } +trait UpcastFrom { + fn any_from(value: &T) -> &Self; + fn any_mut_from(value: &mut T) -> &mut Self; +} - #[inline] - fn about_to_wait(&mut self, event_loop: &dyn ActiveEventLoop) { - (**self).about_to_wait(event_loop); - } +pub trait AsAny { + fn as_any(&self) -> &U; + fn as_any_mut(&mut self) -> &mut U; +} - #[inline] - fn suspended(&mut self, event_loop: &dyn ActiveEventLoop) { - (**self).suspended(event_loop); +impl AsAny for T +where + U: UpcastFrom, +{ + fn as_any(&self) -> &U { + U::any_from(self) } - - #[inline] - fn destroy_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) { - (**self).destroy_surfaces(event_loop); + fn as_any_mut(&mut self) -> &mut U { + U::any_mut_from(self) } +} - #[inline] - fn exiting(&mut self, event_loop: &dyn ActiveEventLoop) { - (**self).exiting(event_loop); +impl UpcastFrom for dyn Any { + fn any_from(value: &T) -> &dyn Any { + value } - - #[inline] - fn memory_warning(&mut self, event_loop: &dyn ActiveEventLoop) { - (**self).memory_warning(event_loop); + fn any_mut_from(value: &mut T) -> &mut dyn Any { + value } } diff --git a/src/platform/pump_events.rs b/src/platform/pump_events.rs index 4d070feac5..56115a049e 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: A, + app: &mut A, ) -> PumpStatus; } @@ -110,7 +110,7 @@ impl EventLoopExtPumpEvents for EventLoop { fn pump_app_events( &mut self, timeout: Option, - app: A, + app: &mut 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 851e3450fc..d0ef58cca0 100644 --- a/src/platform/run_on_demand.rs +++ b/src/platform/run_on_demand.rs @@ -60,11 +60,11 @@ pub trait EventLoopExtRunOnDemand { /// /// [`exit()`]: ActiveEventLoop::exit() /// [`set_control_flow()`]: ActiveEventLoop::set_control_flow() - fn run_app_on_demand(&mut self, app: A) -> Result<(), EventLoopError>; + fn run_app_on_demand(&mut self, app: &mut A) -> Result<(), EventLoopError>; } impl EventLoopExtRunOnDemand for EventLoop { - fn run_app_on_demand(&mut self, app: A) -> Result<(), EventLoopError> { + fn run_app_on_demand(&mut self, app: &mut A) -> Result<(), EventLoopError> { self.event_loop.run_app_on_demand(app) } } diff --git a/src/platform/wayland.rs b/src/platform/wayland.rs index 789c2fa88a..18e85cca92 100644 --- a/src/platform/wayland.rs +++ b/src/platform/wayland.rs @@ -58,11 +58,7 @@ impl EventLoopExtWayland for EventLoop { }; event_loop.wayland_callback.set(Some(|app: &mut dyn ApplicationHandler| { - app.as_any() - .expect("as_any_mut is not implemented") - .downcast_mut::() - .unwrap() - .wayland_callback() + app.as_any_mut().downcast_mut::().unwrap().wayland_callback() })); } } diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 9fbc3e8912..573fe06b35 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -772,7 +772,7 @@ impl EventLoop { pub fn run_app_on_demand( &mut self, - app: A, + app: &mut A, ) -> Result<(), EventLoopError> { x11_or_wayland!(match self; EventLoop(evlp) => evlp.run_app_on_demand(app)) } @@ -780,7 +780,7 @@ impl EventLoop { pub fn pump_app_events( &mut self, timeout: Option, - app: A, + app: &mut 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 299dabfb9c..366af61bbc 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -156,17 +156,17 @@ impl EventLoop { Ok(event_loop) } - pub fn run_app(mut self, app: A) -> Result<(), EventLoopError> { - self.run_app_on_demand(app) + pub fn run_app(mut self, mut app: A) -> Result<(), EventLoopError> { + self.run_app_on_demand(&mut app) } pub fn run_app_on_demand( &mut self, - mut app: A, + app: &mut A, ) -> Result<(), EventLoopError> { self.active_event_loop.clear_exit(); let exit = loop { - match self.pump_app_events(None, &mut app) { + match self.pump_app_events(None, app) { PumpStatus::Exit(0) => { break Ok(()); }, @@ -191,19 +191,19 @@ impl EventLoop { pub fn pump_app_events( &mut self, timeout: Option, - mut app: A, + app: &mut A, ) -> PumpStatus { if !self.loop_running { self.loop_running = true; // Run the initial loop iteration. - self.single_iteration(&mut app, StartCause::Init); + self.single_iteration(app, StartCause::Init); } // Consider the possibility that the `StartCause::Init` iteration could // request to Exit. if !self.exiting() { - self.poll_events_with_timeout(timeout, &mut app); + self.poll_events_with_timeout(timeout, app); } if let Some(code) = self.exit_code() { self.loop_running = false; @@ -588,6 +588,7 @@ pub struct ActiveEventLoop { /// Connection to the wayland server. pub connection: Connection, + #[allow(clippy::type_complexity)] pub wayland_callback: Cell>, } diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 247f8f1609..8b8803ae02 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -372,17 +372,17 @@ impl EventLoop { &self.event_processor.target } - pub fn run_app(mut self, app: A) -> Result<(), EventLoopError> { - self.run_app_on_demand(app) + pub fn run_app(mut self, mut app: A) -> Result<(), EventLoopError> { + self.run_app_on_demand(&mut app) } pub fn run_app_on_demand( &mut self, - mut app: A, + app: &mut A, ) -> Result<(), EventLoopError> { self.event_processor.target.clear_exit(); let exit = loop { - match self.pump_app_events(None, &mut app) { + match self.pump_app_events(None, app) { PumpStatus::Exit(0) => { break Ok(()); }, @@ -409,19 +409,19 @@ impl EventLoop { pub fn pump_app_events( &mut self, timeout: Option, - mut app: A, + app: &mut A, ) -> PumpStatus { if !self.loop_running { self.loop_running = true; // run the initial loop iteration - self.single_iteration(&mut app, StartCause::Init); + self.single_iteration(app, StartCause::Init); } // Consider the possibility that the `StartCause::Init` iteration could // request to Exit. if !self.exiting() { - self.poll_events_with_timeout(timeout, &mut app); + self.poll_events_with_timeout(timeout, app); } if let Some(code) = self.exit_code() { self.loop_running = false;