diff --git a/src/platform_impl/orbital/event_loop.rs b/src/platform_impl/orbital/event_loop.rs index 1f39c8adbb9..c374b4ec30f 100644 --- a/src/platform_impl/orbital/event_loop.rs +++ b/src/platform_impl/orbital/event_loop.rs @@ -1,4 +1,5 @@ use std::{ + cell::Cell, collections::VecDeque, mem, slice, sync::{mpsc, Arc, Mutex}, @@ -14,7 +15,7 @@ use raw_window_handle::{OrbitalDisplayHandle, RawDisplayHandle}; use crate::{ error::EventLoopError, event::{self, Ime, Modifiers, StartCause}, - event_loop::{self, ControlFlow}, + event_loop, keyboard::{ Key, KeyCode, KeyLocation, ModifiersKeys, ModifiersState, NativeKey, NativeKeyCode, }, @@ -298,6 +299,7 @@ impl EventLoop { windows: Vec::new(), window_target: event_loop::EventLoopWindowTarget { p: EventLoopWindowTarget { + control_flow: Cell::new(ControlFlow::default()), user_events_sender, user_events_receiver, creates: Mutex::new(VecDeque::new()), @@ -454,40 +456,21 @@ impl EventLoop { pub fn run(mut self, mut event_handler_inner: F) -> Result<(), EventLoopError> where - F: FnMut(event::Event, &event_loop::EventLoopWindowTarget, &mut ControlFlow), + F: FnMut(event::Event, &event_loop::EventLoopWindowTarget), { // Wrapper for event handler function that prevents ExitWithCode from being unset. let mut event_handler = - move |event: event::Event, - window_target: &event_loop::EventLoopWindowTarget, - control_flow: &mut ControlFlow| { - if let ControlFlow::ExitWithCode(code) = control_flow { - event_handler_inner( - event, - window_target, - &mut ControlFlow::ExitWithCode(*code), - ); - } else { - event_handler_inner(event, window_target, control_flow); - } + move |event: event::Event, window_target: &event_loop::EventLoopWindowTarget| { + event_handler_inner(event, window_target); }; - let mut control_flow = ControlFlow::default(); let mut start_cause = StartCause::Init; - let code = loop { - event_handler( - event::Event::NewEvents(start_cause), - &self.window_target, - &mut control_flow, - ); + loop { + event_handler(event::Event::NewEvents(start_cause), &self.window_target); if start_cause == StartCause::Init { - event_handler( - event::Event::Resumed, - &self.window_target, - &mut control_flow, - ); + event_handler(event::Event::Resumed, &self.window_target); } // Handle window creates. @@ -512,7 +495,6 @@ impl EventLoop { event: event::WindowEvent::Resized((properties.w, properties.h).into()), }, &self.window_target, - &mut control_flow, ); // Send resize event on create to indicate first position. @@ -522,7 +504,6 @@ impl EventLoop { event: event::WindowEvent::Moved((properties.x, properties.y).into()), }, &self.window_target, - &mut control_flow, ); } @@ -537,7 +518,6 @@ impl EventLoop { event: event::WindowEvent::Destroyed, }, &self.window_target, - &mut control_flow, ); self.windows @@ -568,7 +548,7 @@ impl EventLoop { window_id, orbital_event.to_option(), event_state, - |event| event_handler(event, &self.window_target, &mut control_flow), + |event| event_handler(event, &self.window_target), ); } @@ -595,11 +575,7 @@ impl EventLoop { } while let Ok(event) = self.window_target.p.user_events_receiver.try_recv() { - event_handler( - event::Event::UserEvent(event), - &self.window_target, - &mut control_flow, - ); + event_handler(event::Event::UserEvent(event), &self.window_target); } // To avoid deadlocks the redraws lock is not held during event processing. @@ -613,24 +589,19 @@ impl EventLoop { event: event::WindowEvent::RedrawRequested, }, &self.window_target, - &mut control_flow, ); } - event_handler( - event::Event::AboutToWait, - &self.window_target, - &mut control_flow, - ); + event_handler(event::Event::AboutToWait, &self.window_target); - let requested_resume = match control_flow { + let requested_resume = match self.window_target.p.control_flow() { ControlFlow::Poll => { start_cause = StartCause::Poll; continue; } ControlFlow::Wait => None, ControlFlow::WaitUntil(instant) => Some(instant), - ControlFlow::ExitWithCode(code) => break code, + ControlFlow::Exit => break, }; // Re-using wake socket caused extra wake events before because there were leftover @@ -686,19 +657,11 @@ impl EventLoop { }; } } - }; + } - event_handler( - event::Event::LoopExiting, - &self.window_target, - &mut control_flow, - ); + event_handler(event::Event::LoopExiting, &self.window_target); - if code == 0 { - Ok(()) - } else { - Err(EventLoopError::ExitFailure(code)) - } + Ok(()) } pub fn window_target(&self) -> &event_loop::EventLoopWindowTarget { @@ -742,6 +705,7 @@ impl Clone for EventLoopProxy { impl Unpin for EventLoopProxy {} pub struct EventLoopWindowTarget { + control_flow: Cell, pub(super) user_events_sender: mpsc::Sender, pub(super) user_events_receiver: mpsc::Receiver, pub(super) creates: Mutex>>, @@ -765,4 +729,46 @@ impl EventLoopWindowTarget { pub fn raw_display_handle(&self) -> RawDisplayHandle { RawDisplayHandle::Orbital(OrbitalDisplayHandle::empty()) } + + fn control_flow(&self) -> ControlFlow { + self.control_flow.get() + } + + fn set_control_flow(&self, control_flow: ControlFlow) { + if let ControlFlow::Exit = self.control_flow.get() { + } else { + self.control_flow.set(control_flow) + } + } + + pub(crate) fn set_poll(&self) { + self.set_control_flow(ControlFlow::Poll) + } + + pub(crate) fn set_wait(&self) { + self.set_control_flow(ControlFlow::Wait) + } + + pub(crate) fn set_wait_until(&self, instant: Instant) { + self.set_control_flow(ControlFlow::WaitUntil(instant)) + } + + pub(crate) fn set_exit(&self) { + self.set_control_flow(ControlFlow::Exit) + } +} + +#[derive(Clone, Copy)] +pub(crate) enum ControlFlow { + Poll, + Wait, + WaitUntil(Instant), + Exit, +} + +impl Default for ControlFlow { + #[inline(always)] + fn default() -> Self { + Self::Poll + } }