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