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}