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
/// 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
#[inline]
#[cfg(not(all(wasm_platform, target_feature = "exception-handling")))]
pub fn run<F>(self, event_handler: F) -> Result<(), RunLoopError>
where
F: 'static + FnMut(Event<T>, &EventLoopWindowTarget<T>, &mut ControlFlow),
F: FnMut(Event<T>, &EventLoopWindowTarget<T>, &mut ControlFlow),
{
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>
where
F: 'static
+ FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
{
self.run_ondemand(event_handler)
}

View file

@ -106,7 +106,7 @@ impl<T: 'static> EventLoop<T> {
pub fn run<F>(self, event_handler: F) -> !
where
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
F: FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
{
unsafe {
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\
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,
event_loop: self.window_target,
}));
};
app_state::will_launch(Box::new(handler));
// Ensure application delegate is initialized
view::WinitApplicationDelegate::class();
@ -314,17 +322,20 @@ fn setup_control_flow_observers() {
#[derive(Debug)]
pub enum Never {}
type EventHandlerCallback<T> =
dyn FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow) + 'static;
pub trait EventHandler: Debug {
fn handle_nonuser_event(&mut self, event: Event<Never>, control_flow: &mut ControlFlow);
fn handle_user_events(&mut self, control_flow: &mut ControlFlow);
}
struct EventLoopHandler<F, T: 'static> {
f: F,
struct EventLoopHandler<T: 'static> {
f: Box<EventHandlerCallback<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 {
f.debug_struct("EventLoopHandler")
.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>
where
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
T: 'static,
{
impl<T: 'static> EventHandler for EventLoopHandler<T> {
fn handle_nonuser_event(&mut self, event: Event<Never>, control_flow: &mut ControlFlow) {
(self.f)(
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>
where
F: 'static + FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
F: FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
{
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>
where
F: 'static
+ FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
{
// Wrapper for event handler function that prevents ExitWithCode from being unset.
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
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
// compiler this function won't return, giving it a return type of '!'
@ -44,14 +56,7 @@ impl<T> EventLoop<T> {
unreachable!();
}
pub fn spawn<F>(self, 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)
pub fn spawn<F>(self, mut event_handler: F)
where
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
{
@ -62,7 +67,7 @@ impl<T> EventLoop<T> {
self.elw.p.run(
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>
where
F: 'static + FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
{
self.run_ondemand(event_handler)
}