Skip to content

Commit

Permalink
Remove ApplicationHandler::as_any()
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda committed Aug 10, 2024
1 parent 9ea7a54 commit 3740148
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 110 deletions.
14 changes: 8 additions & 6 deletions examples/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,15 @@ fn main() -> Result<(), Box<dyn Error>> {
});
}

let app = Application::new(&event_loop, receiver, sender);
let mut app = Application::new(&event_loop, receiver, sender);
event_loop.register_wayland_callback::<Application>();

fn test<T: WaylandApplicationHandler>(app: &mut dyn ApplicationHandler) {
app.as_any_mut().downcast_mut::<T>().unwrap().wayland_callback();
}

test::<Application>(&mut app);

Ok(event_loop.run_app(app)?)
}

Expand Down Expand Up @@ -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)
Expand Down
103 changes: 24 additions & 79 deletions src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<dyn Any> {
/// 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
Expand Down Expand Up @@ -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<A: ?Sized + ApplicationHandler> ApplicationHandler for &mut A {
#[inline(always)]
fn as_any(&mut self) -> Option<&mut dyn Any> {
(**self).as_any()
}

impl<A: ?Sized + ApplicationHandler + 'static> ApplicationHandler for Box<A> {
#[inline]
fn new_events(&mut self, event_loop: &dyn ActiveEventLoop, cause: StartCause) {
(**self).new_events(event_loop, cause);
Expand Down Expand Up @@ -410,75 +397,33 @@ impl<A: ?Sized + ApplicationHandler> ApplicationHandler for &mut A {
}
}

#[deny(clippy::missing_trait_methods)]
impl<A: ?Sized + ApplicationHandler> ApplicationHandler for Box<A> {
#[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<T: ?Sized> {
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<U: ?Sized> {
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<T: ?Sized, U: ?Sized> AsAny<U> for T
where
U: UpcastFrom<T>,
{
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<T: Any> UpcastFrom<T> 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
}
}
4 changes: 2 additions & 2 deletions src/platform/pump_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,15 @@ pub trait EventLoopExtPumpEvents {
fn pump_app_events<A: ApplicationHandler>(
&mut self,
timeout: Option<Duration>,
app: A,
app: &mut A,
) -> PumpStatus;
}

impl EventLoopExtPumpEvents for EventLoop {
fn pump_app_events<A: ApplicationHandler>(
&mut self,
timeout: Option<Duration>,
app: A,
app: &mut A,
) -> PumpStatus {
self.event_loop.pump_app_events(timeout, app)
}
Expand Down
4 changes: 2 additions & 2 deletions src/platform/run_on_demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,11 @@ pub trait EventLoopExtRunOnDemand {
///
/// [`exit()`]: ActiveEventLoop::exit()
/// [`set_control_flow()`]: ActiveEventLoop::set_control_flow()
fn run_app_on_demand<A: ApplicationHandler>(&mut self, app: A) -> Result<(), EventLoopError>;
fn run_app_on_demand<A: ApplicationHandler>(&mut self, app: &mut A) -> Result<(), EventLoopError>;
}

impl EventLoopExtRunOnDemand for EventLoop {
fn run_app_on_demand<A: ApplicationHandler>(&mut self, app: A) -> Result<(), EventLoopError> {
fn run_app_on_demand<A: ApplicationHandler>(&mut self, app: &mut A) -> Result<(), EventLoopError> {
self.event_loop.run_app_on_demand(app)
}
}
Expand Down
6 changes: 1 addition & 5 deletions src/platform/wayland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<T>()
.unwrap()
.wayland_callback()
app.as_any_mut().downcast_mut::<T>().unwrap().wayland_callback()
}));
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/platform_impl/linux/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -772,15 +772,15 @@ impl EventLoop {

pub fn run_app_on_demand<A: ApplicationHandler>(
&mut self,
app: A,
app: &mut A,
) -> Result<(), EventLoopError> {
x11_or_wayland!(match self; EventLoop(evlp) => evlp.run_app_on_demand(app))
}

pub fn pump_app_events<A: ApplicationHandler>(
&mut self,
timeout: Option<Duration>,
app: A,
app: &mut A,
) -> PumpStatus {
x11_or_wayland!(match self; EventLoop(evlp) => evlp.pump_app_events(timeout, app))
}
Expand Down
15 changes: 8 additions & 7 deletions src/platform_impl/linux/wayland/event_loop/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,17 +156,17 @@ impl EventLoop {
Ok(event_loop)
}

pub fn run_app<A: ApplicationHandler>(mut self, app: A) -> Result<(), EventLoopError> {
self.run_app_on_demand(app)
pub fn run_app<A: ApplicationHandler>(mut self, mut app: A) -> Result<(), EventLoopError> {
self.run_app_on_demand(&mut app)
}

pub fn run_app_on_demand<A: ApplicationHandler>(
&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(());
},
Expand All @@ -191,19 +191,19 @@ impl EventLoop {
pub fn pump_app_events<A: ApplicationHandler>(
&mut self,
timeout: Option<Duration>,
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;
Expand Down Expand Up @@ -588,6 +588,7 @@ pub struct ActiveEventLoop {
/// Connection to the wayland server.
pub connection: Connection,

#[allow(clippy::type_complexity)]
pub wayland_callback: Cell<Option<fn(&mut dyn ApplicationHandler)>>,
}

Expand Down
14 changes: 7 additions & 7 deletions src/platform_impl/linux/x11/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,17 +372,17 @@ impl EventLoop {
&self.event_processor.target
}

pub fn run_app<A: ApplicationHandler>(mut self, app: A) -> Result<(), EventLoopError> {
self.run_app_on_demand(app)
pub fn run_app<A: ApplicationHandler>(mut self, mut app: A) -> Result<(), EventLoopError> {
self.run_app_on_demand(&mut app)
}

pub fn run_app_on_demand<A: ApplicationHandler>(
&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(());
},
Expand All @@ -409,19 +409,19 @@ impl EventLoop {
pub fn pump_app_events<A: ApplicationHandler>(
&mut self,
timeout: Option<Duration>,
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;
Expand Down

0 comments on commit 3740148

Please sign in to comment.