objc2_watch_kit/application.rs
1#![cfg(feature = "WKApplicationMain")]
2use core::ffi::{c_char, c_int};
3use core::ptr::NonNull;
4
5use objc2::MainThreadMarker;
6use objc2_foundation::NSString;
7
8use crate::WKApplication;
9
10// These functions are in crt_externs.h.
11extern "C" {
12 fn _NSGetArgc() -> *mut c_int;
13 fn _NSGetArgv() -> *mut *mut *mut c_char;
14}
15
16impl WKApplication {
17 /// The entry point to WatchKit applications.
18 ///
19 /// Creates the application object and the application delegate, and sets
20 /// up the app’s event cycle.
21 ///
22 /// See [Apple's documentation][apple-doc] for more details.
23 ///
24 /// [apple-doc]: https://developer.apple.com/documentation/appkit/nsapplicationmain(_:_:)
25 #[doc(alias = "WKApplicationMain")]
26 pub fn main(application_delegate_class_name: Option<&NSString>, mtm: MainThreadMarker) -> ! {
27 // WKApplicationMain must be called on the main thread.
28 let _ = mtm;
29
30 // NOTE: `WKApplicationMain` ignores `argc` and `argv`, so we choose
31 // to not expose those in our API.
32 // We pass correct values anyhow though, just to be certain.
33 let argc = unsafe { *_NSGetArgc() };
34 let argv = unsafe { NonNull::new(*_NSGetArgv()).unwrap().cast() };
35
36 // SAFETY: `argc` and `argv` are correct.
37 // `WKApplicationMain` is safely re-entrant, just weird to do so.
38 let _ret = unsafe { Self::__main(argc, argv, application_delegate_class_name) };
39
40 // WKApplicationMain is documented to never return, so whatever we do
41 // here is just for show really.
42 #[cfg(feature = "std")]
43 {
44 std::process::exit(_ret as i32)
45 }
46 #[cfg(not(feature = "std"))]
47 {
48 unreachable!("WKApplicationMain should not have returned")
49 }
50 }
51}