mirror of
https://github.com/rust-windowing/winit.git
synced 2026-09-02 06:40:06 -04:00
When SendEvent is called during event closure, buffer events
This commit is contained in:
@@ -20,6 +20,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::collections::VecDeque;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use crossbeam_channel::{self, Sender, Receiver};
|
use crossbeam_channel::{self, Sender, Receiver};
|
||||||
|
|
||||||
@@ -122,11 +123,7 @@ pub(crate) struct SubclassInput<T> {
|
|||||||
|
|
||||||
impl<T> SubclassInput<T> {
|
impl<T> SubclassInput<T> {
|
||||||
unsafe fn send_event(&self, event: Event<T>) {
|
unsafe fn send_event(&self, event: Event<T>) {
|
||||||
let mut runner = self.event_loop_runner.borrow_mut();
|
self.event_loop_runner.send_event(event);
|
||||||
match *runner {
|
|
||||||
ELRSharedOption::Runner(runner) => (*runner).process_event(event),
|
|
||||||
ELRSharedOption::Buffer(ref mut buffer) => buffer.push(event)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,11 +134,7 @@ struct ThreadMsgTargetSubclassInput<T> {
|
|||||||
|
|
||||||
impl<T> ThreadMsgTargetSubclassInput<T> {
|
impl<T> ThreadMsgTargetSubclassInput<T> {
|
||||||
unsafe fn send_event(&self, event: Event<T>) {
|
unsafe fn send_event(&self, event: Event<T>) {
|
||||||
let mut runner = self.event_loop_runner.borrow_mut();
|
self.event_loop_runner.send_event(event);
|
||||||
match *runner {
|
|
||||||
ELRSharedOption::Runner(runner) => (*runner).process_event(event),
|
|
||||||
ELRSharedOption::Buffer(ref mut buffer) => buffer.push(event)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +156,10 @@ impl<T> EventLoop<T> {
|
|||||||
become_dpi_aware(dpi_aware);
|
become_dpi_aware(dpi_aware);
|
||||||
|
|
||||||
let thread_id = unsafe { processthreadsapi::GetCurrentThreadId() };
|
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());
|
let (thread_msg_target, thread_msg_sender) = thread_event_target_window(runner_shared.clone());
|
||||||
|
|
||||||
EventLoop {
|
EventLoop {
|
||||||
@@ -201,15 +197,15 @@ impl<T> EventLoop<T> {
|
|||||||
};
|
};
|
||||||
{
|
{
|
||||||
let runner_shared = self.runner_shared.clone();
|
let runner_shared = self.runner_shared.clone();
|
||||||
let mut runner_shared = runner_shared.borrow_mut();
|
let mut runner_ref = runner_shared.runner.borrow_mut();
|
||||||
let mut event_buffer = vec![];
|
loop {
|
||||||
if let ELRSharedOption::Buffer(ref mut buffer) = *runner_shared {
|
let event = runner_shared.buffer.borrow_mut().pop_front();
|
||||||
mem::swap(buffer, &mut event_buffer);
|
match event {
|
||||||
|
Some(e) => unsafe{ runner.process_event(e); },
|
||||||
|
None => break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for event in event_buffer.drain(..) {
|
*runner_ref = Some(&mut runner);
|
||||||
unsafe{ runner.process_event(event); }
|
|
||||||
}
|
|
||||||
*runner_shared = ELRSharedOption::Runner(&mut runner);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -247,7 +243,7 @@ impl<T> EventLoop<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe{ runner.call_event_handler(Event::LoopDestroyed) }
|
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<T> {
|
pub fn create_proxy(&self) -> EventLoopProxy<T> {
|
||||||
@@ -266,10 +262,10 @@ impl<T> EventLoop<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type EventLoopRunnerShared<T> = Rc<RefCell<ELRSharedOption<T>>>;
|
pub(crate) type EventLoopRunnerShared<T> = Rc<ELRShared<T>>;
|
||||||
pub(crate) enum ELRSharedOption<T> {
|
pub(crate) struct ELRShared<T> {
|
||||||
Runner(*mut EventLoopRunner<T>),
|
runner: RefCell<Option<*mut EventLoopRunner<T>>>,
|
||||||
Buffer(Vec<Event<T>>)
|
buffer: RefCell<VecDeque<Event<T>>>
|
||||||
}
|
}
|
||||||
pub(crate) struct EventLoopRunner<T> {
|
pub(crate) struct EventLoopRunner<T> {
|
||||||
event_loop: *const EventLoop<T>,
|
event_loop: *const EventLoop<T>,
|
||||||
@@ -280,6 +276,18 @@ pub(crate) struct EventLoopRunner<T> {
|
|||||||
event_handler: *mut FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow)
|
event_handler: *mut FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> ELRShared<T> {
|
||||||
|
unsafe fn send_event(&self, event: Event<T>) {
|
||||||
|
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)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
enum RunnerState {
|
enum RunnerState {
|
||||||
/// The event loop has just been created, and an `Init` event must be sent.
|
/// 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<T>(
|
|||||||
|
|
||||||
match msg {
|
match msg {
|
||||||
winuser::WM_ENTERSIZEMOVE => {
|
winuser::WM_ENTERSIZEMOVE => {
|
||||||
let runner = subclass_input.event_loop_runner.borrow_mut();
|
let runner = subclass_input.event_loop_runner.runner.borrow_mut();
|
||||||
if let ELRSharedOption::Runner(runner) = *runner {
|
if let Some(runner) = *runner {
|
||||||
(*runner).in_modal_loop = true;
|
(*runner).in_modal_loop = true;
|
||||||
}
|
}
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
winuser::WM_EXITSIZEMOVE => {
|
winuser::WM_EXITSIZEMOVE => {
|
||||||
let runner = subclass_input.event_loop_runner.borrow_mut();
|
let runner = subclass_input.event_loop_runner.runner.borrow_mut();
|
||||||
if let ELRSharedOption::Runner(runner) = *runner {
|
if let Some(runner) = *runner {
|
||||||
(*runner).in_modal_loop = false;
|
(*runner).in_modal_loop = false;
|
||||||
}
|
}
|
||||||
0
|
0
|
||||||
@@ -791,8 +799,8 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
|
|
||||||
_ if msg == *REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID => {
|
_ if msg == *REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID => {
|
||||||
use event::WindowEvent::RedrawRequested;
|
use event::WindowEvent::RedrawRequested;
|
||||||
let runner = subclass_input.event_loop_runner.borrow_mut();
|
let runner = subclass_input.event_loop_runner.runner.borrow_mut();
|
||||||
if let ELRSharedOption::Runner(runner) = *runner {
|
if let Some(runner) = *runner {
|
||||||
let runner = &mut *runner;
|
let runner = &mut *runner;
|
||||||
match runner.runner_state {
|
match runner.runner_state {
|
||||||
RunnerState::Idle(..) |
|
RunnerState::Idle(..) |
|
||||||
@@ -814,8 +822,8 @@ unsafe extern "system" fn public_window_callback<T>(
|
|||||||
|
|
||||||
let mut send_event = false;
|
let mut send_event = false;
|
||||||
{
|
{
|
||||||
let runner = subclass_input.event_loop_runner.borrow_mut();
|
let runner = subclass_input.event_loop_runner.runner.borrow_mut();
|
||||||
if let ELRSharedOption::Runner(runner) = *runner {
|
if let Some(runner) = *runner {
|
||||||
let runner = &mut *runner;
|
let runner = &mut *runner;
|
||||||
match runner.runner_state {
|
match runner.runner_state {
|
||||||
RunnerState::Idle(..) |
|
RunnerState::Idle(..) |
|
||||||
@@ -1502,8 +1510,8 @@ unsafe extern "system" fn thread_event_target_callback<T>(
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
let in_modal_loop = {
|
let in_modal_loop = {
|
||||||
let runner = subclass_input.event_loop_runner.borrow_mut();
|
let runner = subclass_input.event_loop_runner.runner.borrow_mut();
|
||||||
if let ELRSharedOption::Runner(runner) = *runner {
|
if let Some(runner) = *runner {
|
||||||
(*runner).in_modal_loop
|
(*runner).in_modal_loop
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@@ -1537,8 +1545,8 @@ unsafe extern "system" fn thread_event_target_callback<T>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let runner = subclass_input.event_loop_runner.borrow_mut();
|
let runner = subclass_input.event_loop_runner.runner.borrow_mut();
|
||||||
if let ELRSharedOption::Runner(runner) = *runner {
|
if let Some(runner) = *runner {
|
||||||
let runner = &mut *runner;
|
let runner = &mut *runner;
|
||||||
runner.events_cleared();
|
runner.events_cleared();
|
||||||
match runner.control_flow {
|
match runner.control_flow {
|
||||||
|
|||||||
Reference in New Issue
Block a user