1 use std::{
2     any::Any,
3     cell::{Cell, RefCell},
4     collections::{HashSet, VecDeque},
5     mem, panic, ptr,
6     rc::Rc,
7     time::Instant,
8 };
9 
10 use winapi::{
11     shared::{minwindef::DWORD, windef::HWND},
12     um::winuser,
13 };
14 
15 use crate::{
16     dpi::PhysicalSize,
17     event::{Event, StartCause, WindowEvent},
18     event_loop::ControlFlow,
19     platform_impl::platform::util,
20     window::WindowId,
21 };
22 
23 pub(crate) type EventLoopRunnerShared<T> = Rc<EventLoopRunner<T>>;
24 pub(crate) struct EventLoopRunner<T: 'static> {
25     // The event loop's win32 handles
26     thread_msg_target: HWND,
27     wait_thread_id: DWORD,
28 
29     control_flow: Cell<ControlFlow>,
30     runner_state: Cell<RunnerState>,
31     last_events_cleared: Cell<Instant>,
32 
33     event_handler: Cell<Option<Box<dyn FnMut(Event<'_, T>, &mut ControlFlow)>>>,
34     event_buffer: RefCell<VecDeque<BufferedEvent<T>>>,
35 
36     owned_windows: Cell<HashSet<HWND>>,
37 
38     panic_error: Cell<Option<PanicError>>,
39 }
40 
41 pub type PanicError = Box<dyn Any + Send + 'static>;
42 
43 /// See `move_state_to` function for details on how the state loop works.
44 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
45 enum RunnerState {
46     /// The event loop has just been created, and an `Init` event must be sent.
47     Uninitialized,
48     /// The event loop is idling.
49     Idle,
50     /// The event loop is handling the OS's events and sending them to the user's callback.
51     /// `NewEvents` has been sent, and `MainEventsCleared` hasn't.
52     HandlingMainEvents,
53     /// The event loop is handling the redraw events and sending them to the user's callback.
54     /// `MainEventsCleared` has been sent, and `RedrawEventsCleared` hasn't.
55     HandlingRedrawEvents,
56     /// The event loop has been destroyed. No other events will be emitted.
57     Destroyed,
58 }
59 
60 enum BufferedEvent<T: 'static> {
61     Event(Event<'static, T>),
62     ScaleFactorChanged(WindowId, f64, PhysicalSize<u32>),
63 }
64 
65 impl<T> EventLoopRunner<T> {
new(thread_msg_target: HWND, wait_thread_id: DWORD) -> EventLoopRunner<T>66     pub(crate) fn new(thread_msg_target: HWND, wait_thread_id: DWORD) -> EventLoopRunner<T> {
67         EventLoopRunner {
68             thread_msg_target,
69             wait_thread_id,
70             runner_state: Cell::new(RunnerState::Uninitialized),
71             control_flow: Cell::new(ControlFlow::Poll),
72             panic_error: Cell::new(None),
73             last_events_cleared: Cell::new(Instant::now()),
74             event_handler: Cell::new(None),
75             event_buffer: RefCell::new(VecDeque::new()),
76             owned_windows: Cell::new(HashSet::new()),
77         }
78     }
79 
set_event_handler<F>(&self, f: F) where F: FnMut(Event<'_, T>, &mut ControlFlow),80     pub(crate) unsafe fn set_event_handler<F>(&self, f: F)
81     where
82         F: FnMut(Event<'_, T>, &mut ControlFlow),
83     {
84         let old_event_handler = self.event_handler.replace(mem::transmute::<
85             Option<Box<dyn FnMut(Event<'_, T>, &mut ControlFlow)>>,
86             Option<Box<dyn FnMut(Event<'_, T>, &mut ControlFlow)>>,
87         >(Some(Box::new(f))));
88         assert!(old_event_handler.is_none());
89     }
90 
reset_runner(&self)91     pub(crate) fn reset_runner(&self) {
92         let EventLoopRunner {
93             thread_msg_target: _,
94             wait_thread_id: _,
95             runner_state,
96             panic_error,
97             control_flow,
98             last_events_cleared: _,
99             event_handler,
100             event_buffer: _,
101             owned_windows: _,
102         } = self;
103         runner_state.set(RunnerState::Uninitialized);
104         panic_error.set(None);
105         control_flow.set(ControlFlow::Poll);
106         event_handler.set(None);
107     }
108 }
109 
110 /// State retrieval functions.
111 impl<T> EventLoopRunner<T> {
thread_msg_target(&self) -> HWND112     pub fn thread_msg_target(&self) -> HWND {
113         self.thread_msg_target
114     }
115 
wait_thread_id(&self) -> DWORD116     pub fn wait_thread_id(&self) -> DWORD {
117         self.wait_thread_id
118     }
119 
redrawing(&self) -> bool120     pub fn redrawing(&self) -> bool {
121         self.runner_state.get() == RunnerState::HandlingRedrawEvents
122     }
123 
take_panic_error(&self) -> Result<(), PanicError>124     pub fn take_panic_error(&self) -> Result<(), PanicError> {
125         match self.panic_error.take() {
126             Some(err) => Err(err),
127             None => Ok(()),
128         }
129     }
130 
control_flow(&self) -> ControlFlow131     pub fn control_flow(&self) -> ControlFlow {
132         self.control_flow.get()
133     }
134 
handling_events(&self) -> bool135     pub fn handling_events(&self) -> bool {
136         self.runner_state.get() != RunnerState::Idle
137     }
138 
should_buffer(&self) -> bool139     pub fn should_buffer(&self) -> bool {
140         let handler = self.event_handler.take();
141         let should_buffer = handler.is_none();
142         self.event_handler.set(handler);
143         should_buffer
144     }
145 }
146 
147 /// Misc. functions
148 impl<T> EventLoopRunner<T> {
catch_unwind<R>(&self, f: impl FnOnce() -> R) -> Option<R>149     pub fn catch_unwind<R>(&self, f: impl FnOnce() -> R) -> Option<R> {
150         let panic_error = self.panic_error.take();
151         if panic_error.is_none() {
152             let result = panic::catch_unwind(panic::AssertUnwindSafe(f));
153 
154             // Check to see if the panic error was set in a re-entrant call to catch_unwind inside
155             // of `f`. If it was, that error takes priority. If it wasn't, check if our call to
156             // catch_unwind caught any panics and set panic_error appropriately.
157             match self.panic_error.take() {
158                 None => match result {
159                     Ok(r) => Some(r),
160                     Err(e) => {
161                         self.panic_error.set(Some(e));
162                         None
163                     }
164                 },
165                 Some(e) => {
166                     self.panic_error.set(Some(e));
167                     None
168                 }
169             }
170         } else {
171             self.panic_error.set(panic_error);
172             None
173         }
174     }
register_window(&self, window: HWND)175     pub fn register_window(&self, window: HWND) {
176         let mut owned_windows = self.owned_windows.take();
177         owned_windows.insert(window);
178         self.owned_windows.set(owned_windows);
179     }
180 
remove_window(&self, window: HWND)181     pub fn remove_window(&self, window: HWND) {
182         let mut owned_windows = self.owned_windows.take();
183         owned_windows.remove(&window);
184         self.owned_windows.set(owned_windows);
185     }
186 
owned_windows(&self, mut f: impl FnMut(HWND))187     pub fn owned_windows(&self, mut f: impl FnMut(HWND)) {
188         let mut owned_windows = self.owned_windows.take();
189         for hwnd in &owned_windows {
190             f(*hwnd);
191         }
192         let new_owned_windows = self.owned_windows.take();
193         owned_windows.extend(&new_owned_windows);
194         self.owned_windows.set(owned_windows);
195     }
196 }
197 
198 /// Event dispatch functions.
199 impl<T> EventLoopRunner<T> {
poll(&self)200     pub(crate) unsafe fn poll(&self) {
201         self.move_state_to(RunnerState::HandlingMainEvents);
202     }
203 
send_event(&self, event: Event<'_, T>)204     pub(crate) unsafe fn send_event(&self, event: Event<'_, T>) {
205         if let Event::RedrawRequested(_) = event {
206             if self.runner_state.get() != RunnerState::HandlingRedrawEvents {
207                 warn!("RedrawRequested dispatched without explicit MainEventsCleared");
208                 self.move_state_to(RunnerState::HandlingRedrawEvents);
209             }
210             self.call_event_handler(event);
211         } else {
212             if self.should_buffer() {
213                 // If the runner is already borrowed, we're in the middle of an event loop invocation. Add
214                 // the event to a buffer to be processed later.
215                 self.event_buffer
216                     .borrow_mut()
217                     .push_back(BufferedEvent::from_event(event))
218             } else {
219                 self.move_state_to(RunnerState::HandlingMainEvents);
220                 self.call_event_handler(event);
221                 self.dispatch_buffered_events();
222             }
223         }
224     }
225 
main_events_cleared(&self)226     pub(crate) unsafe fn main_events_cleared(&self) {
227         self.move_state_to(RunnerState::HandlingRedrawEvents);
228     }
229 
redraw_events_cleared(&self)230     pub(crate) unsafe fn redraw_events_cleared(&self) {
231         self.move_state_to(RunnerState::Idle);
232     }
233 
loop_destroyed(&self)234     pub(crate) unsafe fn loop_destroyed(&self) {
235         self.move_state_to(RunnerState::Destroyed);
236     }
237 
call_event_handler(&self, event: Event<'_, T>)238     unsafe fn call_event_handler(&self, event: Event<'_, T>) {
239         self.catch_unwind(|| {
240             let mut control_flow = self.control_flow.take();
241             let mut event_handler = self.event_handler.take()
242                 .expect("either event handler is re-entrant (likely), or no event handler is registered (very unlikely)");
243 
244             if control_flow != ControlFlow::Exit {
245                 event_handler(event, &mut control_flow);
246             } else {
247                 event_handler(event, &mut ControlFlow::Exit);
248             }
249 
250             assert!(self.event_handler.replace(Some(event_handler)).is_none());
251             self.control_flow.set(control_flow);
252         });
253     }
254 
dispatch_buffered_events(&self)255     unsafe fn dispatch_buffered_events(&self) {
256         loop {
257             // We do this instead of using a `while let` loop because if we use a `while let`
258             // loop the reference returned `borrow_mut()` doesn't get dropped until the end
259             // of the loop's body and attempts to add events to the event buffer while in
260             // `process_event` will fail.
261             let buffered_event_opt = self.event_buffer.borrow_mut().pop_front();
262             match buffered_event_opt {
263                 Some(e) => e.dispatch_event(|e| self.call_event_handler(e)),
264                 None => break,
265             }
266         }
267     }
268 
269     /// Dispatch control flow events (`NewEvents`, `MainEventsCleared`, `RedrawEventsCleared`, and
270     /// `LoopDestroyed`) as necessary to bring the internal `RunnerState` to the new runner state.
271     ///
272     /// The state transitions are defined as follows:
273     ///
274     /// ```text
275     ///    Uninitialized
276     ///          |
277     ///          V
278     ///  HandlingMainEvents
279     ///   ^            |
280     ///   |            V
281     /// Idle <--- HandlingRedrawEvents
282     ///   |
283     ///   V
284     /// Destroyed
285     /// ```
286     ///
287     /// Attempting to transition back to `Uninitialized` will result in a panic. Attempting to
288     /// transition *from* `Destroyed` will also reuslt in a panic. Transitioning to the current
289     /// state is a no-op. Even if the `new_runner_state` isn't the immediate next state in the
290     /// runner state machine (e.g. `self.runner_state == HandlingMainEvents` and
291     /// `new_runner_state == Idle`), the intermediate state transitions will still be executed.
move_state_to(&self, new_runner_state: RunnerState)292     unsafe fn move_state_to(&self, new_runner_state: RunnerState) {
293         use RunnerState::{
294             Destroyed, HandlingMainEvents, HandlingRedrawEvents, Idle, Uninitialized,
295         };
296 
297         match (
298             self.runner_state.replace(new_runner_state),
299             new_runner_state,
300         ) {
301             (Uninitialized, Uninitialized)
302             | (Idle, Idle)
303             | (HandlingMainEvents, HandlingMainEvents)
304             | (HandlingRedrawEvents, HandlingRedrawEvents)
305             | (Destroyed, Destroyed) => (),
306 
307             // State transitions that initialize the event loop.
308             (Uninitialized, HandlingMainEvents) => {
309                 self.call_new_events(true);
310             }
311             (Uninitialized, HandlingRedrawEvents) => {
312                 self.call_new_events(true);
313                 self.call_event_handler(Event::MainEventsCleared);
314             }
315             (Uninitialized, Idle) => {
316                 self.call_new_events(true);
317                 self.call_event_handler(Event::MainEventsCleared);
318                 self.call_redraw_events_cleared();
319             }
320             (Uninitialized, Destroyed) => {
321                 self.call_new_events(true);
322                 self.call_event_handler(Event::MainEventsCleared);
323                 self.call_redraw_events_cleared();
324                 self.call_event_handler(Event::LoopDestroyed);
325             }
326             (_, Uninitialized) => panic!("cannot move state to Uninitialized"),
327 
328             // State transitions that start the event handling process.
329             (Idle, HandlingMainEvents) => {
330                 self.call_new_events(false);
331             }
332             (Idle, HandlingRedrawEvents) => {
333                 self.call_new_events(false);
334                 self.call_event_handler(Event::MainEventsCleared);
335             }
336             (Idle, Destroyed) => {
337                 self.call_event_handler(Event::LoopDestroyed);
338             }
339 
340             (HandlingMainEvents, HandlingRedrawEvents) => {
341                 self.call_event_handler(Event::MainEventsCleared);
342             }
343             (HandlingMainEvents, Idle) => {
344                 warn!("RedrawEventsCleared emitted without explicit MainEventsCleared");
345                 self.call_event_handler(Event::MainEventsCleared);
346                 self.call_redraw_events_cleared();
347             }
348             (HandlingMainEvents, Destroyed) => {
349                 self.call_event_handler(Event::MainEventsCleared);
350                 self.call_redraw_events_cleared();
351                 self.call_event_handler(Event::LoopDestroyed);
352             }
353 
354             (HandlingRedrawEvents, Idle) => {
355                 self.call_redraw_events_cleared();
356             }
357             (HandlingRedrawEvents, HandlingMainEvents) => {
358                 warn!("NewEvents emitted without explicit RedrawEventsCleared");
359                 self.call_redraw_events_cleared();
360                 self.call_new_events(false);
361             }
362             (HandlingRedrawEvents, Destroyed) => {
363                 self.call_redraw_events_cleared();
364                 self.call_event_handler(Event::LoopDestroyed);
365             }
366 
367             (Destroyed, _) => panic!("cannot move state from Destroyed"),
368         }
369     }
370 
call_new_events(&self, init: bool)371     unsafe fn call_new_events(&self, init: bool) {
372         let start_cause = match (init, self.control_flow()) {
373             (true, _) => StartCause::Init,
374             (false, ControlFlow::Poll) => StartCause::Poll,
375             (false, ControlFlow::Exit) | (false, ControlFlow::Wait) => StartCause::WaitCancelled {
376                 requested_resume: None,
377                 start: self.last_events_cleared.get(),
378             },
379             (false, ControlFlow::WaitUntil(requested_resume)) => {
380                 if Instant::now() < requested_resume {
381                     StartCause::WaitCancelled {
382                         requested_resume: Some(requested_resume),
383                         start: self.last_events_cleared.get(),
384                     }
385                 } else {
386                     StartCause::ResumeTimeReached {
387                         requested_resume,
388                         start: self.last_events_cleared.get(),
389                     }
390                 }
391             }
392         };
393         self.call_event_handler(Event::NewEvents(start_cause));
394         self.dispatch_buffered_events();
395         winuser::RedrawWindow(
396             self.thread_msg_target,
397             ptr::null(),
398             ptr::null_mut(),
399             winuser::RDW_INTERNALPAINT,
400         );
401     }
402 
call_redraw_events_cleared(&self)403     unsafe fn call_redraw_events_cleared(&self) {
404         self.call_event_handler(Event::RedrawEventsCleared);
405         self.last_events_cleared.set(Instant::now());
406     }
407 }
408 
409 impl<T> BufferedEvent<T> {
from_event(event: Event<'_, T>) -> BufferedEvent<T>410     pub fn from_event(event: Event<'_, T>) -> BufferedEvent<T> {
411         match event {
412             Event::WindowEvent {
413                 event:
414                     WindowEvent::ScaleFactorChanged {
415                         scale_factor,
416                         new_inner_size,
417                     },
418                 window_id,
419             } => BufferedEvent::ScaleFactorChanged(window_id, scale_factor, *new_inner_size),
420             event => BufferedEvent::Event(event.to_static().unwrap()),
421         }
422     }
423 
dispatch_event(self, dispatch: impl FnOnce(Event<'_, T>))424     pub fn dispatch_event(self, dispatch: impl FnOnce(Event<'_, T>)) {
425         match self {
426             Self::Event(event) => dispatch(event),
427             Self::ScaleFactorChanged(window_id, scale_factor, mut new_inner_size) => {
428                 dispatch(Event::WindowEvent {
429                     window_id,
430                     event: WindowEvent::ScaleFactorChanged {
431                         scale_factor,
432                         new_inner_size: &mut new_inner_size,
433                     },
434                 });
435                 util::set_inner_size_physical(
436                     (window_id.0).0,
437                     new_inner_size.width as _,
438                     new_inner_size.height as _,
439                 );
440             }
441         }
442     }
443 }
444