//! Hoists a basic `NSViewController`. use std::rc::Rc; use std::sync::Once; use objc::declare::ClassDecl; use objc::runtime::{Class, Object, Sel}; use objc::{class, sel, sel_impl}; use crate::view::{VIEW_DELEGATE_PTR, ViewDelegate}; use crate::utils::load; /// Called when the view controller receives a `viewWillAppear` message. extern fn will_appear(this: &mut Object, _: Sel) { let controller = load::(this, VIEW_DELEGATE_PTR); { let vc = controller.borrow(); (*vc).will_appear(); } Rc::into_raw(controller); } /// Called when the view controller receives a `viewDidAppear` message. extern fn did_appear(this: &mut Object, _: Sel) { let controller = load::(this, VIEW_DELEGATE_PTR); { let vc = controller.borrow(); (*vc).did_appear(); } Rc::into_raw(controller); } /// Called when the view controller receives a `viewWillDisappear` message. extern fn will_disappear(this: &mut Object, _: Sel) { let controller = load::(this, VIEW_DELEGATE_PTR); { let vc = controller.borrow(); (*vc).will_disappear(); } Rc::into_raw(controller); } /// Called when the view controller receives a `viewDidDisappear` message. extern fn did_disappear(this: &mut Object, _: Sel) { let controller = load::(this, VIEW_DELEGATE_PTR); { let vc = controller.borrow(); (*vc).did_disappear(); } Rc::into_raw(controller); } /// Registers an `NSViewDelegate`. pub(crate) fn register_view_controller_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(NSViewController); let mut decl = ClassDecl::new("RSTViewController", superclass).unwrap(); decl.add_ivar::(VIEW_DELEGATE_PTR); // NSViewDelegate decl.add_method(sel!(viewWillAppear), will_appear:: as extern fn(&mut Object, _)); decl.add_method(sel!(viewDidAppear), did_appear:: as extern fn(&mut Object, _)); decl.add_method(sel!(viewWillDisappear), will_disappear:: as extern fn(&mut Object, _)); decl.add_method(sel!(viewDidDisappear), did_disappear:: as extern fn(&mut Object, _)); VIEW_CLASS = decl.register(); }); unsafe { VIEW_CLASS } }