mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 06:11:30 +11:00
Allow recreating wasm event loop with spawn
(#2897)
This commit is contained in:
parent
864a1d5924
commit
bc216b8f67
|
@ -8,6 +8,7 @@ And please only add new entries to the top of this list, right below the `# Unre
|
||||||
|
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
|
- On Web, allow event loops to be recreated with `spawn`.
|
||||||
- **Breaking:** Rename `Window::set_ime_position` to `Window::set_ime_cursor_area` adding a way to set exclusive zone.
|
- **Breaking:** Rename `Window::set_ime_position` to `Window::set_ime_cursor_area` adding a way to set exclusive zone.
|
||||||
- On Android, changed default behavior of Android to ignore volume keys letting the operating system handle them.
|
- On Android, changed default behavior of Android to ignore volume keys letting the operating system handle them.
|
||||||
- On Android, added `EventLoopBuilderExtAndroid::handle_volume_keys` to indicate that the application will handle the volume keys manually.
|
- On Android, added `EventLoopBuilderExtAndroid::handle_volume_keys` to indicate that the application will handle the volume keys manually.
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
//! handle events.
|
//! handle events.
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::{error, fmt};
|
use std::{error, fmt};
|
||||||
|
|
||||||
use once_cell::sync::OnceCell;
|
|
||||||
use raw_window_handle::{HasRawDisplayHandle, RawDisplayHandle};
|
use raw_window_handle::{HasRawDisplayHandle, RawDisplayHandle};
|
||||||
#[cfg(not(wasm_platform))]
|
#[cfg(not(wasm_platform))]
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
@ -69,6 +69,8 @@ impl EventLoopBuilder<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static EVENT_LOOP_CREATED: AtomicBool = AtomicBool::new(false);
|
||||||
|
|
||||||
impl<T> EventLoopBuilder<T> {
|
impl<T> EventLoopBuilder<T> {
|
||||||
/// Start building a new event loop, with the given type as the user event
|
/// Start building a new event loop, with the given type as the user event
|
||||||
/// type.
|
/// type.
|
||||||
|
@ -114,10 +116,10 @@ impl<T> EventLoopBuilder<T> {
|
||||||
)]
|
)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn build(&mut self) -> EventLoop<T> {
|
pub fn build(&mut self) -> EventLoop<T> {
|
||||||
static EVENT_LOOP_CREATED: OnceCell<()> = OnceCell::new();
|
if EVENT_LOOP_CREATED.swap(true, Ordering::Relaxed) {
|
||||||
if EVENT_LOOP_CREATED.set(()).is_err() {
|
|
||||||
panic!("Creating EventLoop multiple times is not supported.");
|
panic!("Creating EventLoop multiple times is not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Certain platforms accept a mutable reference in their API.
|
// Certain platforms accept a mutable reference in their API.
|
||||||
#[allow(clippy::unnecessary_mut_passed)]
|
#[allow(clippy::unnecessary_mut_passed)]
|
||||||
EventLoop {
|
EventLoop {
|
||||||
|
@ -125,6 +127,11 @@ impl<T> EventLoopBuilder<T> {
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(wasm_platform)]
|
||||||
|
pub(crate) fn allow_event_loop_recreation() {
|
||||||
|
EVENT_LOOP_CREATED.store(false, Ordering::Relaxed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> fmt::Debug for EventLoop<T> {
|
impl<T> fmt::Debug for EventLoop<T> {
|
||||||
|
|
|
@ -66,6 +66,11 @@ pub trait EventLoopExtWebSys {
|
||||||
///
|
///
|
||||||
/// Unlike `run`, this returns immediately, and doesn't throw an exception in order to
|
/// Unlike `run`, this returns immediately, and doesn't throw an exception in order to
|
||||||
/// satisfy its `!` return type.
|
/// satisfy its `!` return type.
|
||||||
|
///
|
||||||
|
/// Once the event loop has been destroyed, it's possible to reinitialize another event loop
|
||||||
|
/// by calling this function again. This can be useful if you want to recreate the event loop
|
||||||
|
/// while the WebAssembly module is still loaded. For example, this can be used to recreate the
|
||||||
|
/// event loop when switching between tabs on a single page application.
|
||||||
fn spawn<F>(self, event_handler: F)
|
fn spawn<F>(self, event_handler: F)
|
||||||
where
|
where
|
||||||
F: 'static
|
F: 'static
|
||||||
|
|
|
@ -8,7 +8,9 @@ pub use self::window_target::EventLoopWindowTarget;
|
||||||
|
|
||||||
use super::{backend, device, window};
|
use super::{backend, device, window};
|
||||||
use crate::event::Event;
|
use crate::event::Event;
|
||||||
use crate::event_loop::{ControlFlow, EventLoopWindowTarget as RootEventLoopWindowTarget};
|
use crate::event_loop::{
|
||||||
|
ControlFlow, EventLoopBuilder, EventLoopWindowTarget as RootEventLoopWindowTarget,
|
||||||
|
};
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
@ -33,7 +35,7 @@ impl<T> EventLoop<T> {
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
self.spawn(event_handler);
|
self.spawn_inner(event_handler);
|
||||||
|
|
||||||
// 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,7 +46,15 @@ impl<T> EventLoop<T> {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn<F>(self, mut event_handler: F)
|
pub fn spawn<F>(self, event_handler: F)
|
||||||
|
where
|
||||||
|
F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
|
{
|
||||||
|
EventLoopBuilder::<T>::allow_event_loop_recreation();
|
||||||
|
self.spawn_inner(event_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn_inner<F>(self, mut event_handler: F)
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue