From 70722cc4c322e3e599b3a03bce5058a5d433970b Mon Sep 17 00:00:00 2001 From: Osspial Date: Wed, 5 Sep 2018 19:58:52 -1100 Subject: [PATCH] When SendEvent is called during event closure, buffer events --- src/platform_impl/windows/event_loop.rs | 80 ++++++++++++++----------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index ca238a2980..60a493995e 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -20,6 +20,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::time::{Duration, Instant}; use std::rc::Rc; use std::cell::RefCell; +use std::collections::VecDeque; use parking_lot::Mutex; use crossbeam_channel::{self, Sender, Receiver}; @@ -122,11 +123,7 @@ pub(crate) struct SubclassInput { impl SubclassInput { unsafe fn send_event(&self, event: Event) { - let mut runner = self.event_loop_runner.borrow_mut(); - match *runner { - ELRSharedOption::Runner(runner) => (*runner).process_event(event), - ELRSharedOption::Buffer(ref mut buffer) => buffer.push(event) - } + self.event_loop_runner.send_event(event); } } @@ -137,11 +134,7 @@ struct ThreadMsgTargetSubclassInput { impl ThreadMsgTargetSubclassInput { unsafe fn send_event(&self, event: Event) { - let mut runner = self.event_loop_runner.borrow_mut(); - match *runner { - ELRSharedOption::Runner(runner) => (*runner).process_event(event), - ELRSharedOption::Buffer(ref mut buffer) => buffer.push(event) - } + self.event_loop_runner.send_event(event); } } @@ -163,7 +156,10 @@ impl EventLoop { become_dpi_aware(dpi_aware); let thread_id = unsafe { processthreadsapi::GetCurrentThreadId() }; - let runner_shared = Rc::new(RefCell::new(ELRSharedOption::Buffer(vec![]))); + let runner_shared = Rc::new(ELRShared { + runner: RefCell::new(None), + buffer: RefCell::new(VecDeque::new()) + }); let (thread_msg_target, thread_msg_sender) = thread_event_target_window(runner_shared.clone()); EventLoop { @@ -201,15 +197,15 @@ impl EventLoop { }; { let runner_shared = self.runner_shared.clone(); - let mut runner_shared = runner_shared.borrow_mut(); - let mut event_buffer = vec![]; - if let ELRSharedOption::Buffer(ref mut buffer) = *runner_shared { - mem::swap(buffer, &mut event_buffer); - } - for event in event_buffer.drain(..) { - unsafe{ runner.process_event(event); } + let mut runner_ref = runner_shared.runner.borrow_mut(); + loop { + let event = runner_shared.buffer.borrow_mut().pop_front(); + match event { + Some(e) => unsafe{ runner.process_event(e); }, + None => break + } } - *runner_shared = ELRSharedOption::Runner(&mut runner); + *runner_ref = Some(&mut runner); } unsafe { @@ -247,7 +243,7 @@ impl EventLoop { } unsafe{ runner.call_event_handler(Event::LoopDestroyed) } - *self.runner_shared.borrow_mut() = ELRSharedOption::Buffer(vec![]); + *self.runner_shared.runner.borrow_mut() = None; } pub fn create_proxy(&self) -> EventLoopProxy { @@ -266,10 +262,10 @@ impl EventLoop { } } -pub(crate) type EventLoopRunnerShared = Rc>>; -pub(crate) enum ELRSharedOption { - Runner(*mut EventLoopRunner), - Buffer(Vec>) +pub(crate) type EventLoopRunnerShared = Rc>; +pub(crate) struct ELRShared { + runner: RefCell>>, + buffer: RefCell>> } pub(crate) struct EventLoopRunner { event_loop: *const EventLoop, @@ -280,6 +276,18 @@ pub(crate) struct EventLoopRunner { event_handler: *mut FnMut(Event, &RootEventLoop, &mut ControlFlow) } +impl ELRShared { + unsafe fn send_event(&self, event: Event) { + if let Ok(runner_ref) = self.runner.try_borrow_mut() { + if let Some(runner) = *runner_ref { + (*runner).process_event(event); + return; + } + } + self.buffer.borrow_mut().push_back(event) + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum RunnerState { /// The event loop has just been created, and an `Init` event must be sent. @@ -749,15 +757,15 @@ unsafe extern "system" fn public_window_callback( match msg { winuser::WM_ENTERSIZEMOVE => { - let runner = subclass_input.event_loop_runner.borrow_mut(); - if let ELRSharedOption::Runner(runner) = *runner { + let runner = subclass_input.event_loop_runner.runner.borrow_mut(); + if let Some(runner) = *runner { (*runner).in_modal_loop = true; } 0 }, winuser::WM_EXITSIZEMOVE => { - let runner = subclass_input.event_loop_runner.borrow_mut(); - if let ELRSharedOption::Runner(runner) = *runner { + let runner = subclass_input.event_loop_runner.runner.borrow_mut(); + if let Some(runner) = *runner { (*runner).in_modal_loop = false; } 0 @@ -791,8 +799,8 @@ unsafe extern "system" fn public_window_callback( _ if msg == *REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID => { use event::WindowEvent::RedrawRequested; - let runner = subclass_input.event_loop_runner.borrow_mut(); - if let ELRSharedOption::Runner(runner) = *runner { + let runner = subclass_input.event_loop_runner.runner.borrow_mut(); + if let Some(runner) = *runner { let runner = &mut *runner; match runner.runner_state { RunnerState::Idle(..) | @@ -814,8 +822,8 @@ unsafe extern "system" fn public_window_callback( let mut send_event = false; { - let runner = subclass_input.event_loop_runner.borrow_mut(); - if let ELRSharedOption::Runner(runner) = *runner { + let runner = subclass_input.event_loop_runner.runner.borrow_mut(); + if let Some(runner) = *runner { let runner = &mut *runner; match runner.runner_state { RunnerState::Idle(..) | @@ -1502,8 +1510,8 @@ unsafe extern "system" fn thread_event_target_callback( ); }; let in_modal_loop = { - let runner = subclass_input.event_loop_runner.borrow_mut(); - if let ELRSharedOption::Runner(runner) = *runner { + let runner = subclass_input.event_loop_runner.runner.borrow_mut(); + if let Some(runner) = *runner { (*runner).in_modal_loop } else { false @@ -1537,8 +1545,8 @@ unsafe extern "system" fn thread_event_target_callback( } } - let runner = subclass_input.event_loop_runner.borrow_mut(); - if let ELRSharedOption::Runner(runner) = *runner { + let runner = subclass_input.event_loop_runner.runner.borrow_mut(); + if let Some(runner) = *runner { let runner = &mut *runner; runner.events_cleared(); match runner.control_flow {