1use std::{
2 any::Any,
3 cell::{Cell, RefCell},
4 collections::{HashSet, VecDeque},
5 mem, panic, ptr,
6 rc::Rc,
7 time::Instant,
8};
9
10use winapi::{
11 shared::{minwindef::DWORD, windef::HWND},
12 um::winuser,
13};
14
15use crate::{
16 dpi::PhysicalSize,
17 event::{Event, StartCause, WindowEvent},
18 event_loop::ControlFlow,
19 platform_impl::platform::util,
20 window::WindowId,
21};
22
23pub(crate) type EventLoopRunnerShared<T> = Rc<EventLoopRunner<T>>;
24pub(crate) struct EventLoopRunner<T: 'static> {
25 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
41pub type PanicError = Box<dyn Any + Send + 'static>;
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
45enum RunnerState {
46 Uninitialized,
48 Idle,
50 HandlingMainEvents,
53 HandlingRedrawEvents,
56 Destroyed,
58}
59
60enum BufferedEvent<T: 'static> {
61 Event(Event<'static, T>),
62 ScaleFactorChanged(WindowId, f64, PhysicalSize<u32>),
63}
64
65impl<T> 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
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
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
110impl<T> EventLoopRunner<T> {
112 pub fn thread_msg_target(&self) -> HWND {
113 self.thread_msg_target
114 }
115
116 pub fn wait_thread_id(&self) -> DWORD {
117 self.wait_thread_id
118 }
119
120 pub fn redrawing(&self) -> bool {
121 self.runner_state.get() == RunnerState::HandlingRedrawEvents
122 }
123
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
131 pub fn control_flow(&self) -> ControlFlow {
132 self.control_flow.get()
133 }
134
135 pub fn handling_events(&self) -> bool {
136 self.runner_state.get() != RunnerState::Idle
137 }
138
139 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
147impl<T> EventLoopRunner<T> {
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 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 }
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
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
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
198impl<T> EventLoopRunner<T> {
200 pub(crate) unsafe fn poll(&self) {
201 self.move_state_to(RunnerState::HandlingMainEvents);
202 }
203
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 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
226 pub(crate) unsafe fn main_events_cleared(&self) {
227 self.move_state_to(RunnerState::HandlingRedrawEvents);
228 }
229
230 pub(crate) unsafe fn redraw_events_cleared(&self) {
231 self.move_state_to(RunnerState::Idle);
232 }
233
234 pub(crate) unsafe fn loop_destroyed(&self) {
235 self.move_state_to(RunnerState::Destroyed);
236 }
237
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
255 unsafe fn dispatch_buffered_events(&self) {
256 loop {
257 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 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 (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 (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
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
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
409impl<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
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}