Remove 'static requirement on run

There's no need to force the static on the users, given that internally
some backends were not using static in the first place.

Co-authored-by: daxpedda <daxpedda@gmail.com>
This commit is contained in:
Kirill Chibisov 2023-08-06 01:56:56 +04:00 committed by GitHub
parent cad3277550
commit 8100a6a584
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 43 additions and 30 deletions

View file

@ -310,11 +310,14 @@ impl<T> EventLoop<T> {
/// asynchronously (via the browser's own, internal, event loop) and doesn't block the /// asynchronously (via the browser's own, internal, event loop) and doesn't block the
/// current thread of execution like it does on other platforms. /// current thread of execution like it does on other platforms.
/// ///
/// This function won't be available with `target_feature = "exception-handling"`.
///
/// [`ControlFlow`]: crate::event_loop::ControlFlow /// [`ControlFlow`]: crate::event_loop::ControlFlow
#[inline] #[inline]
#[cfg(not(all(wasm_platform, target_feature = "exception-handling")))]
pub fn run<F>(self, event_handler: F) -> Result<(), RunLoopError> pub fn run<F>(self, event_handler: F) -> Result<(), RunLoopError>
where where
F: 'static + FnMut(Event<T>, &EventLoopWindowTarget<T>, &mut ControlFlow), F: FnMut(Event<T>, &EventLoopWindowTarget<T>, &mut ControlFlow),
{ {
self.event_loop.run(event_handler) self.event_loop.run(event_handler)
} }

View file

@ -526,8 +526,7 @@ impl<T: 'static> EventLoop<T> {
pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError> pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError>
where where
F: 'static F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
+ FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
{ {
self.run_ondemand(event_handler) self.run_ondemand(event_handler)
} }

View file

@ -106,7 +106,7 @@ impl<T: 'static> EventLoop<T> {
pub fn run<F>(self, event_handler: F) -> ! pub fn run<F>(self, event_handler: F) -> !
where where
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow), F: FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
{ {
unsafe { unsafe {
let application = UIApplication::shared(MainThreadMarker::new().unwrap()); let application = UIApplication::shared(MainThreadMarker::new().unwrap());
@ -116,10 +116,18 @@ impl<T: 'static> EventLoop<T> {
`EventLoop` cannot be `run` after a call to `UIApplicationMain` on iOS\n\ `EventLoop` cannot be `run` after a call to `UIApplicationMain` on iOS\n\
Note: `EventLoop::run` calls `UIApplicationMain` on iOS", Note: `EventLoop::run` calls `UIApplicationMain` on iOS",
); );
app_state::will_launch(Box::new(EventLoopHandler {
let event_handler = std::mem::transmute::<
Box<dyn FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow)>,
Box<EventHandlerCallback<T>>,
>(Box::new(event_handler));
let handler = EventLoopHandler {
f: event_handler, f: event_handler,
event_loop: self.window_target, event_loop: self.window_target,
})); };
app_state::will_launch(Box::new(handler));
// Ensure application delegate is initialized // Ensure application delegate is initialized
view::WinitApplicationDelegate::class(); view::WinitApplicationDelegate::class();
@ -314,17 +322,20 @@ fn setup_control_flow_observers() {
#[derive(Debug)] #[derive(Debug)]
pub enum Never {} pub enum Never {}
type EventHandlerCallback<T> =
dyn FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow) + 'static;
pub trait EventHandler: Debug { pub trait EventHandler: Debug {
fn handle_nonuser_event(&mut self, event: Event<Never>, control_flow: &mut ControlFlow); fn handle_nonuser_event(&mut self, event: Event<Never>, control_flow: &mut ControlFlow);
fn handle_user_events(&mut self, control_flow: &mut ControlFlow); fn handle_user_events(&mut self, control_flow: &mut ControlFlow);
} }
struct EventLoopHandler<F, T: 'static> { struct EventLoopHandler<T: 'static> {
f: F, f: Box<EventHandlerCallback<T>>,
event_loop: RootEventLoopWindowTarget<T>, event_loop: RootEventLoopWindowTarget<T>,
} }
impl<F, T: 'static> Debug for EventLoopHandler<F, T> { impl<T: 'static> Debug for EventLoopHandler<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("EventLoopHandler") f.debug_struct("EventLoopHandler")
.field("event_loop", &self.event_loop) .field("event_loop", &self.event_loop)
@ -332,11 +343,7 @@ impl<F, T: 'static> Debug for EventLoopHandler<F, T> {
} }
} }
impl<F, T> EventHandler for EventLoopHandler<F, T> impl<T: 'static> EventHandler for EventLoopHandler<T> {
where
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
T: 'static,
{
fn handle_nonuser_event(&mut self, event: Event<Never>, control_flow: &mut ControlFlow) { fn handle_nonuser_event(&mut self, event: Event<Never>, control_flow: &mut ControlFlow) {
(self.f)( (self.f)(
event.map_nonuser_event().unwrap(), event.map_nonuser_event().unwrap(),

View file

@ -195,7 +195,7 @@ impl<T> EventLoop<T> {
pub fn run<F>(mut self, callback: F) -> Result<(), RunLoopError> pub fn run<F>(mut self, callback: F) -> Result<(), RunLoopError>
where where
F: 'static + FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow), F: FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
{ {
self.run_ondemand(callback) self.run_ondemand(callback)
} }

View file

@ -445,8 +445,7 @@ impl<T: 'static> EventLoop<T> {
pub fn run<F>(mut self, mut event_handler_inner: F) -> Result<(), RunLoopError> pub fn run<F>(mut self, mut event_handler_inner: F) -> Result<(), RunLoopError>
where where
F: 'static F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
+ FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
{ {
// Wrapper for event handler function that prevents ExitWithCode from being unset. // Wrapper for event handler function that prevents ExitWithCode from being unset.
let mut event_handler = let mut event_handler =

View file

@ -29,11 +29,23 @@ impl<T> EventLoop<T> {
} }
} }
pub fn run<F>(self, event_handler: F) -> ! pub fn run<F>(self, mut event_handler: F) -> !
where where
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow), F: FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
{ {
self.spawn_inner(event_handler, false); let target = RootEventLoopWindowTarget {
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(_, _)> =
Box::new(|event, flow| event_handler(event, &target, flow));
// 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
// `throw` will leak, making this actually `'static`.
let handler = unsafe { std::mem::transmute(handler) };
self.elw.p.run(handler, false);
// Throw an exception to break out of Rust execution and use unreachable to tell the // Throw an exception to break out of Rust execution and use unreachable to tell the
// compiler this function won't return, giving it a return type of '!' // compiler this function won't return, giving it a return type of '!'
@ -44,14 +56,7 @@ impl<T> EventLoop<T> {
unreachable!(); unreachable!();
} }
pub fn spawn<F>(self, event_handler: F) pub fn spawn<F>(self, mut event_handler: F)
where
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
{
self.spawn_inner(event_handler, true);
}
fn spawn_inner<F>(self, mut event_handler: F, event_loop_recreation: bool)
where where
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow), F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
{ {
@ -62,7 +67,7 @@ impl<T> EventLoop<T> {
self.elw.p.run( self.elw.p.run(
Box::new(move |event, flow| event_handler(event, &target, flow)), Box::new(move |event, flow| event_handler(event, &target, flow)),
event_loop_recreation, true,
); );
} }

View file

@ -248,7 +248,7 @@ impl<T: 'static> EventLoop<T> {
pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError> pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError>
where where
F: 'static + FnMut(Event<T>, &RootELW<T>, &mut ControlFlow), F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
{ {
self.run_ondemand(event_handler) self.run_ondemand(event_handler)
} }