api: make EventLoopProxy wrap an opaque type
The proxy is intended to be Clone, thus use `Arc` for it internally and don't require backends for it to be `Clone`. Use `EventLoopProxyProvider` to hide the backend's proxy implementation details. Co-authored-by: daxpedda <daxpedda@gmail.com>
This commit is contained in:
parent
ae4c449670
commit
3a60cbaba5
24 changed files with 256 additions and 307 deletions
|
|
@ -1,7 +1,7 @@
|
|||
use std::cell::{Cell, OnceCell, RefCell};
|
||||
use std::mem;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
|
||||
use std::sync::atomic::Ordering as AtomicOrdering;
|
||||
use std::sync::Arc;
|
||||
use std::time::Instant;
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ use objc2_app_kit::{NSApplication, NSApplicationActivationPolicy};
|
|||
use objc2_foundation::{MainThreadMarker, NSNotification};
|
||||
|
||||
use super::super::event_handler::EventHandler;
|
||||
use super::event_loop::{stop_app_immediately, ActiveEventLoop, PanicInfo};
|
||||
use super::event_loop::{stop_app_immediately, ActiveEventLoop, EventLoopProxy, PanicInfo};
|
||||
use super::menu;
|
||||
use super::observer::{EventLoopWaker, RunLoop};
|
||||
use crate::application::ApplicationHandler;
|
||||
|
|
@ -24,7 +24,7 @@ pub(super) struct AppState {
|
|||
default_menu: bool,
|
||||
activate_ignoring_other_apps: bool,
|
||||
run_loop: RunLoop,
|
||||
proxy_wake_up: Arc<AtomicBool>,
|
||||
event_loop_proxy: Arc<EventLoopProxy>,
|
||||
event_handler: EventHandler,
|
||||
stop_on_launch: Cell<bool>,
|
||||
stop_before_wait: Cell<bool>,
|
||||
|
|
@ -72,7 +72,7 @@ impl AppState {
|
|||
let this = Rc::new(AppState {
|
||||
mtm,
|
||||
activation_policy,
|
||||
proxy_wake_up: Arc::new(AtomicBool::new(false)),
|
||||
event_loop_proxy: Arc::new(EventLoopProxy::new()),
|
||||
default_menu,
|
||||
activate_ignoring_other_apps,
|
||||
run_loop: RunLoop::main(mtm),
|
||||
|
|
@ -165,8 +165,8 @@ impl AppState {
|
|||
self.event_handler.set(handler, closure)
|
||||
}
|
||||
|
||||
pub fn proxy_wake_up(&self) -> Arc<AtomicBool> {
|
||||
self.proxy_wake_up.clone()
|
||||
pub fn event_loop_proxy(&self) -> &Arc<EventLoopProxy> {
|
||||
&self.event_loop_proxy
|
||||
}
|
||||
|
||||
/// If `pump_events` is called to progress the event loop then we
|
||||
|
|
@ -350,7 +350,7 @@ impl AppState {
|
|||
return;
|
||||
}
|
||||
|
||||
if self.proxy_wake_up.swap(false, AtomicOrdering::Relaxed) {
|
||||
if self.event_loop_proxy.wake_up.swap(false, AtomicOrdering::Relaxed) {
|
||||
self.with_handler(|app, event_loop| app.proxy_wake_up(event_loop));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ use std::panic::{catch_unwind, resume_unwind, RefUnwindSafe, UnwindSafe};
|
|||
use std::ptr;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use core_foundation::base::{CFIndex, CFRelease};
|
||||
|
|
@ -32,7 +31,8 @@ use crate::application::ApplicationHandler;
|
|||
use crate::error::{EventLoopError, RequestError};
|
||||
use crate::event_loop::{
|
||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||
EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||
EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
|
||||
OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||
};
|
||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||
use crate::platform::macos::ActivationPolicy;
|
||||
|
|
@ -95,9 +95,8 @@ impl ActiveEventLoop {
|
|||
}
|
||||
|
||||
impl RootActiveEventLoop for ActiveEventLoop {
|
||||
fn create_proxy(&self) -> RootEventLoopProxy {
|
||||
let event_loop_proxy = EventLoopProxy::new(self.app_state.proxy_wake_up());
|
||||
RootEventLoopProxy { event_loop_proxy }
|
||||
fn create_proxy(&self) -> CoreEventLoopProxy {
|
||||
CoreEventLoopProxy::new(self.app_state.event_loop_proxy().clone())
|
||||
}
|
||||
|
||||
fn create_window(
|
||||
|
|
@ -436,8 +435,9 @@ pub fn stop_app_on_panic<F: FnOnce() -> R + UnwindSafe, R>(
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EventLoopProxy {
|
||||
proxy_wake_up: Arc<AtomicBool>,
|
||||
pub(crate) wake_up: AtomicBool,
|
||||
source: CFRunLoopSourceRef,
|
||||
}
|
||||
|
||||
|
|
@ -452,14 +452,8 @@ impl Drop for EventLoopProxy {
|
|||
}
|
||||
}
|
||||
|
||||
impl Clone for EventLoopProxy {
|
||||
fn clone(&self) -> Self {
|
||||
EventLoopProxy::new(self.proxy_wake_up.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl EventLoopProxy {
|
||||
fn new(proxy_wake_up: Arc<AtomicBool>) -> Self {
|
||||
pub(crate) fn new() -> Self {
|
||||
unsafe {
|
||||
// just wake up the eventloop
|
||||
extern "C" fn event_loop_proxy_handler(_: *const c_void) {}
|
||||
|
|
@ -483,14 +477,16 @@ impl EventLoopProxy {
|
|||
CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes);
|
||||
CFRunLoopWakeUp(rl);
|
||||
|
||||
EventLoopProxy { proxy_wake_up, source }
|
||||
EventLoopProxy { wake_up: AtomicBool::new(false), source }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wake_up(&self) {
|
||||
self.proxy_wake_up.store(true, AtomicOrdering::Relaxed);
|
||||
impl EventLoopProxyProvider for EventLoopProxy {
|
||||
fn wake_up(&self) {
|
||||
self.wake_up.store(true, AtomicOrdering::Relaxed);
|
||||
unsafe {
|
||||
// let the main thread know there's a new event
|
||||
// Let the main thread know there's a new event.
|
||||
CFRunLoopSourceSignal(self.source);
|
||||
let rl = CFRunLoopGetMain();
|
||||
CFRunLoopWakeUp(rl);
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ mod window_delegate;
|
|||
pub(crate) use self::cursor::CustomCursor as PlatformCustomCursor;
|
||||
pub(crate) use self::event::{physicalkey_to_scancode, scancode_to_physicalkey, KeyEventExtra};
|
||||
pub(crate) use self::event_loop::{
|
||||
ActiveEventLoop, EventLoop, EventLoopProxy, OwnedDisplayHandle,
|
||||
PlatformSpecificEventLoopAttributes,
|
||||
ActiveEventLoop, EventLoop, OwnedDisplayHandle, PlatformSpecificEventLoopAttributes,
|
||||
};
|
||||
pub(crate) use self::monitor::{MonitorHandle, VideoModeHandle};
|
||||
pub(crate) use self::window::Window;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
use std::cell::{OnceCell, RefCell, RefMut};
|
||||
use std::collections::HashSet;
|
||||
use std::os::raw::c_void;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::{Arc, Mutex, OnceLock};
|
||||
use std::time::Instant;
|
||||
use std::{mem, ptr};
|
||||
|
|
@ -24,7 +24,7 @@ use objc2_ui_kit::{UIApplication, UICoordinateSpace, UIView, UIWindow};
|
|||
|
||||
use super::super::event_handler::EventHandler;
|
||||
use super::window::WinitUIWindow;
|
||||
use super::ActiveEventLoop;
|
||||
use super::{ActiveEventLoop, EventLoopProxy};
|
||||
use crate::application::ApplicationHandler;
|
||||
use crate::dpi::PhysicalSize;
|
||||
use crate::event::{Event, StartCause, SurfaceSizeWriter, WindowEvent};
|
||||
|
|
@ -139,7 +139,7 @@ pub(crate) struct AppState {
|
|||
app_state: Option<AppStateImpl>,
|
||||
control_flow: ControlFlow,
|
||||
waker: EventLoopWaker,
|
||||
proxy_wake_up: Arc<AtomicBool>,
|
||||
event_loop_proxy: Arc<EventLoopProxy>,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
|
|
@ -164,7 +164,7 @@ impl AppState {
|
|||
}),
|
||||
control_flow: ControlFlow::default(),
|
||||
waker,
|
||||
proxy_wake_up: Arc::new(AtomicBool::new(false)),
|
||||
event_loop_proxy: Arc::new(EventLoopProxy::new()),
|
||||
});
|
||||
}
|
||||
init_guard(&mut guard);
|
||||
|
|
@ -376,8 +376,8 @@ impl AppState {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn proxy_wake_up(&self) -> Arc<AtomicBool> {
|
||||
self.proxy_wake_up.clone()
|
||||
pub fn event_loop_proxy(&self) -> &Arc<EventLoopProxy> {
|
||||
&self.event_loop_proxy
|
||||
}
|
||||
|
||||
pub(crate) fn set_control_flow(&mut self, control_flow: ControlFlow) {
|
||||
|
|
@ -543,10 +543,10 @@ fn handle_user_events(mtm: MainThreadMarker) {
|
|||
if processing_redraws {
|
||||
bug!("user events attempted to be sent out while `ProcessingRedraws`");
|
||||
}
|
||||
let proxy_wake_up = this.proxy_wake_up.clone();
|
||||
let event_loop_proxy = this.event_loop_proxy().clone();
|
||||
drop(this);
|
||||
|
||||
if proxy_wake_up.swap(false, Ordering::Relaxed) {
|
||||
if event_loop_proxy.wake_up.swap(false, Ordering::Relaxed) {
|
||||
handle_event(mtm, Event::UserWakeUp);
|
||||
}
|
||||
|
||||
|
|
@ -578,7 +578,7 @@ fn handle_user_events(mtm: MainThreadMarker) {
|
|||
}
|
||||
}
|
||||
|
||||
if proxy_wake_up.swap(false, Ordering::Relaxed) {
|
||||
if event_loop_proxy.wake_up.swap(false, Ordering::Relaxed) {
|
||||
handle_event(mtm, Event::UserWakeUp);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
use std::ffi::{c_char, c_int, c_void};
|
||||
use std::ptr::{self, NonNull};
|
||||
use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
|
||||
use std::sync::Arc;
|
||||
|
||||
use core_foundation::base::{CFIndex, CFRelease};
|
||||
use core_foundation::runloop::{
|
||||
|
|
@ -29,7 +28,8 @@ use crate::error::{EventLoopError, NotSupportedError, RequestError};
|
|||
use crate::event::Event;
|
||||
use crate::event_loop::{
|
||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||
EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||
EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
|
||||
OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||
};
|
||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||
use crate::platform_impl::Window;
|
||||
|
|
@ -41,9 +41,8 @@ pub(crate) struct ActiveEventLoop {
|
|||
}
|
||||
|
||||
impl RootActiveEventLoop for ActiveEventLoop {
|
||||
fn create_proxy(&self) -> crate::event_loop::EventLoopProxy {
|
||||
let event_loop_proxy = EventLoopProxy::new(AppState::get_mut(self.mtm).proxy_wake_up());
|
||||
RootEventLoopProxy { event_loop_proxy }
|
||||
fn create_proxy(&self) -> CoreEventLoopProxy {
|
||||
CoreEventLoopProxy::new(AppState::get_mut(self.mtm).event_loop_proxy().clone())
|
||||
}
|
||||
|
||||
fn create_window(
|
||||
|
|
@ -289,19 +288,13 @@ impl EventLoop {
|
|||
}
|
||||
|
||||
pub struct EventLoopProxy {
|
||||
proxy_wake_up: Arc<AtomicBool>,
|
||||
pub(crate) wake_up: AtomicBool,
|
||||
source: CFRunLoopSourceRef,
|
||||
}
|
||||
|
||||
unsafe impl Send for EventLoopProxy {}
|
||||
unsafe impl Sync for EventLoopProxy {}
|
||||
|
||||
impl Clone for EventLoopProxy {
|
||||
fn clone(&self) -> EventLoopProxy {
|
||||
EventLoopProxy::new(self.proxy_wake_up.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for EventLoopProxy {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
|
|
@ -312,7 +305,7 @@ impl Drop for EventLoopProxy {
|
|||
}
|
||||
|
||||
impl EventLoopProxy {
|
||||
fn new(proxy_wake_up: Arc<AtomicBool>) -> EventLoopProxy {
|
||||
pub(crate) fn new() -> EventLoopProxy {
|
||||
unsafe {
|
||||
// just wake up the eventloop
|
||||
extern "C" fn event_loop_proxy_handler(_: *const c_void) {}
|
||||
|
|
@ -336,12 +329,14 @@ impl EventLoopProxy {
|
|||
CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes);
|
||||
CFRunLoopWakeUp(rl);
|
||||
|
||||
EventLoopProxy { proxy_wake_up, source }
|
||||
EventLoopProxy { wake_up: AtomicBool::new(false), source }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn wake_up(&self) {
|
||||
self.proxy_wake_up.store(true, AtomicOrdering::Relaxed);
|
||||
impl EventLoopProxyProvider for EventLoopProxy {
|
||||
fn wake_up(&self) {
|
||||
self.wake_up.store(true, AtomicOrdering::Relaxed);
|
||||
unsafe {
|
||||
// let the main thread know there's a new event
|
||||
CFRunLoopSourceSignal(self.source);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue