Move ControlFlow to EventLoopWindowTarget

Fixes #3042.
This commit is contained in:
daxpedda 2023-09-07 08:25:04 +02:00 committed by GitHub
parent 8fdd81ecef
commit e648169861
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 800 additions and 860 deletions

View file

@ -250,14 +250,14 @@ impl<T: 'static> EventLoop<T> {
pub fn run<F>(mut self, event_handler: F) -> Result<(), EventLoopError>
where
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
F: FnMut(Event<T>, &RootELW<T>),
{
self.run_ondemand(event_handler)
}
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), EventLoopError>
where
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
F: FnMut(Event<T>, &RootELW<T>),
{
{
let runner = &self.window_target.p.runner_shared;
@ -270,18 +270,20 @@ impl<T: 'static> EventLoop<T> {
// We make sure to call runner.clear_event_handler() before
// returning
unsafe {
runner.set_event_handler(move |event, control_flow| {
event_handler(event, event_loop_windows_ref, control_flow)
});
runner.set_event_handler(move |event| event_handler(event, event_loop_windows_ref));
}
}
let exit_code = loop {
if let ControlFlow::ExitWithCode(code) = self.wait_and_dispatch_message(None) {
self.wait_and_dispatch_message(None);
if let Some(code) = self.exit_code() {
break code;
}
if let ControlFlow::ExitWithCode(code) = self.dispatch_peeked_messages() {
self.dispatch_peeked_messages();
if let Some(code) = self.exit_code() {
break code;
}
};
@ -303,7 +305,7 @@ impl<T: 'static> EventLoop<T> {
pub fn pump_events<F>(&mut self, timeout: Option<Duration>, mut event_handler: F) -> PumpStatus
where
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
F: FnMut(Event<T>, &RootELW<T>),
{
{
let runner = &self.window_target.p.runner_shared;
@ -317,23 +319,20 @@ impl<T: 'static> EventLoop<T> {
// to leave the runner in an unsound state with an associated
// event handler.
unsafe {
runner.set_event_handler(move |event, control_flow| {
event_handler(event, event_loop_windows_ref, control_flow)
});
runner.set_event_handler(move |event| event_handler(event, event_loop_windows_ref));
runner.wakeup();
}
}
if !matches!(
self.wait_and_dispatch_message(timeout),
ControlFlow::ExitWithCode(_)
) {
self.wait_and_dispatch_message(timeout);
if self.exit_code().is_none() {
self.dispatch_peeked_messages();
}
let runner = &self.window_target.p.runner_shared;
let status = if let ControlFlow::ExitWithCode(code) = runner.control_flow() {
let status = if let Some(code) = runner.exit_code() {
runner.loop_destroyed();
// Immediately reset the internal state for the loop to allow
@ -357,7 +356,7 @@ impl<T: 'static> EventLoop<T> {
}
/// Wait for one message and dispatch it, optionally with a timeout
fn wait_and_dispatch_message(&mut self, timeout: Option<Duration>) -> ControlFlow {
fn wait_and_dispatch_message(&mut self, timeout: Option<Duration>) {
let start = Instant::now();
let runner = &self.window_target.p.runner_shared;
@ -368,7 +367,6 @@ impl<T: 'static> EventLoop<T> {
ControlFlow::WaitUntil(wait_deadline) => {
Some(wait_deadline.saturating_duration_since(start))
}
ControlFlow::ExitWithCode(_code) => unreachable!(),
};
let timeout = min_timeout(control_flow_timeout, timeout);
@ -432,8 +430,7 @@ impl<T: 'static> EventLoop<T> {
match msg_status {
None => {} // No MSG to dispatch
Some(PumpStatus::Exit(code)) => {
runner.set_exit_control_flow(code);
return runner.control_flow();
runner.set_exit_code(code);
}
Some(PumpStatus::Continue) => {
unsafe {
@ -454,12 +451,10 @@ impl<T: 'static> EventLoop<T> {
}
}
}
runner.control_flow()
}
/// Dispatch all queued messages via `PeekMessageW`
fn dispatch_peeked_messages(&mut self) -> ControlFlow {
fn dispatch_peeked_messages(&mut self) {
let runner = &self.window_target.p.runner_shared;
// We generally want to continue dispatching all pending messages
@ -476,8 +471,6 @@ impl<T: 'static> EventLoop<T> {
// is the simplest way avoid unitialized memory in Rust
let mut msg = unsafe { mem::zeroed() };
let mut control_flow = runner.control_flow();
loop {
unsafe {
if PeekMessageW(&mut msg, 0, 0, 0, PM_REMOVE) == false.into() {
@ -500,8 +493,7 @@ impl<T: 'static> EventLoop<T> {
panic::resume_unwind(payload);
}
control_flow = runner.control_flow();
if let ControlFlow::ExitWithCode(_code) = control_flow {
if let Some(_code) = runner.exit_code() {
break;
}
@ -509,8 +501,6 @@ impl<T: 'static> EventLoop<T> {
break;
}
}
control_flow
}
pub fn create_proxy(&self) -> EventLoopProxy<T> {
@ -519,6 +509,10 @@ impl<T: 'static> EventLoop<T> {
event_send: self.thread_msg_sender.clone(),
}
}
fn exit_code(&self) -> Option<i32> {
self.window_target.p.exit_code()
}
}
impl<T> EventLoopWindowTarget<T> {
@ -547,6 +541,26 @@ impl<T> EventLoopWindowTarget<T> {
pub fn listen_device_events(&self, allowed: DeviceEvents) {
raw_input::register_all_mice_and_keyboards_for_raw_input(self.thread_msg_target, allowed);
}
pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) {
self.runner_shared.set_control_flow(control_flow)
}
pub(crate) fn control_flow(&self) -> ControlFlow {
self.runner_shared.control_flow()
}
pub(crate) fn exit(&self) {
self.runner_shared.set_exit_code(0)
}
pub(crate) fn exiting(&self) -> bool {
self.runner_shared.exit_code().is_some()
}
fn exit_code(&self) -> Option<i32> {
self.runner_shared.exit_code()
}
}
/// Returns the id of the main thread.