diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 522399f6..71c87851 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -352,8 +352,8 @@ We'll step through an example (abridged) `View` bridge below, for macOS. You sho For our basic `View` type, we want to just map to the corresponding class on the Objective-C side (in this case, `NSView`), and maybe do a bit of tweaking for sanity reasons. ``` rust -pub(crate) fn register_view_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_view_class() -> &'static Class { + static mut VIEW_CLASS: Option<'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -364,10 +364,10 @@ pub(crate) fn register_view_class() -> *const Class { decl.add_ivar::(BACKGROUND_COLOR); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } ``` @@ -377,7 +377,7 @@ Objective-C method signatures, as well as provision space for variable storage ( For our _delegate_ types, we need a different class creation method - one that creates a subclass per-unique-type: ``` rust -pub(crate) fn register_view_class_with_delegate(instance: &T) -> *const Class { +pub(crate) fn register_view_class_with_delegate(instance: &T) -> &'static Class { load_or_register_class("NSView", instance.subclass_name(), |decl| unsafe { decl.add_ivar::(VIEW_DELEGATE_PTR); decl.add_ivar::(BACKGROUND_COLOR); diff --git a/src/appkit/app/class.rs b/src/appkit/app/class.rs index e53885f4..fa034ba1 100644 --- a/src/appkit/app/class.rs +++ b/src/appkit/app/class.rs @@ -9,15 +9,15 @@ use objc::declare::ClassDecl; use objc::runtime::Class; /// Used for injecting a custom NSApplication. Currently does nothing. -pub(crate) fn register_app_class() -> *const Class { - static mut APP_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_app_class() -> &'static Class { + static mut APP_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(NSApplication); let decl = ClassDecl::new("RSTApplication", superclass).unwrap(); - APP_CLASS = decl.register(); + APP_CLASS = Some(decl.register()); }); - unsafe { APP_CLASS } + unsafe { APP_CLASS.unwrap() } } diff --git a/src/appkit/app/delegate.rs b/src/appkit/app/delegate.rs index 0b904ee2..cf5a7438 100644 --- a/src/appkit/app/delegate.rs +++ b/src/appkit/app/delegate.rs @@ -294,8 +294,8 @@ extern "C" fn delegate_handles_key(this: &Object, _: Sel, _: id, /// Registers an `NSObject` application delegate, and configures it for the various callbacks and /// pointers we need to have. -pub(crate) fn register_app_delegate_class() -> *const Class { - static mut DELEGATE_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_app_delegate_class() -> &'static Class { + static mut DELEGATE_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -453,8 +453,8 @@ pub(crate) fn register_app_delegate_class() -> *co delegate_handles_key:: as extern "C" fn(_, _, _, _) -> _ ); - DELEGATE_CLASS = decl.register(); + DELEGATE_CLASS = Some(decl.register()); }); - unsafe { DELEGATE_CLASS } + unsafe { DELEGATE_CLASS.unwrap() } } diff --git a/src/appkit/menu/item.rs b/src/appkit/menu/item.rs index a39eaa48..b4105d6e 100644 --- a/src/appkit/menu/item.rs +++ b/src/appkit/menu/item.rs @@ -313,8 +313,8 @@ extern "C" fn fire_block_action(this: &Object, _: Sel, _item: id) { /// /// In general, we do not want to do more than we need to here - menus are one of the last areas /// where Carbon still lurks, and subclassing things can get weird. -pub(crate) fn register_menu_item_class() -> *const Class { - static mut APP_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_menu_item_class() -> &'static Class { + static mut APP_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -325,8 +325,8 @@ pub(crate) fn register_menu_item_class() -> *const Class { decl.add_method(sel!(dealloc), dealloc_cacao_menuitem as extern "C" fn(_, _)); decl.add_method(sel!(fireBlockAction:), fire_block_action as extern "C" fn(_, _, _)); - APP_CLASS = decl.register(); + APP_CLASS = Some(decl.register()); }); - unsafe { APP_CLASS } + unsafe { APP_CLASS.unwrap() } } diff --git a/src/appkit/toolbar/class.rs b/src/appkit/toolbar/class.rs index 29139fcb..feecfda0 100644 --- a/src/appkit/toolbar/class.rs +++ b/src/appkit/toolbar/class.rs @@ -65,7 +65,7 @@ extern "C" fn item_for_identifier(this: &Object, _: Sel, _: /// Registers a `NSToolbar` subclass, and configures it to hold some ivars for various things we need /// to store. We use it as our delegate as well, just to cut down on moving pieces. -pub(crate) fn register_toolbar_class(instance: &T) -> *const Class { +pub(crate) fn register_toolbar_class(instance: &T) -> &'static Class { load_or_register_class("NSObject", instance.subclass_name(), |decl| unsafe { // For callbacks decl.add_ivar::(TOOLBAR_PTR); diff --git a/src/appkit/window/class.rs b/src/appkit/window/class.rs index 19dca2a6..09c6c02c 100644 --- a/src/appkit/window/class.rs +++ b/src/appkit/window/class.rs @@ -227,7 +227,7 @@ extern "C" fn cancel(this: &Object, _: Sel, _: id) { /// Injects an `NSWindowDelegate` subclass, with some callback and pointer ivars for what we /// need to do. -pub(crate) fn register_window_class_with_delegate(instance: &T) -> *const Class { +pub(crate) fn register_window_class_with_delegate(instance: &T) -> &'static Class { load_or_register_class("NSWindow", instance.subclass_name(), |decl| unsafe { decl.add_ivar::(WINDOW_DELEGATE_PTR); diff --git a/src/appkit/window/controller/class.rs b/src/appkit/window/controller/class.rs index 2f9c914c..ac2802ba 100644 --- a/src/appkit/window/controller/class.rs +++ b/src/appkit/window/controller/class.rs @@ -11,16 +11,16 @@ use crate::appkit::window::{WindowDelegate, WINDOW_DELEGATE_PTR}; /// Injects an `NSWindowController` subclass, with some callback and pointer ivars for what we /// need to do. -pub(crate) fn register_window_controller_class() -> *const Class { - static mut DELEGATE_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_window_controller_class() -> &'static Class { + static mut DELEGATE_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(NSWindowController); let mut decl = ClassDecl::new("RSTWindowController", superclass).unwrap(); decl.add_ivar::(WINDOW_DELEGATE_PTR); - DELEGATE_CLASS = decl.register(); + DELEGATE_CLASS = Some(decl.register()); }); - unsafe { DELEGATE_CLASS } + unsafe { DELEGATE_CLASS.unwrap() } } diff --git a/src/button/mod.rs b/src/button/mod.rs index 6085925d..ecf62c28 100644 --- a/src/button/mod.rs +++ b/src/button/mod.rs @@ -342,15 +342,15 @@ impl Drop for Button { /// Registers an `NSButton` subclass, and configures it to hold some ivars /// for various things we need to store. -fn register_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +fn register_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(NSButton); let decl = ClassDecl::new("RSTButton", superclass).unwrap(); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } diff --git a/src/color/appkit_dynamic_color.rs b/src/color/appkit_dynamic_color.rs index 3c3ceb9f..3e12c3df 100644 --- a/src/color/appkit_dynamic_color.rs +++ b/src/color/appkit_dynamic_color.rs @@ -258,8 +258,8 @@ extern "C" fn color_with_system_effect(this: &Object, _: Sel, effect: NSInteger) unsafe { msg_send![color, colorWithSystemEffect: effect] } } -pub(crate) fn register_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -333,8 +333,8 @@ pub(crate) fn register_class() -> *const Class { decl.add_ivar::(AQUA_DARK_COLOR_NORMAL_CONTRAST); decl.add_ivar::(AQUA_DARK_COLOR_HIGH_CONTRAST); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } diff --git a/src/foundation/class.rs b/src/foundation/class.rs index 2b435dbc..ed1d26d9 100644 --- a/src/foundation/class.rs +++ b/src/foundation/class.rs @@ -49,12 +49,12 @@ impl ClassMap { } /// Attempts to load a previously registered subclass. - pub fn load_subclass(&self, subclass_name: &'static str, superclass_name: &'static str) -> Option<*const Class> { + pub fn load_subclass(&self, subclass_name: &'static str, superclass_name: &'static str) -> Option<&'static Class> { let reader = self.0.read().unwrap(); if let Some(inner) = (*reader).get(subclass_name) { if let Some(class) = inner.get(superclass_name) { - return Some(*class as *const Class); + return Some(unsafe { (*class as *const Class).as_ref() }.unwrap()); } } @@ -103,7 +103,7 @@ impl ClassMap { } } - Some(superclass.cast()) + Some(unsafe { superclass.cast::().as_ref() }.unwrap()) } } @@ -121,7 +121,7 @@ impl ClassMap { /// /// There's definitely room to optimize here, but it works for now. #[inline(always)] -pub fn load_or_register_class(superclass_name: &'static str, subclass_name: &'static str, config: F) -> *const Class +pub fn load_or_register_class(superclass_name: &'static str, subclass_name: &'static str, config: F) -> &'static Class where F: Fn(&mut ClassDecl) + 'static { diff --git a/src/image/appkit.rs b/src/image/appkit.rs index a269041b..6be6f59b 100644 --- a/src/image/appkit.rs +++ b/src/image/appkit.rs @@ -22,8 +22,8 @@ use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR}; /// Injects an `NSView` subclass. This is used for the default views that don't use delegates - we /// have separate classes here since we don't want to waste cycles on methods that will never be /// used if there's no delegates. -pub(crate) fn register_image_view_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_image_view_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -32,8 +32,8 @@ pub(crate) fn register_image_view_class() -> *const Class { //decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(_, _) -> _); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } diff --git a/src/image/mod.rs b/src/image/mod.rs index bbf07958..7806cfb8 100644 --- a/src/image/mod.rs +++ b/src/image/mod.rs @@ -32,7 +32,7 @@ mod icons; pub use icons::*; /// A helper method for instantiating view classes and applying default settings to them. -fn allocate_view(registration_fn: fn() -> *const Class) -> id { +fn allocate_view(registration_fn: fn() -> &'static Class) -> id { unsafe { let view: id = msg_send![registration_fn(), new]; diff --git a/src/image/uikit.rs b/src/image/uikit.rs index d8dd60ac..0550447f 100644 --- a/src/image/uikit.rs +++ b/src/image/uikit.rs @@ -12,15 +12,15 @@ use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR}; /// Injects an `NSView` subclass. This is used for the default views that don't use delegates - we /// have separate classes here since we don't want to waste cycles on methods that will never be /// used if there's no delegates. -pub(crate) fn register_image_view_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_image_view_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(UIImageView); let mut decl = ClassDecl::new("RSTImageView", superclass).expect("Failed to get RSTVIEW"); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } diff --git a/src/input/appkit.rs b/src/input/appkit.rs index 11417cda..373cf9b3 100644 --- a/src/input/appkit.rs +++ b/src/input/appkit.rs @@ -51,22 +51,22 @@ extern "C" fn text_should_end_editing(this: &mut Object, _ /// Injects an `NSTextField` subclass. This is used for the default views that don't use delegates - we /// have separate classes here since we don't want to waste cycles on methods that will never be /// used if there's no delegates. -pub(crate) fn register_view_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_view_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(NSTextField); let decl = ClassDecl::new("RSTTextInputField", superclass).unwrap(); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } /// Injects an `NSTextField` subclass, with some callback and pointer ivars for what we /// need to do. -pub(crate) fn register_view_class_with_delegate(instance: &T) -> *const Class { +pub(crate) fn register_view_class_with_delegate(instance: &T) -> &'static Class { load_or_register_class("NSTextField", instance.subclass_name(), |decl| unsafe { // A pointer to the "view controller" on the Rust side. It's expected that this doesn't // move. diff --git a/src/input/mod.rs b/src/input/mod.rs index a294c1b7..40b07411 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -78,7 +78,7 @@ pub use traits::TextFieldDelegate; pub(crate) static TEXTFIELD_DELEGATE_PTR: &str = "rstTextFieldDelegatePtr"; /// A helper method for instantiating view classes and applying default settings to them. -fn common_init(class: *const Class) -> id { +fn common_init(class: &Class) -> id { unsafe { let view: id = msg_send![class, new]; diff --git a/src/invoker.rs b/src/invoker.rs index 173fa08a..ecc91912 100644 --- a/src/invoker.rs +++ b/src/invoker.rs @@ -94,8 +94,8 @@ extern "C" fn perform(this: &mut Object, _: Sel, _sender: id) /// The `NSButton` owns this object on instantiation, and will release it /// on drop. We handle the heap copy on the Rust side, so setting the block /// is just an ivar. -pub(crate) fn register_invoker_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_invoker_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -105,8 +105,8 @@ pub(crate) fn register_invoker_class() -> *const Class { decl.add_ivar::(ACTION_CALLBACK_PTR); decl.add_method(sel!(perform:), perform:: as extern "C" fn(_, _, _)); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } diff --git a/src/listview/appkit.rs b/src/listview/appkit.rs index 45c3cf83..49af6fa3 100644 --- a/src/listview/appkit.rs +++ b/src/listview/appkit.rs @@ -184,24 +184,24 @@ extern "C" fn dragging_exited(this: &mut Object, _: Sel, in /// need to do. Note that we treat and constrain this as a one-column "list" view to match /// `UITableView` semantics; if `NSTableView`'s multi column behavior is needed, then it can /// be added in. -pub(crate) fn register_listview_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_listview_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(NSTableView); let decl = ClassDecl::new("RSTListView", superclass).unwrap(); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } /// Injects an `NSTableView` subclass, with some callback and pointer ivars for what we /// need to do. Note that we treat and constrain this as a one-column "list" view to match /// `UITableView` semantics; if `NSTableView`'s multi column behavior is needed, then it can /// be added in. -pub(crate) fn register_listview_class_with_delegate(instance: &T) -> *const Class { +pub(crate) fn register_listview_class_with_delegate(instance: &T) -> &'static Class { load_or_register_class("NSTableView", instance.subclass_name(), |decl| unsafe { decl.add_ivar::(LISTVIEW_DELEGATE_PTR); diff --git a/src/listview/mod.rs b/src/listview/mod.rs index 4b924e4e..b3d91e69 100644 --- a/src/listview/mod.rs +++ b/src/listview/mod.rs @@ -100,7 +100,7 @@ use std::cell::RefCell; use std::rc::Rc; /// A helper method for instantiating view classes and applying default settings to them. -fn common_init(class: *const Class) -> id { +fn common_init(class: &Class) -> id { unsafe { // Note: we do *not* enable AutoLayout here as we're by default placing this in a scroll // view, and we want it to just do its thing. diff --git a/src/listview/row/appkit.rs b/src/listview/row/appkit.rs index a3487baf..81318b94 100644 --- a/src/listview/row/appkit.rs +++ b/src/listview/row/appkit.rs @@ -106,8 +106,8 @@ extern "C" fn dealloc(this: &Object, _: Sel) { /// Injects an `NSView` subclass. This is used for the default views that don't use delegates - we /// have separate classes here since we don't want to waste cycles on methods that will never be /// used if there's no delegates. -pub(crate) fn register_listview_row_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_listview_row_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -116,16 +116,16 @@ pub(crate) fn register_listview_row_class() -> *const Class { decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(_, _) -> _); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } /// Injects an `NSView` subclass, with some callback and pointer ivars for what we /// need to do. -pub(crate) fn register_listview_row_class_with_delegate() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_listview_row_class_with_delegate() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -159,8 +159,8 @@ pub(crate) fn register_listview_row_class_with_delegate() -> *c // Cleanup decl.add_method(sel!(dealloc), dealloc:: as extern "C" fn(_, _)); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } diff --git a/src/listview/row/mod.rs b/src/listview/row/mod.rs index 782942bf..e221688d 100644 --- a/src/listview/row/mod.rs +++ b/src/listview/row/mod.rs @@ -76,7 +76,7 @@ pub(crate) static BACKGROUND_COLOR: &str = "cacaoBackgroundColor"; pub(crate) static LISTVIEW_ROW_DELEGATE_PTR: &str = "cacaoListViewRowDelegatePtr"; /// A helper method for instantiating view classes and applying default settings to them. -fn allocate_view(registration_fn: fn() -> *const Class) -> id { +fn allocate_view(registration_fn: fn() -> &'static Class) -> id { unsafe { let view: id = msg_send![registration_fn(), new]; diff --git a/src/listview/row/uikit.rs b/src/listview/row/uikit.rs index 70a36563..3f21d840 100644 --- a/src/listview/row/uikit.rs +++ b/src/listview/row/uikit.rs @@ -13,33 +13,31 @@ use crate::utils::load; /// Injects an `NSView` subclass. This is used for the default views that don't use delegates - we /// have separate classes here since we don't want to waste cycles on methods that will never be /// used if there's no delegates. -pub(crate) fn register_view_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_view_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(UIView); let mut decl = ClassDecl::new("RSTView", superclass).unwrap(); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } /// Injects an `NSView` subclass, with some callback and pointer ivars for what we /// need to do. -pub(crate) fn register_view_class_with_delegate() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_view_class_with_delegate() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(UIView); let mut decl = ClassDecl::new("RSTViewWithDelegate", superclass).unwrap(); decl.add_ivar::(VIEW_DELEGATE_PTR); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { - VIEW_CLASS - } + unsafe { VIEW_CLASS.unwrap() } } diff --git a/src/scrollview/appkit.rs b/src/scrollview/appkit.rs index 012e5675..9b70fc36 100644 --- a/src/scrollview/appkit.rs +++ b/src/scrollview/appkit.rs @@ -76,23 +76,23 @@ extern "C" fn dragging_exited(this: &mut Object, _: Sel, } /// Injects an `NSScrollView` subclass. -pub(crate) fn register_scrollview_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_scrollview_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(NSScrollView); let decl = ClassDecl::new("RSTScrollView", superclass).unwrap(); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } /// Injects an `NSView` subclass, with some callback and pointer ivars for what we /// need to do. -pub(crate) fn register_scrollview_class_with_delegate() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_scrollview_class_with_delegate() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -121,8 +121,8 @@ pub(crate) fn register_scrollview_class_with_delegate() - ); decl.add_method(sel!(draggingExited:), dragging_exited:: as extern "C" fn(_, _, _)); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } diff --git a/src/scrollview/mod.rs b/src/scrollview/mod.rs index e1968f85..28607949 100644 --- a/src/scrollview/mod.rs +++ b/src/scrollview/mod.rs @@ -76,7 +76,7 @@ pub use traits::ScrollViewDelegate; pub(crate) static SCROLLVIEW_DELEGATE_PTR: &str = "rstScrollViewDelegatePtr"; /// A helper method for instantiating view classes and applying default settings to them. -fn allocate_view(registration_fn: fn() -> *const Class) -> id { +fn allocate_view(registration_fn: fn() -> &'static Class) -> id { unsafe { let view: id = msg_send![registration_fn(), new]; diff --git a/src/select/mod.rs b/src/select/mod.rs index c32bd84c..3d7b9c26 100644 --- a/src/select/mod.rs +++ b/src/select/mod.rs @@ -267,15 +267,15 @@ impl Drop for Select { /// Registers an `NSSelect` subclass, and configures it to hold some ivars /// for various things we need to store. -fn register_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +fn register_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(NSPopUpButton); let decl = ClassDecl::new("CacaoSelect", superclass).unwrap(); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } diff --git a/src/switch.rs b/src/switch.rs index 97e4d32f..c8499009 100644 --- a/src/switch.rs +++ b/src/switch.rs @@ -177,15 +177,15 @@ impl Drop for Switch { /// Registers an `NSButton` subclass, and configures it to hold some ivars /// for various things we need to store. -fn register_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +fn register_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(NSButton); let decl = ClassDecl::new("RSTSwitch", superclass).unwrap(); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } diff --git a/src/text/label/appkit.rs b/src/text/label/appkit.rs index c84d8c47..c4c9ab23 100644 --- a/src/text/label/appkit.rs +++ b/src/text/label/appkit.rs @@ -22,23 +22,23 @@ use crate::utils::load; /// Injects an `NSTextField` subclass. This is used for the default views that don't use delegates - we /// have separate classes here since we don't want to waste cycles on methods that will never be /// used if there's no delegates. -pub(crate) fn register_view_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_view_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(NSTextField); let decl = ClassDecl::new("RSTTextField", superclass).unwrap(); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } /// Injects an `NSTextField` subclass, with some callback and pointer ivars for what we /// need to do. -pub(crate) fn register_view_class_with_delegate() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_view_class_with_delegate() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -49,8 +49,8 @@ pub(crate) fn register_view_class_with_delegate() -> *const Cl // move. decl.add_ivar::(LABEL_DELEGATE_PTR); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } diff --git a/src/text/label/mod.rs b/src/text/label/mod.rs index e6c4adce..1b19a658 100644 --- a/src/text/label/mod.rs +++ b/src/text/label/mod.rs @@ -77,7 +77,7 @@ pub use traits::LabelDelegate; pub(crate) static LABEL_DELEGATE_PTR: &str = "rstLabelDelegatePtr"; /// A helper method for instantiating view classes and applying default settings to them. -fn allocate_view(registration_fn: fn() -> *const Class) -> id { +fn allocate_view(registration_fn: fn() -> &'static Class) -> id { unsafe { #[cfg(feature = "appkit")] let view: id = { diff --git a/src/uikit/app/class.rs b/src/uikit/app/class.rs index 3baf3502..5c590986 100644 --- a/src/uikit/app/class.rs +++ b/src/uikit/app/class.rs @@ -9,15 +9,15 @@ use objc::declare::ClassDecl; use objc::runtime::Class; /// Used for injecting a custom UIApplication. Currently does nothing. -pub(crate) fn register_app_class() -> *const Class { - static mut APP_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_app_class() -> &'static Class { + static mut APP_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(UIApplication); let decl = ClassDecl::new("RSTApplication", superclass).unwrap(); - APP_CLASS = decl.register(); + APP_CLASS = Some(decl.register()); }); - unsafe { APP_CLASS } + unsafe { APP_CLASS.unwrap() } } diff --git a/src/uikit/app/delegate.rs b/src/uikit/app/delegate.rs index fc636f3c..0040cbd4 100644 --- a/src/uikit/app/delegate.rs +++ b/src/uikit/app/delegate.rs @@ -48,8 +48,8 @@ extern "C" fn configuration_for_scene_session(this: &Object, _: /// Registers an `NSObject` application delegate, and configures it for the various callbacks and /// pointers we need to have. -pub(crate) fn register_app_delegate_class() -> *const Class { - static mut DELEGATE_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_app_delegate_class() -> &'static Class { + static mut DELEGATE_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -72,8 +72,8 @@ pub(crate) fn register_app_delegate_class() -> *const Class { did_discard_scene_sessions:: as extern "C" fn(_, _, _, _) );*/ - DELEGATE_CLASS = decl.register(); + DELEGATE_CLASS = Some(decl.register()); }); - unsafe { DELEGATE_CLASS } + unsafe { DELEGATE_CLASS.unwrap() } } diff --git a/src/uikit/scene/delegate.rs b/src/uikit/scene/delegate.rs index 9db97aa6..824e2485 100644 --- a/src/uikit/scene/delegate.rs +++ b/src/uikit/scene/delegate.rs @@ -59,8 +59,8 @@ extern "C" fn scene_will_connect_to_session_with_options /// Registers an `NSObject` application delegate, and configures it for the various callbacks and /// pointers we need to have. -pub(crate) fn register_window_scene_delegate_class Box>() -> *const Class { - static mut DELEGATE_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_window_scene_delegate_class Box>() -> &'static Class { + static mut DELEGATE_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -83,8 +83,8 @@ pub(crate) fn register_window_scene_delegate_class *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_view_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -105,15 +105,15 @@ pub(crate) fn register_view_class() -> *const Class { decl.add_ivar::(BACKGROUND_COLOR); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } /// Injects an `NSView` subclass, with some callback and pointer ivars for what we /// need to do. -pub(crate) fn register_view_class_with_delegate(instance: &T) -> *const Class { +pub(crate) fn register_view_class_with_delegate(instance: &T) -> &'static Class { load_or_register_class("NSView", instance.subclass_name(), |decl| unsafe { // A pointer to the ViewDelegate instance on the Rust side. // It's expected that this doesn't move. diff --git a/src/view/controller/appkit.rs b/src/view/controller/appkit.rs index 9aec40c7..4e7840b4 100644 --- a/src/view/controller/appkit.rs +++ b/src/view/controller/appkit.rs @@ -51,7 +51,7 @@ extern "C" fn did_disappear(this: &mut Object, _: Sel) { } /// Registers an `NSViewDelegate`. -pub(crate) fn register_view_controller_class(instance: &T) -> *const Class { +pub(crate) fn register_view_controller_class(instance: &T) -> &'static Class { load_or_register_class("NSViewController", instance.subclass_name(), |decl| unsafe { decl.add_ivar::(VIEW_DELEGATE_PTR); diff --git a/src/view/controller/uikit.rs b/src/view/controller/uikit.rs index a95f71b3..542a6adc 100644 --- a/src/view/controller/uikit.rs +++ b/src/view/controller/uikit.rs @@ -51,7 +51,7 @@ extern "C" fn did_disappear(this: &mut Object, _: Sel, animated } /// Registers an `NSViewDelegate`. -pub(crate) fn register_view_controller_class(instance: &T) -> *const Class { +pub(crate) fn register_view_controller_class(instance: &T) -> &'static Class { load_or_register_class("UIViewController", instance.subclass_name(), |decl| unsafe { decl.add_ivar::(VIEW_DELEGATE_PTR); diff --git a/src/view/splitviewcontroller/ios.rs b/src/view/splitviewcontroller/ios.rs index ff11dcf4..43ff36bd 100644 --- a/src/view/splitviewcontroller/ios.rs +++ b/src/view/splitviewcontroller/ios.rs @@ -50,8 +50,8 @@ extern "C" fn did_disappear(this: &mut Object, _: Sel, animated } /// Registers an `NSViewDelegate`. -pub(crate) fn register_view_controller_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_view_controller_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -65,8 +65,8 @@ pub(crate) fn register_view_controller_class() -> *co decl.add_method(sel!(viewWillDisappear:), will_disappear:: as extern "C" fn(_, _, _)); decl.add_method(sel!(viewDidDisappear:), did_disappear:: as extern "C" fn(_, _, _)); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } diff --git a/src/view/splitviewcontroller/macos.rs b/src/view/splitviewcontroller/macos.rs index a31d966b..e5005170 100644 --- a/src/view/splitviewcontroller/macos.rs +++ b/src/view/splitviewcontroller/macos.rs @@ -51,7 +51,7 @@ extern "C" fn did_disappear(this: &mut Object, _: Sel) { } /// Registers an `NSViewDelegate`. -pub(crate) fn register_view_controller_class(instance: &T) -> *const Class { +pub(crate) fn register_view_controller_class(instance: &T) -> &'static Class { load_or_register_class("NSViewController", instance.subclass_name(), |decl| unsafe { decl.add_ivar::(VIEW_DELEGATE_PTR); diff --git a/src/view/uikit.rs b/src/view/uikit.rs index e0d7b189..b0f358e7 100644 --- a/src/view/uikit.rs +++ b/src/view/uikit.rs @@ -13,22 +13,22 @@ use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR}; /// Injects an `NSView` subclass. This is used for the default views that don't use delegates - we /// have separate classes here since we don't want to waste cycles on methods that will never be /// used if there's no delegates. -pub(crate) fn register_view_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_view_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(UIView); let mut decl = ClassDecl::new("RSTView", superclass).unwrap(); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } /// Injects a `UIView` subclass, with some callback and pointer ivars for what we /// need to do. -pub(crate) fn register_view_class_with_delegate(instance: &T) -> *const Class { +pub(crate) fn register_view_class_with_delegate(instance: &T) -> &'static Class { load_or_register_class("UIView", instance.subclass_name(), |decl| unsafe { decl.add_ivar::(VIEW_DELEGATE_PTR); }) diff --git a/src/webview/class.rs b/src/webview/class.rs index a4cfc7ae..868bbe59 100644 --- a/src/webview/class.rs +++ b/src/webview/class.rs @@ -174,24 +174,24 @@ extern "C" fn handle_download(this: &Object, _: Sel, downloa /// Registers an `NSViewController` that we effectively turn into a `WebViewController`. Acts as /// both a subclass of `NSViewController` and a delegate of the held `WKWebView` (for the various /// varieties of delegates needed there). -pub fn register_webview_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub fn register_webview_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(WKWebView); let decl = ClassDecl::new("RSTWebView", superclass).unwrap(); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } /// Registers an `NSViewController` that we effectively turn into a `WebViewController`. Acts as /// both a subclass of `NSViewController` and a delegate of the held `WKWebView` (for the various /// varieties of delegates needed there). -pub fn register_webview_delegate_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub fn register_webview_delegate_class() -> &'static Class { + static mut VIEW_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -245,8 +245,8 @@ pub fn register_webview_delegate_class() -> *const Class { handle_download:: as extern "C" fn(_, _, _, _, _) ); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } }