Fixes possible duplicate objc class registration.

This can happen in environments like plugins, where cacao can exist multiple times and thus tries to create and register its objc classes more than once.
This commit is contained in:
Alexander Czernay 2023-04-16 10:47:32 +02:00
parent 1d76dce75f
commit 2803922f3a
24 changed files with 626 additions and 478 deletions

View file

@ -12,12 +12,17 @@ use objc::runtime::Class;
pub(crate) fn register_app_class() -> *const Class { pub(crate) fn register_app_class() -> *const Class {
static mut APP_CLASS: *const Class = 0 as *const Class; static mut APP_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTApplication";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { APP_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSApplication); let superclass = class!(NSApplication);
let decl = ClassDecl::new("RSTApplication", superclass).unwrap(); let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
APP_CLASS = decl.register(); APP_CLASS = decl.register();
}); });
}
unsafe { APP_CLASS } unsafe { APP_CLASS }
} }

View file

@ -297,10 +297,14 @@ extern "C" fn delegate_handles_key<T: AppDelegate>(this: &Object, _: Sel, _: id,
pub(crate) fn register_app_delegate_class<T: AppDelegate + AppDelegate>() -> *const Class { pub(crate) fn register_app_delegate_class<T: AppDelegate + AppDelegate>() -> *const Class {
static mut DELEGATE_CLASS: *const Class = 0 as *const Class; static mut DELEGATE_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTAppDelegate";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { DELEGATE_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSObject); let superclass = class!(NSObject);
let mut decl = ClassDecl::new("RSTAppDelegate", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
decl.add_ivar::<usize>(APP_PTR); decl.add_ivar::<usize>(APP_PTR);
@ -464,6 +468,7 @@ pub(crate) fn register_app_delegate_class<T: AppDelegate + AppDelegate>() -> *co
DELEGATE_CLASS = decl.register(); DELEGATE_CLASS = decl.register();
}); });
}
unsafe { DELEGATE_CLASS } unsafe { DELEGATE_CLASS }
} }

View file

@ -316,10 +316,14 @@ extern "C" fn fire_block_action(this: &Object, _: Sel, _item: id) {
pub(crate) fn register_menu_item_class() -> *const Class { pub(crate) fn register_menu_item_class() -> *const Class {
static mut APP_CLASS: *const Class = 0 as *const Class; static mut APP_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "CacaoMenuItem";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { APP_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSMenuItem); let superclass = class!(NSMenuItem);
let mut decl = ClassDecl::new("CacaoMenuItem", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
decl.add_ivar::<usize>(BLOCK_PTR); decl.add_ivar::<usize>(BLOCK_PTR);
decl.add_method(sel!(dealloc), dealloc_cacao_menuitem as extern "C" fn(&Object, _)); decl.add_method(sel!(dealloc), dealloc_cacao_menuitem as extern "C" fn(&Object, _));
@ -327,6 +331,7 @@ pub(crate) fn register_menu_item_class() -> *const Class {
APP_CLASS = decl.register(); APP_CLASS = decl.register();
}); });
}
unsafe { APP_CLASS } unsafe { APP_CLASS }
} }

View file

@ -14,13 +14,18 @@ use crate::appkit::window::{WindowDelegate, WINDOW_DELEGATE_PTR};
pub(crate) fn register_window_controller_class<T: WindowDelegate>() -> *const Class { pub(crate) fn register_window_controller_class<T: WindowDelegate>() -> *const Class {
static mut DELEGATE_CLASS: *const Class = 0 as *const Class; static mut DELEGATE_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTWindowController";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { DELEGATE_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSWindowController); let superclass = class!(NSWindowController);
let mut decl = ClassDecl::new("RSTWindowController", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
decl.add_ivar::<usize>(WINDOW_DELEGATE_PTR); decl.add_ivar::<usize>(WINDOW_DELEGATE_PTR);
DELEGATE_CLASS = decl.register(); DELEGATE_CLASS = decl.register();
}); });
}
unsafe { DELEGATE_CLASS } unsafe { DELEGATE_CLASS }
} }

View file

@ -345,12 +345,18 @@ impl Drop for Button {
fn register_class() -> *const Class { fn register_class() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTButton";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe {
VIEW_CLASS = c;
}
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSButton); let superclass = class!(NSButton);
let decl = ClassDecl::new("RSTButton", superclass).unwrap(); let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -261,10 +261,14 @@ extern "C" fn color_with_system_effect(this: &Object, _: Sel, effect: NSInteger)
pub(crate) fn register_class() -> *const Class { pub(crate) fn register_class() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "CacaoDynamicColor";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSColor); let superclass = class!(NSColor);
let mut decl = ClassDecl::new("CacaoDynamicColor", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
// These methods all need to be forwarded, so let's hook them up. // These methods all need to be forwarded, so let's hook them up.
decl.add_method(sel!(colorSpace), color_space as extern "C" fn(&Object, _) -> id); decl.add_method(sel!(colorSpace), color_space as extern "C" fn(&Object, _) -> id);
@ -362,6 +366,7 @@ pub(crate) fn register_class() -> *const Class {
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -25,15 +25,20 @@ use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR};
pub(crate) fn register_image_view_class() -> *const Class { pub(crate) fn register_image_view_class() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTImageView";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSImageView); let superclass = class!(NSImageView);
let decl = ClassDecl::new("RSTImageView", superclass).unwrap(); let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
//decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL); //decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL);
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -15,12 +15,17 @@ use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR};
pub(crate) fn register_image_view_class() -> *const Class { pub(crate) fn register_image_view_class() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTImageView";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(UIImageView); let superclass = class!(UIImageView);
let mut decl = ClassDecl::new("RSTImageView", superclass).expect("Failed to get RSTVIEW"); let mut decl = ClassDecl::new(CLASS_NAME, superclass).expect("Failed to get RSTVIEW");
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -54,12 +54,17 @@ extern "C" fn text_should_end_editing<T: TextFieldDelegate>(this: &mut Object, _
pub(crate) fn register_view_class() -> *const Class { pub(crate) fn register_view_class() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTTextInputField";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSTextField); let superclass = class!(NSTextField);
let decl = ClassDecl::new("RSTTextInputField", superclass).unwrap(); let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -97,16 +97,23 @@ extern "C" fn perform<F: Fn() + 'static>(this: &mut Object, _: Sel, _sender: id)
pub(crate) fn register_invoker_class<F: Fn() + 'static>() -> *const Class { pub(crate) fn register_invoker_class<F: Fn() + 'static>() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTTargetActionHandler";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe {
VIEW_CLASS = c;
}
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSObject); let superclass = class!(NSObject);
let mut decl = ClassDecl::new("RSTTargetActionHandler", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
decl.add_ivar::<usize>(ACTION_CALLBACK_PTR); decl.add_ivar::<usize>(ACTION_CALLBACK_PTR);
decl.add_method(sel!(perform:), perform::<F> as extern "C" fn(&mut Object, _, id)); decl.add_method(sel!(perform:), perform::<F> as extern "C" fn(&mut Object, _, id));
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -187,12 +187,17 @@ extern "C" fn dragging_exited<T: ListViewDelegate>(this: &mut Object, _: Sel, in
pub(crate) fn register_listview_class() -> *const Class { pub(crate) fn register_listview_class() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &'static str = "RSTListView";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSTableView); let superclass = class!(NSTableView);
let decl = ClassDecl::new("RSTListView", superclass).unwrap(); let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -109,15 +109,20 @@ extern "C" fn dealloc<T: ViewDelegate>(this: &Object, _: Sel) {
pub(crate) fn register_listview_row_class() -> *const Class { pub(crate) fn register_listview_row_class() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTTableViewRow";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSView); let superclass = class!(NSView);
let mut decl = ClassDecl::new("RSTTableViewRow", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL); decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL);
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }
@ -127,10 +132,14 @@ pub(crate) fn register_listview_row_class() -> *const Class {
pub(crate) fn register_listview_row_class_with_delegate<T: ViewDelegate>() -> *const Class { pub(crate) fn register_listview_row_class_with_delegate<T: ViewDelegate>() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTableViewRowWithDelegate";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSView); let superclass = class!(NSView);
let mut decl = ClassDecl::new("RSTableViewRowWithDelegate", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't // A pointer to the "view controller" on the Rust side. It's expected that this doesn't
// move. // move.
@ -167,6 +176,7 @@ pub(crate) fn register_listview_row_class_with_delegate<T: ViewDelegate>() -> *c
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -16,12 +16,17 @@ use crate::utils::load;
pub(crate) fn register_view_class() -> *const Class { pub(crate) fn register_view_class() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTView";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(UIView); let superclass = class!(UIView);
let mut decl = ClassDecl::new("RSTView", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }
@ -31,15 +36,18 @@ pub(crate) fn register_view_class() -> *const Class {
pub(crate) fn register_view_class_with_delegate<T: ViewDelegate>() -> *const Class { pub(crate) fn register_view_class_with_delegate<T: ViewDelegate>() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTViewWithDelegate";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(UIView); let superclass = class!(UIView);
let mut decl = ClassDecl::new("RSTViewWithDelegate", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
decl.add_ivar::<usize>(VIEW_DELEGATE_PTR); decl.add_ivar::<usize>(VIEW_DELEGATE_PTR);
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { unsafe { VIEW_CLASS }
VIEW_CLASS
}
} }

View file

@ -79,12 +79,17 @@ extern "C" fn dragging_exited<T: ScrollViewDelegate>(this: &mut Object, _: Sel,
pub(crate) fn register_scrollview_class() -> *const Class { pub(crate) fn register_scrollview_class() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &'static str = "RSTScrollView";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSScrollView); let superclass = class!(NSScrollView);
let decl = ClassDecl::new("RSTScrollView", superclass).unwrap(); let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }
@ -94,10 +99,14 @@ pub(crate) fn register_scrollview_class() -> *const Class {
pub(crate) fn register_scrollview_class_with_delegate<T: ScrollViewDelegate>() -> *const Class { pub(crate) fn register_scrollview_class_with_delegate<T: ScrollViewDelegate>() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &'static str = "RSTScrollViewWithDelegate";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSScrollView); let superclass = class!(NSScrollView);
let mut decl = ClassDecl::new("RSTScrollViewWithDelegate", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't // A pointer to the "view controller" on the Rust side. It's expected that this doesn't
// move. // move.
@ -129,6 +138,7 @@ pub(crate) fn register_scrollview_class_with_delegate<T: ScrollViewDelegate>() -
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -270,12 +270,17 @@ impl Drop for Select {
fn register_class() -> *const Class { fn register_class() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "CacaoSelect";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSPopUpButton); let superclass = class!(NSPopUpButton);
let decl = ClassDecl::new("CacaoSelect", superclass).unwrap(); let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -180,12 +180,19 @@ impl Drop for Switch {
fn register_class() -> *const Class { fn register_class() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTSwitch";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe {
VIEW_CLASS = c;
}
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSButton); let superclass = class!(NSButton);
let decl = ClassDecl::new("RSTSwitch", superclass).unwrap(); let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -25,12 +25,17 @@ use crate::utils::load;
pub(crate) fn register_view_class() -> *const Class { pub(crate) fn register_view_class() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTTextField";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSTextField); let superclass = class!(NSTextField);
let decl = ClassDecl::new("RSTTextField", superclass).unwrap(); let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }
@ -40,10 +45,14 @@ pub(crate) fn register_view_class() -> *const Class {
pub(crate) fn register_view_class_with_delegate<T: LabelDelegate>() -> *const Class { pub(crate) fn register_view_class_with_delegate<T: LabelDelegate>() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTTextFieldWithDelegate";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSView); let superclass = class!(NSView);
let mut decl = ClassDecl::new("RSTTextFieldWithDelegate", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't // A pointer to the "view controller" on the Rust side. It's expected that this doesn't
// move. // move.
@ -51,6 +60,7 @@ pub(crate) fn register_view_class_with_delegate<T: LabelDelegate>() -> *const Cl
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -12,12 +12,17 @@ use objc::runtime::Class;
pub(crate) fn register_app_class() -> *const Class { pub(crate) fn register_app_class() -> *const Class {
static mut APP_CLASS: *const Class = 0 as *const Class; static mut APP_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTApplication";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { APP_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(UIApplication); let superclass = class!(UIApplication);
let decl = ClassDecl::new("RSTApplication", superclass).unwrap(); let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
APP_CLASS = decl.register(); APP_CLASS = decl.register();
}); });
}
unsafe { APP_CLASS } unsafe { APP_CLASS }
} }

View file

@ -51,10 +51,14 @@ extern "C" fn configuration_for_scene_session<T: AppDelegate>(this: &Object, _:
pub(crate) fn register_app_delegate_class<T: AppDelegate>() -> *const Class { pub(crate) fn register_app_delegate_class<T: AppDelegate>() -> *const Class {
static mut DELEGATE_CLASS: *const Class = 0 as *const Class; static mut DELEGATE_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTAppDelegate";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { DELEGATE_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSObject); let superclass = class!(NSObject);
let mut decl = ClassDecl::new("RSTAppDelegate", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
// Launching Applications // Launching Applications
decl.add_method( decl.add_method(
@ -74,6 +78,7 @@ pub(crate) fn register_app_delegate_class<T: AppDelegate>() -> *const Class {
DELEGATE_CLASS = decl.register(); DELEGATE_CLASS = decl.register();
}); });
}
unsafe { DELEGATE_CLASS } unsafe { DELEGATE_CLASS }
} }

View file

@ -62,11 +62,15 @@ extern "C" fn scene_will_connect_to_session_with_options<T: WindowSceneDelegate>
pub(crate) fn register_window_scene_delegate_class<T: WindowSceneDelegate, F: Fn() -> Box<T>>() -> *const Class { pub(crate) fn register_window_scene_delegate_class<T: WindowSceneDelegate, F: Fn() -> Box<T>>() -> *const Class {
static mut DELEGATE_CLASS: *const Class = 0 as *const Class; static mut DELEGATE_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTWindowSceneDelegate";
use objc::runtime::{class_addProtocol, Protocol}; if let Some(c) = Class::get(CLASS_NAME) {
unsafe { DELEGATE_CLASS = c };
} else {
use objc::runtime::Protocol;
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(UIResponder); let superclass = class!(UIResponder);
let mut decl = ClassDecl::new("RSTWindowSceneDelegate", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
let p = Protocol::get("UIWindowSceneDelegate").unwrap(); let p = Protocol::get("UIWindowSceneDelegate").unwrap();
@ -86,6 +90,7 @@ pub(crate) fn register_window_scene_delegate_class<T: WindowSceneDelegate, F: Fn
// Launching Applications // Launching Applications
DELEGATE_CLASS = decl.register(); DELEGATE_CLASS = decl.register();
}); });
}
unsafe { DELEGATE_CLASS } unsafe { DELEGATE_CLASS }
} }

View file

@ -94,10 +94,14 @@ extern "C" fn update_layer(this: &Object, _: Sel) {
pub(crate) fn register_view_class() -> *const Class { pub(crate) fn register_view_class() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTView";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(NSView); let superclass = class!(NSView);
let mut decl = ClassDecl::new("RSTView", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL); decl.add_method(sel!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL);
decl.add_method(sel!(updateLayer), update_layer as extern "C" fn(&Object, _)); decl.add_method(sel!(updateLayer), update_layer as extern "C" fn(&Object, _));
@ -107,6 +111,7 @@ pub(crate) fn register_view_class() -> *const Class {
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -53,20 +53,30 @@ extern "C" fn did_disappear<T: ViewDelegate>(this: &mut Object, _: Sel, animated
pub(crate) fn register_view_controller_class<T: ViewDelegate + 'static>() -> *const Class { pub(crate) fn register_view_controller_class<T: ViewDelegate + 'static>() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTViewController";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(UIViewController); let superclass = class!(UIViewController);
let mut decl = ClassDecl::new("RSTViewController", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
decl.add_ivar::<usize>(VIEW_DELEGATE_PTR); decl.add_ivar::<usize>(VIEW_DELEGATE_PTR);
decl.add_method(sel!(viewWillAppear:), will_appear::<T> as extern "C" fn(&mut Object, _, BOOL)); decl.add_method(sel!(viewWillAppear:), will_appear::<T> as extern "C" fn(&mut Object, _, BOOL));
decl.add_method(sel!(viewDidAppear:), did_appear::<T> as extern "C" fn(&mut Object, _, BOOL)); decl.add_method(sel!(viewDidAppear:), did_appear::<T> as extern "C" fn(&mut Object, _, BOOL));
decl.add_method(sel!(viewWillDisappear:), will_disappear::<T> as extern "C" fn(&mut Object, _, BOOL)); decl.add_method(
decl.add_method(sel!(viewDidDisappear:), did_disappear::<T> as extern "C" fn(&mut Object, _, BOOL)); sel!(viewWillDisappear:),
will_disappear::<T> as extern "C" fn(&mut Object, _, BOOL)
);
decl.add_method(
sel!(viewDidDisappear:),
did_disappear::<T> as extern "C" fn(&mut Object, _, BOOL)
);
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -16,12 +16,17 @@ use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR};
pub(crate) fn register_view_class() -> *const Class { pub(crate) fn register_view_class() -> *const Class {
static mut VIEW_CLASS: *const Class = 0 as *const Class; static mut VIEW_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTView";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { VIEW_CLASS = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = class!(UIView); let superclass = class!(UIView);
let mut decl = ClassDecl::new("RSTView", superclass).unwrap(); let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap();
VIEW_CLASS = decl.register(); VIEW_CLASS = decl.register();
}); });
}
unsafe { VIEW_CLASS } unsafe { VIEW_CLASS }
} }

View file

@ -28,7 +28,11 @@ extern "C" fn download_delegate(this: &Object, _: Sel) -> id {
pub fn register_process_pool() -> *const Object { pub fn register_process_pool() -> *const Object {
static mut PROCESS_POOL: *const Object = 0 as *const Object; static mut PROCESS_POOL: *const Object = 0 as *const Object;
static INIT: Once = Once::new(); static INIT: Once = Once::new();
const CLASS_NAME: &str = "RSTWebViewProcessPool";
if let Some(c) = Class::get(CLASS_NAME) {
unsafe { PROCESS_POOL = c };
} else {
INIT.call_once(|| unsafe { INIT.call_once(|| unsafe {
let superclass = Class::get("WKProcessPool").unwrap(); let superclass = Class::get("WKProcessPool").unwrap();
let mut decl = ClassDecl::new("RSTWebViewProcessPool", superclass).unwrap(); let mut decl = ClassDecl::new("RSTWebViewProcessPool", superclass).unwrap();
@ -39,6 +43,7 @@ pub fn register_process_pool() -> *const Object {
//PROCESS_POOL = decl.register(); //PROCESS_POOL = decl.register();
PROCESS_POOL = msg_send![decl.register(), new]; PROCESS_POOL = msg_send![decl.register(), new];
}); });
}
unsafe { PROCESS_POOL } unsafe { PROCESS_POOL }
} }