Remove custom definition of Core Foundation runloop functionality (#2479)

Use the definitions that `core_foundation` exposes (almost the same, except `CFRunLoopSourceContext::perform` is not nullable, so we account for that as well).
This commit is contained in:
Mads Marquart 2022-09-08 21:03:25 +02:00 committed by GitHub
parent fb248eaadc
commit d8c0ee733b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 66 additions and 236 deletions

View file

@ -63,9 +63,9 @@ ndk-glue = "0.7.0"
[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies] [target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
objc2 = "=0.3.0-beta.3" objc2 = "=0.3.0-beta.3"
core-foundation = "0.9.3"
[target.'cfg(target_os = "macos")'.dependencies] [target.'cfg(target_os = "macos")'.dependencies]
core-foundation = "0.9.3"
core-graphics = "0.22.3" core-graphics = "0.22.3"
dispatch = "0.2.0" dispatch = "0.2.0"

View file

@ -9,6 +9,12 @@ use std::{
time::Instant, time::Instant,
}; };
use core_foundation::base::CFRelease;
use core_foundation::date::CFAbsoluteTimeGetCurrent;
use core_foundation::runloop::{
kCFRunLoopCommonModes, CFRunLoopAddTimer, CFRunLoopGetMain, CFRunLoopRef, CFRunLoopTimerCreate,
CFRunLoopTimerInvalidate, CFRunLoopTimerRef, CFRunLoopTimerSetNextFireDate,
};
use objc2::foundation::{NSInteger, NSUInteger}; use objc2::foundation::{NSInteger, NSUInteger};
use objc2::runtime::Object; use objc2::runtime::Object;
use objc2::{class, msg_send, sel}; use objc2::{class, msg_send, sel};
@ -20,12 +26,7 @@ use crate::{
event_loop::ControlFlow, event_loop::ControlFlow,
platform_impl::platform::{ platform_impl::platform::{
event_loop::{EventHandler, EventProxy, EventWrapper, Never}, event_loop::{EventHandler, EventProxy, EventWrapper, Never},
ffi::{ ffi::{id, CGRect, CGSize, NSOperatingSystemVersion},
id, kCFRunLoopCommonModes, CFAbsoluteTimeGetCurrent, CFRelease, CFRunLoopAddTimer,
CFRunLoopGetMain, CFRunLoopRef, CFRunLoopTimerCreate, CFRunLoopTimerInvalidate,
CFRunLoopTimerRef, CFRunLoopTimerSetNextFireDate, CGRect, CGSize,
NSOperatingSystemVersion,
},
}, },
window::WindowId as RootWindowId, window::WindowId as RootWindowId,
}; };

View file

@ -3,10 +3,18 @@ use std::{
ffi::c_void, ffi::c_void,
fmt::{self, Debug}, fmt::{self, Debug},
marker::PhantomData, marker::PhantomData,
mem, ptr, ptr,
sync::mpsc::{self, Receiver, Sender}, sync::mpsc::{self, Receiver, Sender},
}; };
use core_foundation::base::{CFIndex, CFRelease};
use core_foundation::runloop::{
kCFRunLoopAfterWaiting, kCFRunLoopBeforeWaiting, kCFRunLoopCommonModes, kCFRunLoopDefaultMode,
kCFRunLoopEntry, kCFRunLoopExit, CFRunLoopActivity, CFRunLoopAddObserver, CFRunLoopAddSource,
CFRunLoopGetMain, CFRunLoopObserverCreate, CFRunLoopObserverRef, CFRunLoopSourceContext,
CFRunLoopSourceCreate, CFRunLoopSourceInvalidate, CFRunLoopSourceRef, CFRunLoopSourceSignal,
CFRunLoopWakeUp,
};
use objc2::runtime::Object; use objc2::runtime::Object;
use objc2::{class, msg_send, ClassType}; use objc2::{class, msg_send, ClassType};
use raw_window_handle::{RawDisplayHandle, UiKitDisplayHandle}; use raw_window_handle::{RawDisplayHandle, UiKitDisplayHandle};
@ -23,15 +31,7 @@ use crate::{
use crate::platform_impl::platform::{ use crate::platform_impl::platform::{
app_state, app_state,
ffi::{ ffi::{id, nil, NSStringRust, UIApplicationMain, UIUserInterfaceIdiom},
id, kCFRunLoopAfterWaiting, kCFRunLoopBeforeWaiting, kCFRunLoopCommonModes,
kCFRunLoopDefaultMode, kCFRunLoopEntry, kCFRunLoopExit, nil, CFIndex, CFRelease,
CFRunLoopActivity, CFRunLoopAddObserver, CFRunLoopAddSource, CFRunLoopGetMain,
CFRunLoopObserverCreate, CFRunLoopObserverRef, CFRunLoopSourceContext,
CFRunLoopSourceCreate, CFRunLoopSourceInvalidate, CFRunLoopSourceRef,
CFRunLoopSourceSignal, CFRunLoopWakeUp, NSStringRust, UIApplicationMain,
UIUserInterfaceIdiom,
},
monitor, view, MonitorHandle, monitor, view, MonitorHandle,
}; };
@ -184,14 +184,23 @@ impl<T> EventLoopProxy<T> {
fn new(sender: Sender<T>) -> EventLoopProxy<T> { fn new(sender: Sender<T>) -> EventLoopProxy<T> {
unsafe { unsafe {
// just wake up the eventloop // just wake up the eventloop
extern "C" fn event_loop_proxy_handler(_: *mut c_void) {} extern "C" fn event_loop_proxy_handler(_: *const c_void) {}
// adding a Source to the main CFRunLoop lets us wake it up and // adding a Source to the main CFRunLoop lets us wake it up and
// process user events through the normal OS EventLoop mechanisms. // process user events through the normal OS EventLoop mechanisms.
let rl = CFRunLoopGetMain(); let rl = CFRunLoopGetMain();
// we want all the members of context to be zero/null, except one let mut context = CFRunLoopSourceContext {
let mut context: CFRunLoopSourceContext = mem::zeroed(); version: 0,
context.perform = Some(event_loop_proxy_handler); info: ptr::null_mut(),
retain: None,
release: None,
copyDescription: None,
equal: None,
hash: None,
schedule: None,
cancel: None,
perform: event_loop_proxy_handler,
};
let source = let source =
CFRunLoopSourceCreate(ptr::null_mut(), CFIndex::max_value() - 1, &mut context); CFRunLoopSourceCreate(ptr::null_mut(), CFIndex::max_value() - 1, &mut context);
CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes); CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes);

View file

@ -1,6 +1,9 @@
#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)] #![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)]
use std::{convert::TryInto, ffi::CString, ops::BitOr, os::raw::*}; use std::convert::TryInto;
use std::ffi::CString;
use std::ops::BitOr;
use std::os::raw::{c_char, c_int};
use objc2::encode::{Encode, Encoding}; use objc2::encode::{Encode, Encoding};
use objc2::foundation::{NSInteger, NSUInteger}; use objc2::foundation::{NSInteger, NSUInteger};
@ -280,108 +283,13 @@ impl UIScreenOverscanCompensation {
} }
#[link(name = "UIKit", kind = "framework")] #[link(name = "UIKit", kind = "framework")]
#[link(name = "CoreFoundation", kind = "framework")]
extern "C" { extern "C" {
pub static kCFRunLoopDefaultMode: CFRunLoopMode;
pub static kCFRunLoopCommonModes: CFRunLoopMode;
pub fn UIApplicationMain( pub fn UIApplicationMain(
argc: c_int, argc: c_int,
argv: *const c_char, argv: *const c_char,
principalClassName: id, principalClassName: id,
delegateClassName: id, delegateClassName: id,
) -> c_int; ) -> c_int;
pub fn CFRunLoopGetMain() -> CFRunLoopRef;
pub fn CFRunLoopWakeUp(rl: CFRunLoopRef);
pub fn CFRunLoopObserverCreate(
allocator: CFAllocatorRef,
activities: CFOptionFlags,
repeats: Boolean,
order: CFIndex,
callout: CFRunLoopObserverCallBack,
context: *mut CFRunLoopObserverContext,
) -> CFRunLoopObserverRef;
pub fn CFRunLoopAddObserver(
rl: CFRunLoopRef,
observer: CFRunLoopObserverRef,
mode: CFRunLoopMode,
);
pub fn CFRunLoopTimerCreate(
allocator: CFAllocatorRef,
fireDate: CFAbsoluteTime,
interval: CFTimeInterval,
flags: CFOptionFlags,
order: CFIndex,
callout: CFRunLoopTimerCallBack,
context: *mut CFRunLoopTimerContext,
) -> CFRunLoopTimerRef;
pub fn CFRunLoopAddTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFRunLoopMode);
pub fn CFRunLoopTimerSetNextFireDate(timer: CFRunLoopTimerRef, fireDate: CFAbsoluteTime);
pub fn CFRunLoopTimerInvalidate(time: CFRunLoopTimerRef);
pub fn CFRunLoopSourceCreate(
allocator: CFAllocatorRef,
order: CFIndex,
context: *mut CFRunLoopSourceContext,
) -> CFRunLoopSourceRef;
pub fn CFRunLoopAddSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFRunLoopMode);
pub fn CFRunLoopSourceInvalidate(source: CFRunLoopSourceRef);
pub fn CFRunLoopSourceSignal(source: CFRunLoopSourceRef);
pub fn CFAbsoluteTimeGetCurrent() -> CFAbsoluteTime;
pub fn CFRelease(cftype: *const c_void);
}
pub type Boolean = u8;
pub enum CFAllocator {}
pub type CFAllocatorRef = *mut CFAllocator;
pub enum CFRunLoop {}
pub type CFRunLoopRef = *mut CFRunLoop;
pub type CFRunLoopMode = CFStringRef;
pub enum CFRunLoopObserver {}
pub type CFRunLoopObserverRef = *mut CFRunLoopObserver;
pub enum CFRunLoopTimer {}
pub type CFRunLoopTimerRef = *mut CFRunLoopTimer;
pub enum CFRunLoopSource {}
pub type CFRunLoopSourceRef = *mut CFRunLoopSource;
pub enum CFString {}
pub type CFStringRef = *const CFString;
pub type CFHashCode = c_ulong;
pub type CFIndex = c_long;
pub type CFOptionFlags = c_ulong;
pub type CFRunLoopActivity = CFOptionFlags;
pub type CFAbsoluteTime = CFTimeInterval;
pub type CFTimeInterval = f64;
pub const kCFRunLoopEntry: CFRunLoopActivity = 0;
pub const kCFRunLoopBeforeWaiting: CFRunLoopActivity = 1 << 5;
pub const kCFRunLoopAfterWaiting: CFRunLoopActivity = 1 << 6;
pub const kCFRunLoopExit: CFRunLoopActivity = 1 << 7;
pub type CFRunLoopObserverCallBack =
extern "C" fn(observer: CFRunLoopObserverRef, activity: CFRunLoopActivity, info: *mut c_void);
pub type CFRunLoopTimerCallBack = extern "C" fn(timer: CFRunLoopTimerRef, info: *mut c_void);
pub enum CFRunLoopObserverContext {}
pub enum CFRunLoopTimerContext {}
#[repr(C)]
pub struct CFRunLoopSourceContext {
pub version: CFIndex,
pub info: *mut c_void,
pub retain: Option<extern "C" fn(*const c_void) -> *const c_void>,
pub release: Option<extern "C" fn(*const c_void)>,
pub copyDescription: Option<extern "C" fn(*const c_void) -> CFStringRef>,
pub equal: Option<extern "C" fn(*const c_void, *const c_void) -> Boolean>,
pub hash: Option<extern "C" fn(*const c_void) -> CFHashCode>,
pub schedule: Option<extern "C" fn(*mut c_void, CFRunLoopRef, CFRunLoopMode)>,
pub cancel: Option<extern "C" fn(*mut c_void, CFRunLoopRef, CFRunLoopMode)>,
pub perform: Option<extern "C" fn(*mut c_void)>,
} }
// This is named NSStringRust rather than NSString because the "Debug View Heirarchy" feature of // This is named NSStringRust rather than NSString because the "Debug View Heirarchy" feature of

View file

@ -11,6 +11,7 @@ use std::{
time::Instant, time::Instant,
}; };
use core_foundation::runloop::{CFRunLoopGetMain, CFRunLoopWakeUp};
use objc2::foundation::{is_main_thread, NSSize}; use objc2::foundation::{is_main_thread, NSSize};
use objc2::rc::autoreleasepool; use objc2::rc::autoreleasepool;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
@ -24,7 +25,7 @@ use crate::{
event::{EventProxy, EventWrapper}, event::{EventProxy, EventWrapper},
event_loop::PanicInfo, event_loop::PanicInfo,
menu, menu,
observer::{CFRunLoopGetMain, CFRunLoopWakeUp, EventLoopWaker}, observer::EventLoopWaker,
util::Never, util::Never,
window::WinitWindow, window::WinitWindow,
}, },

View file

@ -11,6 +11,11 @@ use std::{
sync::mpsc, sync::mpsc,
}; };
use core_foundation::base::{CFIndex, CFRelease};
use core_foundation::runloop::{
kCFRunLoopCommonModes, CFRunLoopAddSource, CFRunLoopGetMain, CFRunLoopSourceContext,
CFRunLoopSourceCreate, CFRunLoopSourceRef, CFRunLoopSourceSignal, CFRunLoopWakeUp,
};
use objc2::foundation::is_main_thread; use objc2::foundation::is_main_thread;
use objc2::rc::{autoreleasepool, Id, Shared}; use objc2::rc::{autoreleasepool, Id, Shared};
use objc2::{msg_send_id, ClassType}; use objc2::{msg_send_id, ClassType};
@ -27,7 +32,7 @@ use crate::{
app_delegate::ApplicationDelegate, app_delegate::ApplicationDelegate,
app_state::{AppState, Callback}, app_state::{AppState, Callback},
monitor::{self, MonitorHandle}, monitor::{self, MonitorHandle},
observer::*, observer::setup_control_flow_observers,
}, },
}; };
@ -278,13 +283,23 @@ impl<T> EventLoopProxy<T> {
fn new(sender: mpsc::Sender<T>) -> Self { fn new(sender: mpsc::Sender<T>) -> Self {
unsafe { unsafe {
// just wake up the eventloop // just wake up the eventloop
extern "C" fn event_loop_proxy_handler(_: *mut c_void) {} extern "C" fn event_loop_proxy_handler(_: *const c_void) {}
// adding a Source to the main CFRunLoop lets us wake it up and // adding a Source to the main CFRunLoop lets us wake it up and
// process user events through the normal OS EventLoop mechanisms. // process user events through the normal OS EventLoop mechanisms.
let rl = CFRunLoopGetMain(); let rl = CFRunLoopGetMain();
let mut context: CFRunLoopSourceContext = mem::zeroed(); let mut context = CFRunLoopSourceContext {
context.perform = Some(event_loop_proxy_handler); version: 0,
info: ptr::null_mut(),
retain: None,
release: None,
copyDescription: None,
equal: None,
hash: None,
schedule: None,
cancel: None,
perform: event_loop_proxy_handler,
};
let source = let source =
CFRunLoopSourceCreate(ptr::null_mut(), CFIndex::max_value() - 1, &mut context); CFRunLoopSourceCreate(ptr::null_mut(), CFIndex::max_value() - 1, &mut context);
CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes); CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes);

View file

@ -1,6 +1,6 @@
use std::{ use std::{
self, self,
os::raw::*, ffi::c_void,
panic::{AssertUnwindSafe, UnwindSafe}, panic::{AssertUnwindSafe, UnwindSafe},
ptr, ptr,
rc::Weak, rc::Weak,
@ -12,119 +12,15 @@ use crate::platform_impl::platform::{
event_loop::{stop_app_on_panic, PanicInfo}, event_loop::{stop_app_on_panic, PanicInfo},
ffi, ffi,
}; };
use core_foundation::base::{CFIndex, CFOptionFlags, CFRelease};
#[link(name = "CoreFoundation", kind = "framework")] use core_foundation::date::CFAbsoluteTimeGetCurrent;
extern "C" { use core_foundation::runloop::{
pub static kCFRunLoopCommonModes: CFRunLoopMode; kCFRunLoopAfterWaiting, kCFRunLoopBeforeWaiting, kCFRunLoopCommonModes, kCFRunLoopEntry,
kCFRunLoopExit, CFRunLoopActivity, CFRunLoopAddObserver, CFRunLoopAddTimer, CFRunLoopGetMain,
pub fn CFRunLoopGetMain() -> CFRunLoopRef; CFRunLoopObserverCallBack, CFRunLoopObserverContext, CFRunLoopObserverCreate,
pub fn CFRunLoopWakeUp(rl: CFRunLoopRef); CFRunLoopObserverRef, CFRunLoopRef, CFRunLoopTimerCreate, CFRunLoopTimerInvalidate,
CFRunLoopTimerRef, CFRunLoopTimerSetNextFireDate,
pub fn CFRunLoopObserverCreate( };
allocator: CFAllocatorRef,
activities: CFOptionFlags,
repeats: ffi::Boolean,
order: CFIndex,
callout: CFRunLoopObserverCallBack,
context: *mut CFRunLoopObserverContext,
) -> CFRunLoopObserverRef;
pub fn CFRunLoopAddObserver(
rl: CFRunLoopRef,
observer: CFRunLoopObserverRef,
mode: CFRunLoopMode,
);
pub fn CFRunLoopTimerCreate(
allocator: CFAllocatorRef,
fireDate: CFAbsoluteTime,
interval: CFTimeInterval,
flags: CFOptionFlags,
order: CFIndex,
callout: CFRunLoopTimerCallBack,
context: *mut CFRunLoopTimerContext,
) -> CFRunLoopTimerRef;
pub fn CFRunLoopAddTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFRunLoopMode);
pub fn CFRunLoopTimerSetNextFireDate(timer: CFRunLoopTimerRef, fireDate: CFAbsoluteTime);
pub fn CFRunLoopTimerInvalidate(time: CFRunLoopTimerRef);
pub fn CFRunLoopSourceCreate(
allocator: CFAllocatorRef,
order: CFIndex,
context: *mut CFRunLoopSourceContext,
) -> CFRunLoopSourceRef;
pub fn CFRunLoopAddSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFRunLoopMode);
#[allow(dead_code)]
pub fn CFRunLoopSourceInvalidate(source: CFRunLoopSourceRef);
pub fn CFRunLoopSourceSignal(source: CFRunLoopSourceRef);
pub fn CFAbsoluteTimeGetCurrent() -> CFAbsoluteTime;
pub fn CFRelease(cftype: *const c_void);
}
pub enum CFAllocator {}
pub type CFAllocatorRef = *mut CFAllocator;
pub enum CFRunLoop {}
pub type CFRunLoopRef = *mut CFRunLoop;
pub type CFRunLoopMode = CFStringRef;
pub enum CFRunLoopObserver {}
pub type CFRunLoopObserverRef = *mut CFRunLoopObserver;
pub enum CFRunLoopTimer {}
pub type CFRunLoopTimerRef = *mut CFRunLoopTimer;
pub enum CFRunLoopSource {}
pub type CFRunLoopSourceRef = *mut CFRunLoopSource;
pub enum CFString {}
pub type CFStringRef = *const CFString;
pub type CFHashCode = c_ulong;
pub type CFIndex = c_long;
pub type CFOptionFlags = c_ulong;
pub type CFRunLoopActivity = CFOptionFlags;
pub type CFAbsoluteTime = CFTimeInterval;
pub type CFTimeInterval = f64;
#[allow(non_upper_case_globals)]
pub const kCFRunLoopEntry: CFRunLoopActivity = 0;
#[allow(non_upper_case_globals)]
pub const kCFRunLoopBeforeWaiting: CFRunLoopActivity = 1 << 5;
#[allow(non_upper_case_globals)]
pub const kCFRunLoopAfterWaiting: CFRunLoopActivity = 1 << 6;
#[allow(non_upper_case_globals)]
pub const kCFRunLoopExit: CFRunLoopActivity = 1 << 7;
pub type CFRunLoopObserverCallBack =
extern "C" fn(observer: CFRunLoopObserverRef, activity: CFRunLoopActivity, info: *mut c_void);
pub type CFRunLoopTimerCallBack = extern "C" fn(timer: CFRunLoopTimerRef, info: *mut c_void);
pub enum CFRunLoopTimerContext {}
/// This mirrors the struct with the same name from Core Foundation.
///
/// <https://developer.apple.com/documentation/corefoundation/cfrunloopobservercontext?language=objc>
#[allow(non_snake_case)]
#[repr(C)]
pub struct CFRunLoopObserverContext {
pub version: CFIndex,
pub info: *mut c_void,
pub retain: Option<extern "C" fn(info: *const c_void) -> *const c_void>,
pub release: Option<extern "C" fn(info: *const c_void)>,
pub copyDescription: Option<extern "C" fn(info: *const c_void) -> CFStringRef>,
}
#[allow(non_snake_case)]
#[repr(C)]
pub struct CFRunLoopSourceContext {
pub version: CFIndex,
pub info: *mut c_void,
pub retain: Option<extern "C" fn(*const c_void) -> *const c_void>,
pub release: Option<extern "C" fn(*const c_void)>,
pub copyDescription: Option<extern "C" fn(*const c_void) -> CFStringRef>,
pub equal: Option<extern "C" fn(*const c_void, *const c_void) -> ffi::Boolean>,
pub hash: Option<extern "C" fn(*const c_void) -> CFHashCode>,
pub schedule: Option<extern "C" fn(*mut c_void, CFRunLoopRef, CFRunLoopMode)>,
pub cancel: Option<extern "C" fn(*mut c_void, CFRunLoopRef, CFRunLoopMode)>,
pub perform: Option<extern "C" fn(*mut c_void)>,
}
unsafe fn control_flow_handler<F>(panic_info: *mut c_void, f: F) unsafe fn control_flow_handler<F>(panic_info: *mut c_void, f: F)
where where