Skip to content

Commit 4d6fe7e

Browse files
authored
web: Avoid top-level Event
1 parent f9912ba commit 4d6fe7e

File tree

4 files changed

+75
-87
lines changed

4 files changed

+75
-87
lines changed

src/platform_impl/web/event_loop/mod.rs

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use super::{backend, HasMonitorPermissionFuture, MonitorPermissionFuture};
22
use crate::application::ApplicationHandler;
33
use crate::error::{EventLoopError, NotSupportedError};
4-
use crate::event::Event;
54
use crate::event_loop::ActiveEventLoop as RootActiveEventLoop;
65
use crate::platform::web::{PollStrategy, WaitUntilStrategy};
76

@@ -24,20 +23,20 @@ impl EventLoop {
2423
Ok(EventLoop { elw: ActiveEventLoop::new() })
2524
}
2625

27-
pub fn run_app<A: ApplicationHandler>(self, mut app: A) -> ! {
28-
let event_loop = self.elw.clone();
29-
30-
// SAFETY: Don't use `move` to make sure we leak the `event_handler` and `target`.
31-
let handler: Box<dyn FnMut(Event)> =
32-
Box::new(|event| handle_event(&mut app, &event_loop, event));
26+
pub fn run_app<A: ApplicationHandler>(self, app: A) -> ! {
27+
let app = Box::new(app);
3328

3429
// SAFETY: The `transmute` is necessary because `run()` requires `'static`. This is safe
3530
// because this function will never return and all resources not cleaned up by the point we
3631
// `throw` will leak, making this actually `'static`.
37-
let handler = unsafe {
38-
std::mem::transmute::<Box<dyn FnMut(Event)>, Box<dyn FnMut(Event) + 'static>>(handler)
32+
let app = unsafe {
33+
std::mem::transmute::<
34+
Box<dyn ApplicationHandler + '_>,
35+
Box<dyn ApplicationHandler + 'static>,
36+
>(app)
3937
};
40-
self.elw.run(handler, false);
38+
39+
self.elw.run(app, false);
4140

4241
// Throw an exception to break out of Rust execution and use unreachable to tell the
4342
// compiler this function won't return, giving it a return type of '!'
@@ -48,9 +47,8 @@ impl EventLoop {
4847
unreachable!();
4948
}
5049

51-
pub fn spawn_app<A: ApplicationHandler + 'static>(self, mut app: A) {
52-
let event_loop = self.elw.clone();
53-
self.elw.run(Box::new(move |event| handle_event(&mut app, &event_loop, event)), true);
50+
pub fn spawn_app<A: ApplicationHandler + 'static>(self, app: A) {
51+
self.elw.run(Box::new(app), true);
5452
}
5553

5654
pub fn window_target(&self) -> &dyn RootActiveEventLoop {
@@ -85,18 +83,3 @@ impl EventLoop {
8583
self.elw.runner.monitor().has_detailed_monitor_permission_async()
8684
}
8785
}
88-
89-
fn handle_event<A: ApplicationHandler>(app: &mut A, target: &ActiveEventLoop, event: Event) {
90-
match event {
91-
Event::NewEvents(cause) => app.new_events(target, cause),
92-
Event::WindowEvent { window_id, event } => app.window_event(target, window_id, event),
93-
Event::DeviceEvent { device_id, event } => app.device_event(target, device_id, event),
94-
Event::UserWakeUp => app.proxy_wake_up(target),
95-
Event::Suspended => app.suspended(target),
96-
Event::Resumed => app.resumed(target),
97-
Event::CreateSurfaces => app.can_create_surfaces(target),
98-
Event::AboutToWait => app.about_to_wait(target),
99-
Event::LoopExiting => app.exiting(target),
100-
Event::MemoryWarning => app.memory_warning(target),
101-
}
102-
}

src/platform_impl/web/event_loop/runner.rs

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ use web_time::{Duration, Instant};
1313
use super::super::event;
1414
use super::super::main_thread::MainThreadMarker;
1515
use super::super::monitor::MonitorHandler;
16-
use super::backend;
1716
use super::proxy::EventLoopProxy;
1817
use super::state::State;
18+
use super::{backend, ActiveEventLoop};
19+
use crate::application::ApplicationHandler;
1920
use crate::dpi::PhysicalSize;
20-
use crate::event::{DeviceEvent, ElementState, Event, RawKeyEvent, StartCause, WindowEvent};
21+
use crate::event::{DeviceEvent, DeviceId, ElementState, RawKeyEvent, StartCause, WindowEvent};
2122
use crate::event_loop::{ControlFlow, DeviceEvents};
2223
use crate::platform::web::{PollStrategy, WaitUntilStrategy};
2324
use crate::platform_impl::platform::backend::{EventListenerHandle, SafeAreaHandle};
@@ -27,8 +28,6 @@ use crate::window::WindowId;
2728

2829
pub struct Shared(Rc<Execution>);
2930

30-
pub(super) type EventHandler = dyn FnMut(Event);
31-
3231
impl Clone for Shared {
3332
fn clone(&self) -> Self {
3433
Shared(self.0.clone())
@@ -47,7 +46,7 @@ struct Execution {
4746
runner: RefCell<RunnerEnum>,
4847
suspended: Cell<bool>,
4948
event_loop_recreation: Cell<bool>,
50-
events: RefCell<VecDeque<EventWrapper>>,
49+
events: RefCell<VecDeque<Event>>,
5150
id: Cell<usize>,
5251
window: web_sys::Window,
5352
navigator: Navigator,
@@ -93,12 +92,13 @@ impl RunnerEnum {
9392

9493
struct Runner {
9594
state: State,
96-
event_handler: Box<EventHandler>,
95+
app: Box<dyn ApplicationHandler>,
96+
event_loop: ActiveEventLoop,
9797
}
9898

9999
impl Runner {
100-
pub fn new(event_handler: Box<EventHandler>) -> Self {
101-
Runner { state: State::Init, event_handler }
100+
pub fn new(app: Box<dyn ApplicationHandler>, event_loop: ActiveEventLoop) -> Self {
101+
Runner { state: State::Init, app, event_loop }
102102
}
103103

104104
/// Returns the corresponding `StartCause` for the current `state`, or `None`
@@ -115,19 +115,33 @@ impl Runner {
115115
})
116116
}
117117

118-
fn handle_single_event(&mut self, runner: &Shared, event: impl Into<EventWrapper>) {
119-
match event.into() {
120-
EventWrapper::Event(event) => (self.event_handler)(event),
121-
EventWrapper::ScaleChange { canvas, size, scale } => {
118+
fn handle_single_event(&mut self, runner: &Shared, event: Event) {
119+
match event {
120+
Event::NewEvents(cause) => self.app.new_events(&self.event_loop, cause),
121+
Event::WindowEvent { window_id, event } => {
122+
self.app.window_event(&self.event_loop, window_id, event)
123+
},
124+
Event::ScaleChange { canvas, size, scale } => {
122125
if let Some(canvas) = canvas.upgrade() {
123126
canvas.handle_scale_change(
124127
runner,
125-
|event| (self.event_handler)(event),
128+
|window_id, event| {
129+
self.app.window_event(&self.event_loop, window_id, event);
130+
},
126131
size,
127132
scale,
128133
)
129134
}
130135
},
136+
Event::DeviceEvent { device_id, event } => {
137+
self.app.device_event(&self.event_loop, device_id, event)
138+
},
139+
Event::UserWakeUp => self.app.proxy_wake_up(&self.event_loop),
140+
Event::Suspended => self.app.suspended(&self.event_loop),
141+
Event::Resumed => self.app.resumed(&self.event_loop),
142+
Event::CreateSurfaces => self.app.can_create_surfaces(&self.event_loop),
143+
Event::AboutToWait => self.app.about_to_wait(&self.event_loop),
144+
Event::LoopExiting => self.app.exiting(&self.event_loop),
131145
}
132146
}
133147
}
@@ -216,13 +230,13 @@ impl Shared {
216230
self.0.destroy_pending.borrow_mut().push_back(id);
217231
}
218232

219-
pub(crate) fn start(&self, event_handler: Box<EventHandler>) {
233+
pub(crate) fn start(&self, app: Box<dyn ApplicationHandler>, event_loop: ActiveEventLoop) {
220234
let mut runner = self.0.runner.borrow_mut();
221235
assert!(matches!(*runner, RunnerEnum::Pending));
222236
if self.0.monitor.is_initializing() {
223-
*runner = RunnerEnum::Initializing(Runner::new(event_handler));
237+
*runner = RunnerEnum::Initializing(Runner::new(app, event_loop));
224238
} else {
225-
*runner = RunnerEnum::Running(Runner::new(event_handler));
239+
*runner = RunnerEnum::Running(Runner::new(app, event_loop));
226240

227241
drop(runner);
228242

@@ -445,7 +459,7 @@ impl Shared {
445459

446460
pub fn request_redraw(&self, id: WindowId) {
447461
self.0.redraw_pending.borrow_mut().insert(id);
448-
self.send_events::<EventWrapper>(iter::empty());
462+
self.send_events([]);
449463
}
450464

451465
fn init(&self) {
@@ -473,7 +487,7 @@ impl Shared {
473487
// Add an event to the event loop runner, from the user or an event handler
474488
//
475489
// It will determine if the event should be immediately sent to the user or buffered for later
476-
pub(crate) fn send_event<E: Into<EventWrapper>>(&self, event: E) {
490+
pub(crate) fn send_event(&self, event: Event) {
477491
self.send_events(iter::once(event));
478492
}
479493

@@ -514,7 +528,7 @@ impl Shared {
514528
// Add a series of events to the event loop runner
515529
//
516530
// It will determine if the event should be immediately sent to the user or buffered for later
517-
pub(crate) fn send_events<E: Into<EventWrapper>>(&self, events: impl IntoIterator<Item = E>) {
531+
pub(crate) fn send_events(&self, events: impl IntoIterator<Item = Event>) {
518532
// If the event loop is closed, it should discard any new events
519533
if self.is_closed() {
520534
return;
@@ -539,7 +553,7 @@ impl Shared {
539553
}
540554
if !process_immediately {
541555
// Queue these events to look at later
542-
self.0.events.borrow_mut().extend(events.into_iter().map(Into::into));
556+
self.0.events.borrow_mut().extend(events);
543557
return;
544558
}
545559
// At this point, we know this is a fresh set of events
@@ -557,8 +571,7 @@ impl Shared {
557571
// Take the start event, then the events provided to this function, and run an iteration of
558572
// the event loop
559573
let start_event = Event::NewEvents(start_cause);
560-
let events =
561-
iter::once(EventWrapper::from(start_event)).chain(events.into_iter().map(Into::into));
574+
let events = iter::once(start_event).chain(events);
562575
self.run_until_cleared(events);
563576
}
564577

@@ -579,9 +592,9 @@ impl Shared {
579592
// cleared
580593
//
581594
// This will also process any events that have been queued or that are queued during processing
582-
fn run_until_cleared<E: Into<EventWrapper>>(&self, events: impl Iterator<Item = E>) {
595+
fn run_until_cleared(&self, events: impl Iterator<Item = Event>) {
583596
for event in events {
584-
self.handle_event(event.into());
597+
self.handle_event(event);
585598
}
586599
self.process_destroy_pending_windows();
587600

@@ -615,7 +628,7 @@ impl Shared {
615628
// handle_event takes in events and either queues them or applies a callback
616629
//
617630
// It should only ever be called from `run_until_cleared`.
618-
fn handle_event(&self, event: impl Into<EventWrapper>) {
631+
fn handle_event(&self, event: Event) {
619632
if self.is_closed() {
620633
self.exit();
621634
}
@@ -625,7 +638,7 @@ impl Shared {
625638
},
626639
// If an event is being handled without a runner somehow, add it to the event queue so
627640
// it will eventually be processed
628-
RunnerEnum::Pending => self.0.events.borrow_mut().push_back(event.into()),
641+
RunnerEnum::Pending => self.0.events.borrow_mut().push_back(event),
629642
// If the Runner has been destroyed, there is nothing to do.
630643
RunnerEnum::Destroyed => return,
631644
// This function should never be called if we are still waiting for something.
@@ -652,13 +665,7 @@ impl Shared {
652665
let mut events = self.0.events.borrow_mut();
653666

654667
// Pre-fetch `UserEvent`s to avoid having to wait until the next event loop cycle.
655-
events.extend(
656-
self.0
657-
.event_loop_proxy
658-
.take()
659-
.then_some(Event::UserWakeUp)
660-
.map(EventWrapper::from),
661-
);
668+
events.extend(self.0.event_loop_proxy.take().then_some(Event::UserWakeUp));
662669

663670
events.pop_front()
664671
};
@@ -845,13 +852,16 @@ impl WeakShared {
845852
}
846853
}
847854

848-
pub(crate) enum EventWrapper {
849-
Event(Event),
855+
#[allow(clippy::enum_variant_names)]
856+
pub(crate) enum Event {
857+
NewEvents(StartCause),
858+
WindowEvent { window_id: WindowId, event: WindowEvent },
850859
ScaleChange { canvas: Weak<backend::Canvas>, size: PhysicalSize<u32>, scale: f64 },
851-
}
852-
853-
impl From<Event> for EventWrapper {
854-
fn from(value: Event) -> Self {
855-
Self::Event(value)
856-
}
860+
DeviceEvent { device_id: Option<DeviceId>, event: DeviceEvent },
861+
Suspended,
862+
CreateSurfaces,
863+
Resumed,
864+
AboutToWait,
865+
LoopExiting,
866+
UserWakeUp,
857867
}

src/platform_impl/web/event_loop/window_target.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ use web_sys::Element;
88

99
use super::super::monitor::MonitorPermissionFuture;
1010
use super::super::{lock, KeyEventExtra};
11-
use super::runner::EventWrapper;
11+
use super::runner::Event;
1212
use super::{backend, runner};
13+
use crate::application::ApplicationHandler;
1314
use crate::error::{NotSupportedError, RequestError};
14-
use crate::event::{ElementState, Event, KeyEvent, TouchPhase, WindowEvent};
15+
use crate::event::{ElementState, KeyEvent, TouchPhase, WindowEvent};
1516
use crate::event_loop::{
1617
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
1718
EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as CoreOwnedDisplayHandle,
@@ -54,13 +55,9 @@ impl ActiveEventLoop {
5455
Self { runner: runner::Shared::new(), modifiers: ModifiersShared::default() }
5556
}
5657

57-
pub(crate) fn run(
58-
&self,
59-
event_handler: Box<runner::EventHandler>,
60-
event_loop_recreation: bool,
61-
) {
58+
pub(crate) fn run(&self, app: Box<dyn ApplicationHandler>, event_loop_recreation: bool) {
6259
self.runner.event_loop_recreation(event_loop_recreation);
63-
self.runner.start(event_handler);
60+
self.runner.start(app, self.clone());
6461
}
6562

6663
pub fn generate_id(&self) -> WindowId {
@@ -396,7 +393,7 @@ impl ActiveEventLoop {
396393
let canvas = canvas_clone.clone();
397394

398395
move |size, scale| {
399-
runner.send_event(EventWrapper::ScaleChange {
396+
runner.send_event(Event::ScaleChange {
400397
canvas: Rc::downgrade(&canvas),
401398
size,
402399
scale,

src/platform_impl/web/web_sys/canvas.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use web_sys::{
1212
};
1313

1414
use super::super::cursor::CursorHandler;
15+
use super::super::event_loop::runner;
1516
use super::super::main_thread::MainThreadMarker;
1617
use super::animation_frame::AnimationFrameHandler;
1718
use super::event_handle::EventListenerHandle;
@@ -23,7 +24,7 @@ use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
2324
use crate::error::RequestError;
2425
use crate::event::{
2526
ButtonSource, DeviceId, ElementState, MouseScrollDelta, PointerKind, PointerSource,
26-
SurfaceSizeWriter,
27+
SurfaceSizeWriter, WindowEvent,
2728
};
2829
use crate::keyboard::{Key, KeyLocation, ModifiersState, PhysicalKey};
2930
use crate::platform_impl::Fullscreen;
@@ -487,20 +488,17 @@ impl Canvas {
487488
pub(crate) fn handle_scale_change(
488489
&self,
489490
runner: &super::super::event_loop::runner::Shared,
490-
event_handler: impl FnOnce(crate::event::Event),
491+
event_handler: impl FnOnce(WindowId, WindowEvent),
491492
current_size: PhysicalSize<u32>,
492493
scale: f64,
493494
) {
494495
// First, we send the `ScaleFactorChanged` event:
495496
self.set_current_size(current_size);
496497
let new_size = {
497498
let new_size = Arc::new(Mutex::new(current_size));
498-
event_handler(crate::event::Event::WindowEvent {
499-
window_id: self.id,
500-
event: crate::event::WindowEvent::ScaleFactorChanged {
501-
scale_factor: scale,
502-
surface_size_writer: SurfaceSizeWriter::new(Arc::downgrade(&new_size)),
503-
},
499+
event_handler(self.id, WindowEvent::ScaleFactorChanged {
500+
scale_factor: scale,
501+
surface_size_writer: SurfaceSizeWriter::new(Arc::downgrade(&new_size)),
504502
});
505503

506504
let new_size = *new_size.lock().unwrap();
@@ -523,7 +521,7 @@ impl Canvas {
523521
} else if self.old_size() != new_size {
524522
// Then we at least send a resized event.
525523
self.set_old_size(new_size);
526-
runner.send_event(crate::event::Event::WindowEvent {
524+
runner.send_event(runner::Event::WindowEvent {
527525
window_id: self.id,
528526
event: crate::event::WindowEvent::SurfaceResized(new_size),
529527
})

0 commit comments

Comments
 (0)