Don't allow event loops to run in parallel

This commit is contained in:
dAxpeDDa 2023-06-25 12:03:22 +02:00 committed by daxpedda
parent 924f3323b5
commit b0106898f7
3 changed files with 19 additions and 11 deletions

View file

@ -8,9 +8,7 @@ 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::{ use crate::event_loop::{ControlFlow, EventLoopWindowTarget as RootEventLoopWindowTarget};
ControlFlow, EventLoopBuilder, EventLoopWindowTarget as RootEventLoopWindowTarget,
};
use std::marker::PhantomData; use std::marker::PhantomData;
@ -35,7 +33,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_inner(event_handler); self.spawn_inner(event_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 '!'
@ -50,11 +48,10 @@ impl<T> EventLoop<T> {
where where
F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow), F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
{ {
EventLoopBuilder::<T>::allow_event_loop_recreation(); self.spawn_inner(event_handler, true);
self.spawn_inner(event_handler);
} }
fn spawn_inner<F>(self, mut event_handler: F) 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),
{ {
@ -63,9 +60,10 @@ impl<T> EventLoop<T> {
_marker: PhantomData, _marker: PhantomData,
}; };
self.elw.p.run(Box::new(move |event, flow| { self.elw.p.run(
event_handler(event, &target, flow) Box::new(move |event, flow| event_handler(event, &target, flow)),
})); event_loop_recreation,
);
} }
pub fn create_proxy(&self) -> EventLoopProxy<T> { pub fn create_proxy(&self) -> EventLoopProxy<T> {

View file

@ -35,6 +35,7 @@ type OnEventHandle<T> = RefCell<Option<EventListenerHandle<dyn FnMut(T)>>>;
pub struct Execution<T: 'static> { pub struct Execution<T: 'static> {
runner: RefCell<RunnerEnum<T>>, runner: RefCell<RunnerEnum<T>>,
event_loop_recreation: Cell<bool>,
events: RefCell<VecDeque<EventWrapper<T>>>, events: RefCell<VecDeque<EventWrapper<T>>>,
id: RefCell<u32>, id: RefCell<u32>,
window: web_sys::Window, window: web_sys::Window,
@ -139,6 +140,7 @@ impl<T: 'static> Shared<T> {
pub fn new() -> Self { pub fn new() -> Self {
Shared(Rc::new(Execution { Shared(Rc::new(Execution {
runner: RefCell::new(RunnerEnum::Pending), runner: RefCell::new(RunnerEnum::Pending),
event_loop_recreation: Cell::new(false),
events: RefCell::new(VecDeque::new()), events: RefCell::new(VecDeque::new()),
#[allow(clippy::disallowed_methods)] #[allow(clippy::disallowed_methods)]
window: web_sys::window().expect("only callable from inside the `Window`"), window: web_sys::window().expect("only callable from inside the `Window`"),
@ -649,6 +651,9 @@ impl<T: 'static> Shared<T> {
// * For each undropped `Window`: // * For each undropped `Window`:
// * The `register_redraw_request` closure. // * The `register_redraw_request` closure.
// * The `destroy_fn` closure. // * The `destroy_fn` closure.
if self.0.event_loop_recreation.get() {
crate::event_loop::EventLoopBuilder::<T>::allow_event_loop_recreation();
}
} }
// Check if the event loop is currently closed // Check if the event loop is currently closed
@ -691,6 +696,10 @@ impl<T: 'static> Shared<T> {
DeviceEvents::Never => false, DeviceEvents::Never => false,
} }
} }
pub fn event_loop_recreation(&self, allow: bool) {
self.0.event_loop_recreation.set(allow)
}
} }
pub(crate) enum EventWrapper<T: 'static> { pub(crate) enum EventWrapper<T: 'static> {

View file

@ -69,7 +69,8 @@ impl<T> EventLoopWindowTarget<T> {
EventLoopProxy::new(self.runner.clone()) EventLoopProxy::new(self.runner.clone())
} }
pub fn run(&self, event_handler: Box<runner::EventHandler<T>>) { pub fn run(&self, event_handler: Box<runner::EventHandler<T>>, event_loop_recreation: bool) {
self.runner.event_loop_recreation(event_loop_recreation);
self.runner.set_listener(event_handler); self.runner.set_listener(event_handler);
} }