tao/platform_impl/windows/event_loop/
runner.rs1use std::{
6 any::Any,
7 cell::{Cell, RefCell},
8 collections::{HashSet, VecDeque},
9 mem, panic,
10 rc::Rc,
11 time::Instant,
12};
13
14use windows::Win32::{
15 Foundation::HWND,
16 Graphics::Gdi::{RedrawWindow, RDW_INTERNALPAINT},
17};
18
19use crate::{
20 dpi::PhysicalSize,
21 event::{Event, StartCause, WindowEvent},
22 event_loop::ControlFlow,
23 platform_impl::platform::util,
24 window::WindowId,
25};
26
27pub(crate) type EventLoopRunnerShared<T> = Rc<EventLoopRunner<T>>;
28pub(crate) struct EventLoopRunner<T: 'static> {
29 thread_msg_target: HWND,
31 wait_thread_id: u32,
32
33 control_flow: Cell<ControlFlow>,
34 runner_state: Cell<RunnerState>,
35 last_events_cleared: Cell<Instant>,
36
37 event_handler: Cell<Option<Box<dyn FnMut(Event<'_, T>, &mut ControlFlow)>>>,
38 event_buffer: RefCell<VecDeque<BufferedEvent<T>>>,
39
40 owned_windows: Cell<HashSet<isize>>,
41
42 panic_error: Cell<Option<PanicError>>,
43}
44
45pub type PanicError = Box<dyn Any + Send + 'static>;
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
49enum RunnerState {
50 Uninitialized,
52 Idle,
54 HandlingMainEvents,
57 HandlingRedrawEvents,
60 Destroyed,
62}
63
64enum BufferedEvent<T: 'static> {
65 Event(Event<'static, T>),
66 ScaleFactorChanged(WindowId, f64, PhysicalSize<u32>),
67}
68
69impl<T> EventLoopRunner<T> {
70 pub(crate) fn new(thread_msg_target: HWND, wait_thread_id: u32) -> EventLoopRunner<T> {
71 EventLoopRunner {
72 thread_msg_target,
73 wait_thread_id,
74 runner_state: Cell::new(RunnerState::Uninitialized),
75 control_flow: Cell::new(ControlFlow::Poll),
76 panic_error: Cell::new(None),
77 last_events_cleared: Cell::new(Instant::now()),
78 event_handler: Cell::new(None),
79 event_buffer: RefCell::new(VecDeque::new()),
80 owned_windows: Cell::new(HashSet::new()),
81 }
82 }
83
84 pub(crate) unsafe fn set_event_handler<F>(&self, f: F)
85 where
86 F: FnMut(Event<'_, T>, &mut ControlFlow),
87 {
88 let old_event_handler = self.event_handler.replace(mem::transmute::<
89 Option<Box<dyn FnMut(Event<'_, T>, &mut ControlFlow)>>,
90 Option<Box<dyn FnMut(Event<'_, T>, &mut ControlFlow)>>,
91 >(Some(Box::new(f))));
92 assert!(old_event_handler.is_none());
93 }
94
95 pub(crate) fn reset_runner(&self) {
96 let EventLoopRunner {
97 thread_msg_target: _,
98 wait_thread_id: _,
99 runner_state,
100 panic_error,
101 control_flow,
102 last_events_cleared: _,
103 event_handler,
104 event_buffer: _,
105 owned_windows: _,
106 } = self;
107 runner_state.set(RunnerState::Uninitialized);
108 panic_error.set(None);
109 control_flow.set(ControlFlow::Poll);
110 event_handler.set(None);
111 }
112}
113
114impl<T> EventLoopRunner<T> {
116 pub fn thread_msg_target(&self) -> HWND {
117 self.thread_msg_target
118 }
119
120 pub fn wait_thread_id(&self) -> u32 {
121 self.wait_thread_id
122 }
123
124 pub fn redrawing(&self) -> bool {
125 self.runner_state.get() == RunnerState::HandlingRedrawEvents
126 }
127
128 pub fn take_panic_error(&self) -> Result<(), PanicError> {
129 match self.panic_error.take() {
130 Some(err) => Err(err),
131 None => Ok(()),
132 }
133 }
134
135 pub fn control_flow(&self) -> ControlFlow {
136 self.control_flow.get()
137 }
138
139 pub fn handling_events(&self) -> bool {
140 self.runner_state.get() != RunnerState::Idle
141 }
142
143 pub fn should_buffer(&self) -> bool {
144 let handler = self.event_handler.take();
145 let should_buffer = handler.is_none();
146 self.event_handler.set(handler);
147 should_buffer
148 }
149}
150
151impl<T> EventLoopRunner<T> {
153 pub fn catch_unwind<R>(&self, f: impl FnOnce() -> R) -> Option<R> {
154 let panic_error = self.panic_error.take();
155 if panic_error.is_none() {
156 let result = panic::catch_unwind(panic::AssertUnwindSafe(f));
157
158 match self.panic_error.take() {
162 None => match result {
163 Ok(r) => Some(r),
164 Err(e) => {
165 self.panic_error.set(Some(e));
166 None
167 }
168 },
169 Some(e) => {
170 self.panic_error.set(Some(e));
171 None
172 }
173 }
174 } else {
175 self.panic_error.set(panic_error);
176 None
177 }
178 }
179 pub fn register_window(&self, window: HWND) {
180 let mut owned_windows = self.owned_windows.take();
181 owned_windows.insert(window.0 as _);
182 self.owned_windows.set(owned_windows);
183 }
184
185 pub fn remove_window(&self, window: HWND) {
186 let mut owned_windows = self.owned_windows.take();
187 owned_windows.remove(&(window.0 as _));
188 self.owned_windows.set(owned_windows);
189 }
190
191 pub fn owned_windows(&self, mut f: impl FnMut(HWND)) {
192 let mut owned_windows = self.owned_windows.take();
193 for hwnd in &owned_windows {
194 f(HWND(*hwnd as _));
195 }
196 let new_owned_windows = self.owned_windows.take();
197 owned_windows.extend(&new_owned_windows);
198 self.owned_windows.set(owned_windows);
199 }
200}
201
202impl<T> EventLoopRunner<T> {
204 pub(crate) unsafe fn poll(&self) {
205 self.move_state_to(RunnerState::HandlingMainEvents);
206 }
207
208 pub(crate) unsafe fn send_event(&self, event: Event<'_, T>) {
209 if let Event::RedrawRequested(_) = event {
210 if self.runner_state.get() != RunnerState::HandlingRedrawEvents {
211 debug!("RedrawRequested dispatched without explicit MainEventsCleared");
213 self.move_state_to(RunnerState::HandlingRedrawEvents);
214 }
215 self.call_event_handler(event);
216 } else if self.should_buffer() {
217 self
220 .event_buffer
221 .borrow_mut()
222 .push_back(BufferedEvent::from_event(event))
223 } else {
224 self.move_state_to(RunnerState::HandlingMainEvents);
225 self.call_event_handler(event);
226 self.dispatch_buffered_events();
227 }
228 }
229
230 pub(crate) unsafe fn main_events_cleared(&self) {
231 self.move_state_to(RunnerState::HandlingRedrawEvents);
232 }
233
234 pub(crate) unsafe fn redraw_events_cleared(&self) {
235 self.move_state_to(RunnerState::Idle);
236 }
237
238 pub(crate) unsafe fn loop_destroyed(&self) {
239 self.move_state_to(RunnerState::Destroyed);
240 }
241
242 unsafe fn call_event_handler(&self, event: Event<'_, T>) {
243 self.catch_unwind(|| {
244 let mut control_flow = self.control_flow.take();
245 let mut event_handler = self.event_handler.take()
246 .expect("either event handler is re-entrant (likely), or no event handler is registered (very unlikely)");
247
248 if let ControlFlow::ExitWithCode(code) = control_flow {
249 event_handler(event, &mut ControlFlow::ExitWithCode(code));
250 } else {
251 event_handler(event, &mut control_flow);
252 }
253
254 assert!(self.event_handler.replace(Some(event_handler)).is_none());
255 self.control_flow.set(control_flow);
256 });
257 }
258
259 unsafe fn dispatch_buffered_events(&self) {
260 loop {
261 let buffered_event_opt = self.event_buffer.borrow_mut().pop_front();
266 match buffered_event_opt {
267 Some(e) => e.dispatch_event(|e| self.call_event_handler(e)),
268 None => break,
269 }
270 }
271 }
272
273 unsafe fn move_state_to(&self, new_runner_state: RunnerState) {
297 use RunnerState::{Destroyed, HandlingMainEvents, HandlingRedrawEvents, Idle, Uninitialized};
298
299 match (
300 self.runner_state.replace(new_runner_state),
301 new_runner_state,
302 ) {
303 (Uninitialized, Uninitialized)
304 | (Idle, Idle)
305 | (HandlingMainEvents, HandlingMainEvents)
306 | (HandlingRedrawEvents, HandlingRedrawEvents)
307 | (Destroyed, Destroyed) => (),
308
309 (Uninitialized, HandlingMainEvents) => {
311 self.call_new_events(true);
312 }
313 (Uninitialized, HandlingRedrawEvents) => {
314 self.call_new_events(true);
315 self.call_event_handler(Event::MainEventsCleared);
316 }
317 (Uninitialized, Idle) => {
318 self.call_new_events(true);
319 self.call_event_handler(Event::MainEventsCleared);
320 self.call_redraw_events_cleared();
321 }
322 (Uninitialized, Destroyed) => {
323 self.call_new_events(true);
324 self.call_event_handler(Event::MainEventsCleared);
325 self.call_redraw_events_cleared();
326 self.call_event_handler(Event::LoopDestroyed);
327 }
328 (_, Uninitialized) => panic!("cannot move state to Uninitialized"),
329
330 (Idle, HandlingMainEvents) => {
332 self.call_new_events(false);
333 }
334 (Idle, HandlingRedrawEvents) => {
335 self.call_new_events(false);
336 self.call_event_handler(Event::MainEventsCleared);
337 }
338 (Idle, Destroyed) => {
339 self.call_event_handler(Event::LoopDestroyed);
340 }
341
342 (HandlingMainEvents, HandlingRedrawEvents) => {
343 self.call_event_handler(Event::MainEventsCleared);
344 }
345 (HandlingMainEvents, Idle) => {
346 debug!("RedrawEventsCleared emitted without explicit MainEventsCleared");
348 self.call_event_handler(Event::MainEventsCleared);
349 self.call_redraw_events_cleared();
350 }
351 (HandlingMainEvents, Destroyed) => {
352 self.call_event_handler(Event::MainEventsCleared);
353 self.call_redraw_events_cleared();
354 self.call_event_handler(Event::LoopDestroyed);
355 }
356
357 (HandlingRedrawEvents, Idle) => {
358 self.call_redraw_events_cleared();
359 }
360 (HandlingRedrawEvents, HandlingMainEvents) => {
361 debug!("NewEvents emitted without explicit RedrawEventsCleared");
363 self.call_redraw_events_cleared();
364 self.call_new_events(false);
365 }
366 (HandlingRedrawEvents, Destroyed) => {
367 self.call_redraw_events_cleared();
368 self.call_event_handler(Event::LoopDestroyed);
369 }
370
371 (Destroyed, _) => panic!("cannot move state from Destroyed"),
372 }
373 }
374
375 unsafe fn call_new_events(&self, init: bool) {
376 let start_cause = match (init, self.control_flow()) {
377 (true, _) => StartCause::Init,
378 (false, ControlFlow::Poll) => StartCause::Poll,
379 (false, ControlFlow::ExitWithCode(_)) | (false, ControlFlow::Wait) => {
380 StartCause::WaitCancelled {
381 requested_resume: None,
382 start: self.last_events_cleared.get(),
383 }
384 }
385 (false, ControlFlow::WaitUntil(requested_resume)) => {
386 if Instant::now() < requested_resume {
387 StartCause::WaitCancelled {
388 requested_resume: Some(requested_resume),
389 start: self.last_events_cleared.get(),
390 }
391 } else {
392 StartCause::ResumeTimeReached {
393 requested_resume,
394 start: self.last_events_cleared.get(),
395 }
396 }
397 }
398 };
399 self.call_event_handler(Event::NewEvents(start_cause));
400 self.dispatch_buffered_events();
401 let _ = RedrawWindow(Some(self.thread_msg_target), None, None, RDW_INTERNALPAINT);
402 }
403
404 unsafe fn call_redraw_events_cleared(&self) {
405 self.call_event_handler(Event::RedrawEventsCleared);
406 self.last_events_cleared.set(Instant::now());
407 }
408}
409
410impl<T> BufferedEvent<T> {
411 pub fn from_event(event: Event<'_, T>) -> BufferedEvent<T> {
412 match event {
413 Event::WindowEvent {
414 event:
415 WindowEvent::ScaleFactorChanged {
416 scale_factor,
417 new_inner_size,
418 },
419 window_id,
420 } => BufferedEvent::ScaleFactorChanged(window_id, scale_factor, *new_inner_size),
421 event => BufferedEvent::Event(event.to_static().unwrap()),
422 }
423 }
424
425 pub fn dispatch_event(self, dispatch: impl FnOnce(Event<'_, T>)) {
426 match self {
427 Self::Event(event) => dispatch(event),
428 Self::ScaleFactorChanged(window_id, scale_factor, mut new_inner_size) => {
429 let os_inner_size = new_inner_size;
430
431 dispatch(Event::WindowEvent {
432 window_id,
433 event: WindowEvent::ScaleFactorChanged {
434 scale_factor,
435 new_inner_size: &mut new_inner_size,
436 },
437 });
438
439 if new_inner_size != os_inner_size {
440 util::set_inner_size_physical(
441 HWND(window_id.0 .0 as _),
442 new_inner_size.width as _,
443 new_inner_size.height as _,
444 true,
445 );
446 }
447 }
448 }
449 }
450}