add: ActiveEventLoop::create_proxy()

Co-authored-by: Kirill Chibisov <contact@kchibisov.com>
This commit is contained in:
daxpedda 2024-06-29 17:19:09 +02:00 committed by GitHub
parent 2e93e48a3b
commit a0d69c782a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 78 additions and 71 deletions

View file

@ -40,6 +40,10 @@ changelog entry.
## Unreleased ## Unreleased
### Added
- Add `ActiveEventLoop::create_proxy()`.
### Changed ### Changed
- On Web, let events wake up event loop immediately when using `ControlFlow::Poll`. - On Web, let events wake up event loop immediately when using `ControlFlow::Poll`.

View file

@ -247,7 +247,7 @@ impl EventLoop {
/// Creates an [`EventLoopProxy`] that can be used to dispatch user events /// Creates an [`EventLoopProxy`] that can be used to dispatch user events
/// to the main event loop, possibly from another thread. /// to the main event loop, possibly from another thread.
pub fn create_proxy(&self) -> EventLoopProxy { pub fn create_proxy(&self) -> EventLoopProxy {
EventLoopProxy { event_loop_proxy: self.event_loop.create_proxy() } EventLoopProxy { event_loop_proxy: self.event_loop.window_target().p.create_proxy() }
} }
/// Gets a persistent reference to the underlying platform display. /// Gets a persistent reference to the underlying platform display.
@ -345,6 +345,12 @@ impl AsRawFd for EventLoop {
} }
impl ActiveEventLoop { impl ActiveEventLoop {
/// Creates an [`EventLoopProxy`] that can be used to dispatch user events
/// to the main event loop, possibly from another thread.
pub fn create_proxy(&self) -> EventLoopProxy {
EventLoopProxy { event_loop_proxy: self.p.create_proxy() }
}
/// Create the window. /// Create the window.
/// ///
/// Possible causes of error include denied permission, incompatible system, and lack of memory. /// Possible causes of error include denied permission, incompatible system, and lack of memory.

View file

@ -101,7 +101,6 @@ pub struct EventLoop {
android_app: AndroidApp, android_app: AndroidApp,
window_target: event_loop::ActiveEventLoop, window_target: event_loop::ActiveEventLoop,
redraw_flag: SharedFlag, redraw_flag: SharedFlag,
proxy_wake_up: Arc<AtomicBool>,
loop_running: bool, // Dispatched `NewEvents<Init>` loop_running: bool, // Dispatched `NewEvents<Init>`
running: bool, running: bool,
pending_redraw: bool, pending_redraw: bool,
@ -145,11 +144,11 @@ impl EventLoop {
&redraw_flag, &redraw_flag,
android_app.create_waker(), android_app.create_waker(),
), ),
proxy_wake_up,
}, },
_marker: PhantomData, _marker: PhantomData,
}, },
redraw_flag, redraw_flag,
proxy_wake_up,
loop_running: false, loop_running: false,
running: false, running: false,
pending_redraw: false, pending_redraw: false,
@ -278,7 +277,7 @@ impl EventLoop {
}, },
} }
if self.proxy_wake_up.swap(false, Ordering::Relaxed) { if self.window_target.p.proxy_wake_up.swap(false, Ordering::Relaxed) {
app.proxy_wake_up(self.window_target()); app.proxy_wake_up(self.window_target());
} }
@ -485,7 +484,7 @@ impl EventLoop {
self.pending_redraw |= self.redraw_flag.get_and_reset(); self.pending_redraw |= self.redraw_flag.get_and_reset();
timeout = if self.running timeout = if self.running
&& (self.pending_redraw || self.proxy_wake_up.load(Ordering::Relaxed)) && (self.pending_redraw || self.window_target.p.proxy_wake_up.load(Ordering::Relaxed))
{ {
// If we already have work to do then we don't want to block on the next poll // If we already have work to do then we don't want to block on the next poll
Some(Duration::ZERO) Some(Duration::ZERO)
@ -517,7 +516,8 @@ impl EventLoop {
// We also ignore wake ups while suspended. // We also ignore wake ups while suspended.
self.pending_redraw |= self.redraw_flag.get_and_reset(); self.pending_redraw |= self.redraw_flag.get_and_reset();
if !self.running if !self.running
|| (!self.pending_redraw && !self.proxy_wake_up.load(Ordering::Relaxed)) || (!self.pending_redraw
&& !self.window_target.p.proxy_wake_up.load(Ordering::Relaxed))
{ {
return; return;
} }
@ -551,13 +551,6 @@ impl EventLoop {
&self.window_target &self.window_target
} }
pub fn create_proxy(&self) -> EventLoopProxy {
EventLoopProxy {
proxy_wake_up: self.proxy_wake_up.clone(),
waker: self.android_app.create_waker(),
}
}
fn control_flow(&self) -> ControlFlow { fn control_flow(&self) -> ControlFlow {
self.window_target.p.control_flow() self.window_target.p.control_flow()
} }
@ -585,9 +578,14 @@ pub struct ActiveEventLoop {
control_flow: Cell<ControlFlow>, control_flow: Cell<ControlFlow>,
exit: Cell<bool>, exit: Cell<bool>,
redraw_requester: RedrawRequester, redraw_requester: RedrawRequester,
proxy_wake_up: Arc<AtomicBool>,
} }
impl ActiveEventLoop { impl ActiveEventLoop {
pub fn create_proxy(&self) -> EventLoopProxy {
EventLoopProxy { proxy_wake_up: self.proxy_wake_up.clone(), waker: self.app.create_waker() }
}
pub fn primary_monitor(&self) -> Option<MonitorHandle> { pub fn primary_monitor(&self) -> Option<MonitorHandle> {
Some(MonitorHandle::new(self.app.clone())) Some(MonitorHandle::new(self.app.clone()))
} }

View file

@ -80,13 +80,12 @@ impl ApplicationDelegate {
pub(super) fn new( pub(super) fn new(
mtm: MainThreadMarker, mtm: MainThreadMarker,
activation_policy: NSApplicationActivationPolicy, activation_policy: NSApplicationActivationPolicy,
proxy_wake_up: Arc<AtomicBool>,
default_menu: bool, default_menu: bool,
activate_ignoring_other_apps: bool, activate_ignoring_other_apps: bool,
) -> Retained<Self> { ) -> Retained<Self> {
let this = mtm.alloc().set_ivars(AppState { let this = mtm.alloc().set_ivars(AppState {
activation_policy, activation_policy,
proxy_wake_up, proxy_wake_up: Arc::new(AtomicBool::new(false)),
default_menu, default_menu,
activate_ignoring_other_apps, activate_ignoring_other_apps,
run_loop: RunLoop::main(mtm), run_loop: RunLoop::main(mtm),
@ -179,6 +178,10 @@ impl ApplicationDelegate {
self.ivars().event_handler.set(handler, closure) self.ivars().event_handler.set(handler, closure)
} }
pub fn proxy_wake_up(&self) -> Arc<AtomicBool> {
self.ivars().proxy_wake_up.clone()
}
/// If `pump_events` is called to progress the event loop then we /// If `pump_events` is called to progress the event loop then we
/// bootstrap the event loop via `-[NSApplication run]` but will use /// bootstrap the event loop via `-[NSApplication run]` but will use
/// `CFRunLoopRunInMode` for subsequent calls to `pump_events`. /// `CFRunLoopRunInMode` for subsequent calls to `pump_events`.

View file

@ -71,6 +71,10 @@ pub struct ActiveEventLoop {
} }
impl ActiveEventLoop { impl ActiveEventLoop {
pub fn create_proxy(&self) -> EventLoopProxy {
EventLoopProxy::new(self.delegate.proxy_wake_up())
}
pub(super) fn new_root(delegate: Retained<ApplicationDelegate>) -> RootWindowTarget { pub(super) fn new_root(delegate: Retained<ApplicationDelegate>) -> RootWindowTarget {
let mtm = MainThreadMarker::from(&*delegate); let mtm = MainThreadMarker::from(&*delegate);
let p = Self { delegate, mtm }; let p = Self { delegate, mtm };
@ -166,8 +170,6 @@ pub struct EventLoop {
/// keep it around here as well. /// keep it around here as well.
delegate: Retained<ApplicationDelegate>, delegate: Retained<ApplicationDelegate>,
proxy_wake_up: Arc<AtomicBool>,
window_target: RootWindowTarget, window_target: RootWindowTarget,
panic_info: Rc<PanicInfo>, panic_info: Rc<PanicInfo>,
} }
@ -212,12 +214,9 @@ impl EventLoop {
ActivationPolicy::Prohibited => NSApplicationActivationPolicy::Prohibited, ActivationPolicy::Prohibited => NSApplicationActivationPolicy::Prohibited,
}; };
let proxy_wake_up = Arc::new(AtomicBool::new(false));
let delegate = ApplicationDelegate::new( let delegate = ApplicationDelegate::new(
mtm, mtm,
activation_policy, activation_policy,
proxy_wake_up.clone(),
attributes.default_menu, attributes.default_menu,
attributes.activate_ignoring_other_apps, attributes.activate_ignoring_other_apps,
); );
@ -236,7 +235,6 @@ impl EventLoop {
p: ActiveEventLoop { delegate, mtm }, p: ActiveEventLoop { delegate, mtm },
_marker: PhantomData, _marker: PhantomData,
}, },
proxy_wake_up,
panic_info, panic_info,
}) })
} }
@ -358,10 +356,6 @@ impl EventLoop {
}) })
}) })
} }
pub fn create_proxy(&self) -> EventLoopProxy {
EventLoopProxy::new(self.proxy_wake_up.clone())
}
} }
#[derive(Clone)] #[derive(Clone)]

View file

@ -3,6 +3,7 @@
use std::cell::{RefCell, RefMut}; use std::cell::{RefCell, RefMut};
use std::collections::HashSet; use std::collections::HashSet;
use std::os::raw::c_void; use std::os::raw::c_void;
use std::sync::atomic::AtomicBool;
use std::sync::{Arc, Mutex, OnceLock}; use std::sync::{Arc, Mutex, OnceLock};
use std::time::Instant; use std::time::Instant;
use std::{fmt, mem, ptr}; use std::{fmt, mem, ptr};
@ -135,6 +136,7 @@ pub(crate) struct AppState {
app_state: Option<AppStateImpl>, app_state: Option<AppStateImpl>,
control_flow: ControlFlow, control_flow: ControlFlow,
waker: EventLoopWaker, waker: EventLoopWaker,
proxy_wake_up: Arc<AtomicBool>,
} }
impl AppState { impl AppState {
@ -158,6 +160,7 @@ impl AppState {
}), }),
control_flow: ControlFlow::default(), control_flow: ControlFlow::default(),
waker, waker,
proxy_wake_up: Arc::new(AtomicBool::new(false)),
}); });
} }
init_guard(&mut guard); init_guard(&mut guard);
@ -402,6 +405,10 @@ impl AppState {
} }
} }
pub(crate) fn proxy_wake_up(&self) -> Arc<AtomicBool> {
self.proxy_wake_up.clone()
}
pub(crate) fn set_control_flow(&mut self, control_flow: ControlFlow) { pub(crate) fn set_control_flow(&mut self, control_flow: ControlFlow) {
self.control_flow = control_flow; self.control_flow = control_flow;
} }

View file

@ -34,6 +34,10 @@ pub struct ActiveEventLoop {
} }
impl ActiveEventLoop { impl ActiveEventLoop {
pub fn create_proxy(&self) -> EventLoopProxy {
EventLoopProxy::new(AppState::get_mut(self.mtm).proxy_wake_up())
}
pub fn create_custom_cursor(&self, source: CustomCursorSource) -> CustomCursor { pub fn create_custom_cursor(&self, source: CustomCursorSource) -> CustomCursor {
let _ = source.inner; let _ = source.inner;
CustomCursor { inner: super::PlatformCustomCursor } CustomCursor { inner: super::PlatformCustomCursor }
@ -134,7 +138,6 @@ fn map_user_event<A: ApplicationHandler>(
pub struct EventLoop { pub struct EventLoop {
mtm: MainThreadMarker, mtm: MainThreadMarker,
proxy_wake_up: Arc<AtomicBool>,
window_target: RootActiveEventLoop, window_target: RootActiveEventLoop,
} }
@ -160,11 +163,8 @@ impl EventLoop {
// this line sets up the main run loop before `UIApplicationMain` // this line sets up the main run loop before `UIApplicationMain`
setup_control_flow_observers(); setup_control_flow_observers();
let proxy_wake_up = Arc::new(AtomicBool::new(false));
Ok(EventLoop { Ok(EventLoop {
mtm, mtm,
proxy_wake_up,
window_target: RootActiveEventLoop { p: ActiveEventLoop { mtm }, _marker: PhantomData }, window_target: RootActiveEventLoop { p: ActiveEventLoop { mtm }, _marker: PhantomData },
}) })
} }
@ -179,7 +179,7 @@ impl EventLoop {
`EventLoop::run_app` calls `UIApplicationMain` on iOS", `EventLoop::run_app` calls `UIApplicationMain` on iOS",
); );
let handler = map_user_event(app, self.proxy_wake_up.clone()); let handler = map_user_event(app, AppState::get_mut(self.mtm).proxy_wake_up());
let handler = unsafe { let handler = unsafe {
std::mem::transmute::< std::mem::transmute::<
@ -212,10 +212,6 @@ impl EventLoop {
unreachable!() unreachable!()
} }
pub fn create_proxy(&self) -> EventLoopProxy {
EventLoopProxy::new(self.proxy_wake_up.clone())
}
pub fn window_target(&self) -> &RootActiveEventLoop { pub fn window_target(&self) -> &RootActiveEventLoop {
&self.window_target &self.window_target
} }

View file

@ -789,10 +789,6 @@ impl EventLoop {
} }
} }
pub fn create_proxy(&self) -> EventLoopProxy {
x11_or_wayland!(match self; EventLoop(evlp) => evlp.create_proxy(); as EventLoopProxy)
}
pub fn run_app<A: ApplicationHandler>(self, app: &mut A) -> Result<(), EventLoopError> { pub fn run_app<A: ApplicationHandler>(self, app: &mut A) -> Result<(), EventLoopError> {
x11_or_wayland!(match self; EventLoop(evlp) => evlp.run_app(app)) x11_or_wayland!(match self; EventLoop(evlp) => evlp.run_app(app))
} }
@ -843,6 +839,10 @@ pub enum ActiveEventLoop {
} }
impl ActiveEventLoop { impl ActiveEventLoop {
pub fn create_proxy(&self) -> EventLoopProxy {
x11_or_wayland!(match self; ActiveEventLoop(evlp) => evlp.create_proxy(); as EventLoopProxy)
}
#[inline] #[inline]
pub fn is_wayland(&self) -> bool { pub fn is_wayland(&self) -> bool {
match *self { match *self {

View file

@ -47,9 +47,6 @@ pub struct EventLoop {
compositor_updates: Vec<WindowCompositorUpdate>, compositor_updates: Vec<WindowCompositorUpdate>,
window_ids: Vec<WindowId>, window_ids: Vec<WindowId>,
/// Event loop proxy
event_loop_proxy: EventLoopProxy,
/// The Wayland dispatcher to has raw access to the queue when needed, such as /// The Wayland dispatcher to has raw access to the queue when needed, such as
/// when creating a new window. /// when creating a new window.
wayland_dispatcher: WaylandDispatcher, wayland_dispatcher: WaylandDispatcher,
@ -139,6 +136,7 @@ impl EventLoop {
connection: connection.clone(), connection: connection.clone(),
wayland_dispatcher: wayland_dispatcher.clone(), wayland_dispatcher: wayland_dispatcher.clone(),
event_loop_awakener, event_loop_awakener,
event_loop_proxy: EventLoopProxy::new(ping),
queue_handle, queue_handle,
control_flow: Cell::new(ControlFlow::default()), control_flow: Cell::new(ControlFlow::default()),
exit: Cell::new(None), exit: Cell::new(None),
@ -152,7 +150,6 @@ impl EventLoop {
window_ids: Vec::new(), window_ids: Vec::new(),
connection, connection,
wayland_dispatcher, wayland_dispatcher,
event_loop_proxy: EventLoopProxy::new(ping),
event_loop, event_loop,
window_target: RootActiveEventLoop { window_target: RootActiveEventLoop {
p: PlatformActiveEventLoop::Wayland(window_target), p: PlatformActiveEventLoop::Wayland(window_target),
@ -512,11 +509,6 @@ impl EventLoop {
std::mem::swap(&mut self.window_ids, &mut window_ids); std::mem::swap(&mut self.window_ids, &mut window_ids);
} }
#[inline]
pub fn create_proxy(&self) -> EventLoopProxy {
self.event_loop_proxy.clone()
}
#[inline] #[inline]
pub fn window_target(&self) -> &RootActiveEventLoop { pub fn window_target(&self) -> &RootActiveEventLoop {
&self.window_target &self.window_target
@ -589,6 +581,9 @@ impl AsRawFd for EventLoop {
} }
pub struct ActiveEventLoop { pub struct ActiveEventLoop {
/// Event loop proxy
event_loop_proxy: EventLoopProxy,
/// The event loop wakeup source. /// The event loop wakeup source.
pub event_loop_awakener: calloop::ping::Ping, pub event_loop_awakener: calloop::ping::Ping,
@ -613,6 +608,10 @@ pub struct ActiveEventLoop {
} }
impl ActiveEventLoop { impl ActiveEventLoop {
pub(crate) fn create_proxy(&self) -> EventLoopProxy {
self.event_loop_proxy.clone()
}
pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) { pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) {
self.control_flow.set(control_flow) self.control_flow.set(control_flow)
} }

View file

@ -137,6 +137,7 @@ pub struct ActiveEventLoop {
windows: RefCell<HashMap<WindowId, Weak<UnownedWindow>>>, windows: RefCell<HashMap<WindowId, Weak<UnownedWindow>>>,
redraw_sender: WakeSender<WindowId>, redraw_sender: WakeSender<WindowId>,
activation_sender: WakeSender<ActivationToken>, activation_sender: WakeSender<ActivationToken>,
event_loop_proxy: EventLoopProxy,
device_events: Cell<DeviceEvents>, device_events: Cell<DeviceEvents>,
} }
@ -146,7 +147,6 @@ pub struct EventLoop {
event_processor: EventProcessor, event_processor: EventProcessor,
redraw_receiver: PeekableReceiver<WindowId>, redraw_receiver: PeekableReceiver<WindowId>,
activation_receiver: PeekableReceiver<ActivationToken>, activation_receiver: PeekableReceiver<ActivationToken>,
event_loop_proxy: EventLoopProxy,
/// The current state of the event loop. /// The current state of the event loop.
state: EventLoopState, state: EventLoopState,
@ -302,6 +302,7 @@ impl EventLoop {
sender: activation_token_sender, // not used again so no clone sender: activation_token_sender, // not used again so no clone
waker: waker.clone(), waker: waker.clone(),
}, },
event_loop_proxy,
device_events: Default::default(), device_events: Default::default(),
}; };
@ -360,15 +361,10 @@ impl EventLoop {
event_processor, event_processor,
redraw_receiver: PeekableReceiver::from_recv(redraw_channel), redraw_receiver: PeekableReceiver::from_recv(redraw_channel),
activation_receiver: PeekableReceiver::from_recv(activation_token_channel), activation_receiver: PeekableReceiver::from_recv(activation_token_channel),
event_loop_proxy,
state: EventLoopState { x11_readiness: Readiness::EMPTY, proxy_wake_up: false }, state: EventLoopState { x11_readiness: Readiness::EMPTY, proxy_wake_up: false },
} }
} }
pub fn create_proxy(&self) -> EventLoopProxy {
self.event_loop_proxy.clone()
}
pub(crate) fn window_target(&self) -> &RootAEL { pub(crate) fn window_target(&self) -> &RootAEL {
&self.event_processor.target &self.event_processor.target
} }
@ -629,6 +625,10 @@ impl AsRawFd for EventLoop {
} }
impl ActiveEventLoop { impl ActiveEventLoop {
pub fn create_proxy(&self) -> EventLoopProxy {
self.event_loop_proxy.clone()
}
/// Returns the `XConnection` of this events loop. /// Returns the `XConnection` of this events loop.
#[inline] #[inline]
pub(crate) fn x_connection(&self) -> &Arc<XConnection> { pub(crate) fn x_connection(&self) -> &Arc<XConnection> {

View file

@ -275,7 +275,6 @@ impl EventState {
pub struct EventLoop { pub struct EventLoop {
windows: Vec<(Arc<RedoxSocket>, EventState)>, windows: Vec<(Arc<RedoxSocket>, EventState)>,
window_target: event_loop::ActiveEventLoop, window_target: event_loop::ActiveEventLoop,
user_events_sender: mpsc::SyncSender<()>,
user_events_receiver: mpsc::Receiver<()>, user_events_receiver: mpsc::Receiver<()>,
} }
@ -317,10 +316,10 @@ impl EventLoop {
destroys: Arc::new(Mutex::new(VecDeque::new())), destroys: Arc::new(Mutex::new(VecDeque::new())),
event_socket, event_socket,
wake_socket, wake_socket,
user_events_sender,
}, },
_marker: PhantomData, _marker: PhantomData,
}, },
user_events_sender,
user_events_receiver, user_events_receiver,
}) })
} }
@ -684,13 +683,6 @@ impl EventLoop {
pub fn window_target(&self) -> &event_loop::ActiveEventLoop { pub fn window_target(&self) -> &event_loop::ActiveEventLoop {
&self.window_target &self.window_target
} }
pub fn create_proxy(&self) -> EventLoopProxy {
EventLoopProxy {
user_events_sender: self.user_events_sender.clone(),
wake_socket: self.window_target.p.wake_socket.clone(),
}
}
} }
pub struct EventLoopProxy { pub struct EventLoopProxy {
@ -727,9 +719,17 @@ pub struct ActiveEventLoop {
pub(super) destroys: Arc<Mutex<VecDeque<WindowId>>>, pub(super) destroys: Arc<Mutex<VecDeque<WindowId>>>,
pub(super) event_socket: Arc<RedoxSocket>, pub(super) event_socket: Arc<RedoxSocket>,
pub(super) wake_socket: Arc<TimeSocket>, pub(super) wake_socket: Arc<TimeSocket>,
user_events_sender: mpsc::SyncSender<()>,
} }
impl ActiveEventLoop { impl ActiveEventLoop {
pub fn create_proxy(&self) -> EventLoopProxy {
EventLoopProxy {
user_events_sender: self.user_events_sender.clone(),
wake_socket: self.wake_socket.clone(),
}
}
pub fn create_custom_cursor(&self, source: CustomCursorSource) -> RootCustomCursor { pub fn create_custom_cursor(&self, source: CustomCursorSource) -> RootCustomCursor {
let _ = source.inner; let _ = source.inner;
RootCustomCursor { inner: super::PlatformCustomCursor } RootCustomCursor { inner: super::PlatformCustomCursor }

View file

@ -58,10 +58,6 @@ impl EventLoop {
self.elw.p.run(Box::new(move |event| handle_event(&mut app, &target, event)), true); self.elw.p.run(Box::new(move |event| handle_event(&mut app, &target, event)), true);
} }
pub fn create_proxy(&self) -> EventLoopProxy {
EventLoopProxy::new(self.elw.p.waker())
}
pub fn window_target(&self) -> &RootActiveEventLoop { pub fn window_target(&self) -> &RootActiveEventLoop {
&self.elw &self.elw
} }

View file

@ -12,7 +12,7 @@ use super::super::KeyEventExtra;
use super::device::DeviceId; use super::device::DeviceId;
use super::runner::{EventWrapper, Execution}; use super::runner::{EventWrapper, Execution};
use super::window::WindowId; use super::window::WindowId;
use super::{backend, runner}; use super::{backend, runner, EventLoopProxy};
use crate::event::{ use crate::event::{
DeviceId as RootDeviceId, ElementState, Event, KeyEvent, Touch, TouchPhase, WindowEvent, DeviceId as RootDeviceId, ElementState, Event, KeyEvent, Touch, TouchPhase, WindowEvent,
}; };
@ -68,6 +68,10 @@ impl ActiveEventLoop {
WindowId(self.runner.generate_id()) WindowId(self.runner.generate_id())
} }
pub fn create_proxy(&self) -> EventLoopProxy {
EventLoopProxy::new(self.waker())
}
pub fn create_custom_cursor(&self, source: CustomCursorSource) -> RootCustomCursor { pub fn create_custom_cursor(&self, source: CustomCursorSource) -> RootCustomCursor {
RootCustomCursor { inner: CustomCursor::new(self, source.inner) } RootCustomCursor { inner: CustomCursor::new(self, source.inner) }
} }

View file

@ -468,16 +468,16 @@ impl EventLoop {
} }
} }
pub fn create_proxy(&self) -> EventLoopProxy {
EventLoopProxy { target_window: self.window_target.p.thread_msg_target }
}
fn exit_code(&self) -> Option<i32> { fn exit_code(&self) -> Option<i32> {
self.window_target.p.exit_code() self.window_target.p.exit_code()
} }
} }
impl ActiveEventLoop { impl ActiveEventLoop {
pub fn create_proxy(&self) -> EventLoopProxy {
EventLoopProxy { target_window: self.thread_msg_target }
}
#[inline(always)] #[inline(always)]
pub(crate) fn create_thread_executor(&self) -> EventLoopThreadExecutor { pub(crate) fn create_thread_executor(&self) -> EventLoopThreadExecutor {
EventLoopThreadExecutor { thread_id: self.thread_id, target_window: self.thread_msg_target } EventLoopThreadExecutor { thread_id: self.thread_id, target_window: self.thread_msg_target }