diff --git a/src/appkit/app/class.rs b/src/appkit/app/class.rs index e53885f..2b46ae7 100644 --- a/src/appkit/app/class.rs +++ b/src/appkit/app/class.rs @@ -12,12 +12,17 @@ use objc::runtime::Class; pub(crate) fn register_app_class() -> *const Class { static mut APP_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTApplication"; - INIT.call_once(|| unsafe { - let superclass = class!(NSApplication); - let decl = ClassDecl::new("RSTApplication", superclass).unwrap(); - APP_CLASS = decl.register(); - }); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { APP_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSApplication); + let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); + APP_CLASS = decl.register(); + }); + } unsafe { APP_CLASS } } diff --git a/src/appkit/app/delegate.rs b/src/appkit/app/delegate.rs index 45cf6d9..d5e2069 100644 --- a/src/appkit/app/delegate.rs +++ b/src/appkit/app/delegate.rs @@ -297,173 +297,178 @@ extern "C" fn delegate_handles_key(this: &Object, _: Sel, _: id, pub(crate) fn register_app_delegate_class() -> *const Class { static mut DELEGATE_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTAppDelegate"; - INIT.call_once(|| unsafe { - let superclass = class!(NSObject); - let mut decl = ClassDecl::new("RSTAppDelegate", superclass).unwrap(); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { DELEGATE_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSObject); + let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); - decl.add_ivar::(APP_PTR); + decl.add_ivar::(APP_PTR); - // Launching Applications - decl.add_method( - sel!(applicationWillFinishLaunching:), - will_finish_launching:: as extern "C" fn(&Object, _, _) - ); - decl.add_method( - sel!(applicationDidFinishLaunching:), - did_finish_launching:: as extern "C" fn(&Object, _, _) - ); + // Launching Applications + decl.add_method( + sel!(applicationWillFinishLaunching:), + will_finish_launching:: as extern "C" fn(&Object, _, _) + ); + decl.add_method( + sel!(applicationDidFinishLaunching:), + did_finish_launching:: as extern "C" fn(&Object, _, _) + ); - // Managing Active Status - decl.add_method( - sel!(applicationWillBecomeActive:), - will_become_active:: as extern "C" fn(&Object, _, _) - ); - decl.add_method( - sel!(applicationDidBecomeActive:), - did_become_active:: as extern "C" fn(&Object, _, _) - ); - decl.add_method( - sel!(applicationWillResignActive:), - will_resign_active:: as extern "C" fn(&Object, _, _) - ); - decl.add_method( - sel!(applicationDidResignActive:), - did_resign_active:: as extern "C" fn(&Object, _, _) - ); + // Managing Active Status + decl.add_method( + sel!(applicationWillBecomeActive:), + will_become_active:: as extern "C" fn(&Object, _, _) + ); + decl.add_method( + sel!(applicationDidBecomeActive:), + did_become_active:: as extern "C" fn(&Object, _, _) + ); + decl.add_method( + sel!(applicationWillResignActive:), + will_resign_active:: as extern "C" fn(&Object, _, _) + ); + decl.add_method( + sel!(applicationDidResignActive:), + did_resign_active:: as extern "C" fn(&Object, _, _) + ); - // Terminating Applications - decl.add_method( - sel!(applicationShouldTerminate:), - should_terminate:: as extern "C" fn(&Object, _, _) -> NSUInteger - ); - decl.add_method( - sel!(applicationWillTerminate:), - will_terminate:: as extern "C" fn(&Object, _, _) - ); - decl.add_method( - sel!(applicationShouldTerminateAfterLastWindowClosed:), - should_terminate_after_last_window_closed:: as extern "C" fn(&Object, _, _) -> BOOL - ); + // Terminating Applications + decl.add_method( + sel!(applicationShouldTerminate:), + should_terminate:: as extern "C" fn(&Object, _, _) -> NSUInteger + ); + decl.add_method( + sel!(applicationWillTerminate:), + will_terminate:: as extern "C" fn(&Object, _, _) + ); + decl.add_method( + sel!(applicationShouldTerminateAfterLastWindowClosed:), + should_terminate_after_last_window_closed:: as extern "C" fn(&Object, _, _) -> BOOL + ); - // Hiding Applications - decl.add_method(sel!(applicationWillHide:), will_hide:: as extern "C" fn(&Object, _, _)); - decl.add_method(sel!(applicationDidHide:), did_hide:: as extern "C" fn(&Object, _, _)); - decl.add_method(sel!(applicationWillUnhide:), will_unhide:: as extern "C" fn(&Object, _, _)); - decl.add_method(sel!(applicationDidUnhide:), did_unhide:: as extern "C" fn(&Object, _, _)); + // Hiding Applications + decl.add_method(sel!(applicationWillHide:), will_hide:: as extern "C" fn(&Object, _, _)); + decl.add_method(sel!(applicationDidHide:), did_hide:: as extern "C" fn(&Object, _, _)); + decl.add_method(sel!(applicationWillUnhide:), will_unhide:: as extern "C" fn(&Object, _, _)); + decl.add_method(sel!(applicationDidUnhide:), did_unhide:: as extern "C" fn(&Object, _, _)); - // Managing Windows - decl.add_method(sel!(applicationWillUpdate:), will_update:: as extern "C" fn(&Object, _, _)); - decl.add_method(sel!(applicationDidUpdate:), did_update:: as extern "C" fn(&Object, _, _)); - decl.add_method( - sel!(applicationShouldHandleReopen:hasVisibleWindows:), - should_handle_reopen:: as extern "C" fn(&Object, _, _, BOOL) -> BOOL - ); + // Managing Windows + decl.add_method(sel!(applicationWillUpdate:), will_update:: as extern "C" fn(&Object, _, _)); + decl.add_method(sel!(applicationDidUpdate:), did_update:: as extern "C" fn(&Object, _, _)); + decl.add_method( + sel!(applicationShouldHandleReopen:hasVisibleWindows:), + should_handle_reopen:: as extern "C" fn(&Object, _, _, BOOL) -> BOOL + ); - // Dock Menu - decl.add_method( - sel!(applicationDockMenu:), - dock_menu:: as extern "C" fn(&Object, _, _) -> id - ); + // Dock Menu + decl.add_method( + sel!(applicationDockMenu:), + dock_menu:: as extern "C" fn(&Object, _, _) -> id + ); - // Displaying Errors - decl.add_method( - sel!(application:willPresentError:), - will_present_error:: as extern "C" fn(&Object, _, _, id) -> id - ); + // Displaying Errors + decl.add_method( + sel!(application:willPresentError:), + will_present_error:: as extern "C" fn(&Object, _, _, id) -> id + ); - // Managing the Screen - decl.add_method( - sel!(applicationDidChangeScreenParameters:), - did_change_screen_parameters:: as extern "C" fn(&Object, _, _) - ); - decl.add_method( - sel!(applicationDidChangeOcclusionState:), - did_change_occlusion_state:: as extern "C" fn(&Object, _, _) - ); + // Managing the Screen + decl.add_method( + sel!(applicationDidChangeScreenParameters:), + did_change_screen_parameters:: as extern "C" fn(&Object, _, _) + ); + decl.add_method( + sel!(applicationDidChangeOcclusionState:), + did_change_occlusion_state:: as extern "C" fn(&Object, _, _) + ); - // User Activities - decl.add_method( - sel!(application:willContinueUserActivityWithType:), - will_continue_user_activity_with_type:: as extern "C" fn(&Object, _, _, id) -> BOOL - ); - decl.add_method( - sel!(application:continueUserActivity:restorationHandler:), - continue_user_activity:: as extern "C" fn(&Object, _, _, id, id) -> BOOL - ); - decl.add_method( - sel!(application:didFailToContinueUserActivityWithType:error:), - failed_to_continue_user_activity:: as extern "C" fn(&Object, _, _, id, id) - ); - decl.add_method( - sel!(application:didUpdateUserActivity:), - did_update_user_activity:: as extern "C" fn(&Object, _, _, id) - ); + // User Activities + decl.add_method( + sel!(application:willContinueUserActivityWithType:), + will_continue_user_activity_with_type:: as extern "C" fn(&Object, _, _, id) -> BOOL + ); + decl.add_method( + sel!(application:continueUserActivity:restorationHandler:), + continue_user_activity:: as extern "C" fn(&Object, _, _, id, id) -> BOOL + ); + decl.add_method( + sel!(application:didFailToContinueUserActivityWithType:error:), + failed_to_continue_user_activity:: as extern "C" fn(&Object, _, _, id, id) + ); + decl.add_method( + sel!(application:didUpdateUserActivity:), + did_update_user_activity:: as extern "C" fn(&Object, _, _, id) + ); - // Handling push notifications - decl.add_method( - sel!(application:didRegisterForRemoteNotificationsWithDeviceToken:), - registered_for_remote_notifications:: as extern "C" fn(&Object, _, _, id) - ); - decl.add_method( - sel!(application:didFailToRegisterForRemoteNotificationsWithError:), - failed_to_register_for_remote_notifications:: as extern "C" fn(&Object, _, _, id) - ); - decl.add_method( - sel!(application:didReceiveRemoteNotification:), - did_receive_remote_notification:: as extern "C" fn(&Object, _, _, id) - ); + // Handling push notifications + decl.add_method( + sel!(application:didRegisterForRemoteNotificationsWithDeviceToken:), + registered_for_remote_notifications:: as extern "C" fn(&Object, _, _, id) + ); + decl.add_method( + sel!(application:didFailToRegisterForRemoteNotificationsWithError:), + failed_to_register_for_remote_notifications:: as extern "C" fn(&Object, _, _, id) + ); + decl.add_method( + sel!(application:didReceiveRemoteNotification:), + did_receive_remote_notification:: as extern "C" fn(&Object, _, _, id) + ); - // CloudKit - #[cfg(feature = "cloudkit")] - decl.add_method( - sel!(application:userDidAcceptCloudKitShareWithMetadata:), - accepted_cloudkit_share:: as extern "C" fn(&Object, _, _, id) - ); + // CloudKit + #[cfg(feature = "cloudkit")] + decl.add_method( + sel!(application:userDidAcceptCloudKitShareWithMetadata:), + accepted_cloudkit_share:: as extern "C" fn(&Object, _, _, id) + ); - // Opening Files - decl.add_method( - sel!(application:openURLs:), - open_urls:: as extern "C" fn(&Object, _, _, id) - ); - decl.add_method( - sel!(application:openFileWithoutUI:), - open_file_without_ui:: as extern "C" fn(&Object, _, _, id) -> BOOL - ); - decl.add_method( - sel!(applicationShouldOpenUntitledFile:), - should_open_untitled_file:: as extern "C" fn(&Object, _, _) -> BOOL - ); - decl.add_method( - sel!(applicationOpenUntitledFile:), - open_untitled_file:: as extern "C" fn(&Object, _, _) -> BOOL - ); - decl.add_method( - sel!(application:openTempFile:), - open_temp_file:: as extern "C" fn(&Object, _, _, id) -> BOOL - ); + // Opening Files + decl.add_method( + sel!(application:openURLs:), + open_urls:: as extern "C" fn(&Object, _, _, id) + ); + decl.add_method( + sel!(application:openFileWithoutUI:), + open_file_without_ui:: as extern "C" fn(&Object, _, _, id) -> BOOL + ); + decl.add_method( + sel!(applicationShouldOpenUntitledFile:), + should_open_untitled_file:: as extern "C" fn(&Object, _, _) -> BOOL + ); + decl.add_method( + sel!(applicationOpenUntitledFile:), + open_untitled_file:: as extern "C" fn(&Object, _, _) -> BOOL + ); + decl.add_method( + sel!(application:openTempFile:), + open_temp_file:: as extern "C" fn(&Object, _, _, id) -> BOOL + ); - // Printing - decl.add_method( - sel!(application:printFile:), - print_file:: as extern "C" fn(&Object, _, _, id) -> BOOL - ); - decl.add_method( - sel!(application:printFiles:withSettings:showPrintPanels:), - print_files:: as extern "C" fn(&Object, _, id, id, id, BOOL) -> NSUInteger - ); + // Printing + decl.add_method( + sel!(application:printFile:), + print_file:: as extern "C" fn(&Object, _, _, id) -> BOOL + ); + decl.add_method( + sel!(application:printFiles:withSettings:showPrintPanels:), + print_files:: as extern "C" fn(&Object, _, id, id, id, BOOL) -> NSUInteger + ); - // @TODO: Restoring Application State - // Depends on NSCoder support, which is... welp. + // @TODO: Restoring Application State + // Depends on NSCoder support, which is... welp. - // Scripting - decl.add_method( - sel!(application:delegateHandlesKey:), - delegate_handles_key:: as extern "C" fn(&Object, _, _, id) -> BOOL - ); + // Scripting + decl.add_method( + sel!(application:delegateHandlesKey:), + delegate_handles_key:: as extern "C" fn(&Object, _, _, id) -> BOOL + ); - DELEGATE_CLASS = decl.register(); - }); + DELEGATE_CLASS = decl.register(); + }); + } unsafe { DELEGATE_CLASS } } diff --git a/src/appkit/menu/item.rs b/src/appkit/menu/item.rs index 3f65ed5..334ffa4 100644 --- a/src/appkit/menu/item.rs +++ b/src/appkit/menu/item.rs @@ -316,17 +316,22 @@ extern "C" fn fire_block_action(this: &Object, _: Sel, _item: id) { pub(crate) fn register_menu_item_class() -> *const Class { static mut APP_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "CacaoMenuItem"; - INIT.call_once(|| unsafe { - let superclass = class!(NSMenuItem); - let mut decl = ClassDecl::new("CacaoMenuItem", superclass).unwrap(); - decl.add_ivar::(BLOCK_PTR); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { APP_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSMenuItem); + let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); + decl.add_ivar::(BLOCK_PTR); - decl.add_method(sel!(dealloc), dealloc_cacao_menuitem as extern "C" fn(&Object, _)); - decl.add_method(sel!(fireBlockAction:), fire_block_action as extern "C" fn(&Object, _, id)); + decl.add_method(sel!(dealloc), dealloc_cacao_menuitem as extern "C" fn(&Object, _)); + decl.add_method(sel!(fireBlockAction:), fire_block_action as extern "C" fn(&Object, _, id)); - APP_CLASS = decl.register(); - }); + APP_CLASS = decl.register(); + }); + } unsafe { APP_CLASS } } diff --git a/src/appkit/window/controller/class.rs b/src/appkit/window/controller/class.rs index 2f9c914..f82c5d0 100644 --- a/src/appkit/window/controller/class.rs +++ b/src/appkit/window/controller/class.rs @@ -14,13 +14,18 @@ use crate::appkit::window::{WindowDelegate, WINDOW_DELEGATE_PTR}; pub(crate) fn register_window_controller_class() -> *const Class { static mut DELEGATE_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTWindowController"; - 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(); - }); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { DELEGATE_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSWindowController); + let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); + decl.add_ivar::(WINDOW_DELEGATE_PTR); + DELEGATE_CLASS = decl.register(); + }); + } unsafe { DELEGATE_CLASS } } diff --git a/src/button/mod.rs b/src/button/mod.rs index 822fb5c..979385d 100644 --- a/src/button/mod.rs +++ b/src/button/mod.rs @@ -345,12 +345,18 @@ impl Drop for Button { fn register_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTButton"; - INIT.call_once(|| unsafe { - let superclass = class!(NSButton); - let decl = ClassDecl::new("RSTButton", superclass).unwrap(); - VIEW_CLASS = decl.register(); - }); - + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { + VIEW_CLASS = c; + } + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSButton); + let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } diff --git a/src/color/appkit_dynamic_color.rs b/src/color/appkit_dynamic_color.rs index 6283350..6502614 100644 --- a/src/color/appkit_dynamic_color.rs +++ b/src/color/appkit_dynamic_color.rs @@ -261,107 +261,112 @@ extern "C" fn color_with_system_effect(this: &Object, _: Sel, effect: NSInteger) pub(crate) fn register_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "CacaoDynamicColor"; - INIT.call_once(|| unsafe { - let superclass = class!(NSColor); - let mut decl = ClassDecl::new("CacaoDynamicColor", superclass).unwrap(); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSColor); + let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); - // 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!(colorUsingColorSpace:), - color_using_color_space as extern "C" fn(&Object, _, id) -> id - ); - decl.add_method(sel!(colorSpaceName), color_space_name as extern "C" fn(&Object, _) -> id); - decl.add_method( - sel!(colorUsingColorSpaceName:), - color_using_color_space_name as extern "C" fn(&Object, _, id) -> id - ); - decl.add_method( - sel!(numberOfComponents), - number_of_components as extern "C" fn(&Object, _) -> NSInteger - ); + // 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!(colorUsingColorSpace:), + color_using_color_space as extern "C" fn(&Object, _, id) -> id + ); + decl.add_method(sel!(colorSpaceName), color_space_name as extern "C" fn(&Object, _) -> id); + decl.add_method( + sel!(colorUsingColorSpaceName:), + color_using_color_space_name as extern "C" fn(&Object, _, id) -> id + ); + decl.add_method( + sel!(numberOfComponents), + number_of_components as extern "C" fn(&Object, _) -> NSInteger + ); - decl.add_method(sel!(getComponents:), get_components as extern "C" fn(&Object, _, CGFloat)); - decl.add_method( - sel!(getRed:green:blue:alpha:), - get_rgba as extern "C" fn(&Object, _, CGFloat, CGFloat, CGFloat, CGFloat) - ); - decl.add_method(sel!(redComponent), red_component as extern "C" fn(&Object, _) -> CGFloat); - decl.add_method(sel!(greenComponent), green_component as extern "C" fn(&Object, _) -> CGFloat); - decl.add_method(sel!(blueComponent), blue_component as extern "C" fn(&Object, _) -> CGFloat); + decl.add_method(sel!(getComponents:), get_components as extern "C" fn(&Object, _, CGFloat)); + decl.add_method( + sel!(getRed:green:blue:alpha:), + get_rgba as extern "C" fn(&Object, _, CGFloat, CGFloat, CGFloat, CGFloat) + ); + decl.add_method(sel!(redComponent), red_component as extern "C" fn(&Object, _) -> CGFloat); + decl.add_method(sel!(greenComponent), green_component as extern "C" fn(&Object, _) -> CGFloat); + decl.add_method(sel!(blueComponent), blue_component as extern "C" fn(&Object, _) -> CGFloat); - decl.add_method(sel!(hueComponent), hue_component as extern "C" fn(&Object, _) -> CGFloat); - decl.add_method( - sel!(saturationComponent), - saturation_component as extern "C" fn(&Object, _) -> CGFloat - ); - decl.add_method( - sel!(brightnessComponent), - brightness_component as extern "C" fn(&Object, _) -> CGFloat - ); - decl.add_method( - sel!(getHue:saturation:brightness:alpha:), - get_hsba as extern "C" fn(&Object, _, CGFloat, CGFloat, CGFloat, CGFloat) - ); + decl.add_method(sel!(hueComponent), hue_component as extern "C" fn(&Object, _) -> CGFloat); + decl.add_method( + sel!(saturationComponent), + saturation_component as extern "C" fn(&Object, _) -> CGFloat + ); + decl.add_method( + sel!(brightnessComponent), + brightness_component as extern "C" fn(&Object, _) -> CGFloat + ); + decl.add_method( + sel!(getHue:saturation:brightness:alpha:), + get_hsba as extern "C" fn(&Object, _, CGFloat, CGFloat, CGFloat, CGFloat) + ); - decl.add_method(sel!(whiteComponent), white_component as extern "C" fn(&Object, _) -> CGFloat); - decl.add_method( - sel!(getWhite:alpha:), - get_white as extern "C" fn(&Object, _, CGFloat, CGFloat) - ); + decl.add_method(sel!(whiteComponent), white_component as extern "C" fn(&Object, _) -> CGFloat); + decl.add_method( + sel!(getWhite:alpha:), + get_white as extern "C" fn(&Object, _, CGFloat, CGFloat) + ); - decl.add_method(sel!(cyanComponent), cyan_component as extern "C" fn(&Object, _) -> CGFloat); - decl.add_method( - sel!(magentaComponent), - magenta_component as extern "C" fn(&Object, _) -> CGFloat - ); - decl.add_method( - sel!(yellowComponent), - yellow_component as extern "C" fn(&Object, _) -> CGFloat - ); - decl.add_method(sel!(blackComponent), black_component as extern "C" fn(&Object, _) -> CGFloat); - decl.add_method( - sel!(getCyan:magenta:yellow:black:alpha:), - get_cmyk as extern "C" fn(&Object, _, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat) - ); + decl.add_method(sel!(cyanComponent), cyan_component as extern "C" fn(&Object, _) -> CGFloat); + decl.add_method( + sel!(magentaComponent), + magenta_component as extern "C" fn(&Object, _) -> CGFloat + ); + decl.add_method( + sel!(yellowComponent), + yellow_component as extern "C" fn(&Object, _) -> CGFloat + ); + decl.add_method(sel!(blackComponent), black_component as extern "C" fn(&Object, _) -> CGFloat); + decl.add_method( + sel!(getCyan:magenta:yellow:black:alpha:), + get_cmyk as extern "C" fn(&Object, _, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat) + ); - decl.add_method(sel!(alphaComponent), alpha_component as extern "C" fn(&Object, _) -> CGFloat); + decl.add_method(sel!(alphaComponent), alpha_component as extern "C" fn(&Object, _) -> CGFloat); - decl.add_method(sel!(CGColor), cg_color as extern "C" fn(&Object, _) -> id); - decl.add_method(sel!(setStroke), set_stroke as extern "C" fn(&Object, _)); - decl.add_method(sel!(setFill), set_fill as extern "C" fn(&Object, _)); - decl.add_method(sel!(set), call_set as extern "C" fn(&Object, _)); + decl.add_method(sel!(CGColor), cg_color as extern "C" fn(&Object, _) -> id); + decl.add_method(sel!(setStroke), set_stroke as extern "C" fn(&Object, _)); + decl.add_method(sel!(setFill), set_fill as extern "C" fn(&Object, _)); + decl.add_method(sel!(set), call_set as extern "C" fn(&Object, _)); - decl.add_method( - sel!(highlightWithLevel:), - highlight_with_level as extern "C" fn(&Object, _, CGFloat) -> id - ); - decl.add_method( - sel!(shadowWithLevel:), - shadow_with_level as extern "C" fn(&Object, _, CGFloat) -> id - ); + decl.add_method( + sel!(highlightWithLevel:), + highlight_with_level as extern "C" fn(&Object, _, CGFloat) -> id + ); + decl.add_method( + sel!(shadowWithLevel:), + shadow_with_level as extern "C" fn(&Object, _, CGFloat) -> id + ); - decl.add_method( - sel!(colorWithAlphaComponent:), - color_with_alpha_component as extern "C" fn(&Object, _, CGFloat) -> id - ); - decl.add_method( - sel!(blendedColorWithFraction:ofColor:), - blended_color as extern "C" fn(&Object, _, CGFloat, id) -> id - ); - decl.add_method( - sel!(colorWithSystemEffect:), - color_with_system_effect as extern "C" fn(&Object, _, NSInteger) -> id - ); + decl.add_method( + sel!(colorWithAlphaComponent:), + color_with_alpha_component as extern "C" fn(&Object, _, CGFloat) -> id + ); + decl.add_method( + sel!(blendedColorWithFraction:ofColor:), + blended_color as extern "C" fn(&Object, _, CGFloat, id) -> id + ); + decl.add_method( + sel!(colorWithSystemEffect:), + color_with_system_effect as extern "C" fn(&Object, _, NSInteger) -> id + ); - decl.add_ivar::(AQUA_LIGHT_COLOR_NORMAL_CONTRAST); - decl.add_ivar::(AQUA_LIGHT_COLOR_HIGH_CONTRAST); - decl.add_ivar::(AQUA_DARK_COLOR_NORMAL_CONTRAST); - decl.add_ivar::(AQUA_DARK_COLOR_HIGH_CONTRAST); + decl.add_ivar::(AQUA_LIGHT_COLOR_NORMAL_CONTRAST); + decl.add_ivar::(AQUA_LIGHT_COLOR_HIGH_CONTRAST); + decl.add_ivar::(AQUA_DARK_COLOR_NORMAL_CONTRAST); + decl.add_ivar::(AQUA_DARK_COLOR_HIGH_CONTRAST); - VIEW_CLASS = decl.register(); - }); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } diff --git a/src/image/appkit.rs b/src/image/appkit.rs index 0dceb69..b388dd2 100644 --- a/src/image/appkit.rs +++ b/src/image/appkit.rs @@ -25,15 +25,20 @@ use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR}; pub(crate) fn register_image_view_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTImageView"; - INIT.call_once(|| unsafe { - let superclass = class!(NSImageView); - let decl = ClassDecl::new("RSTImageView", superclass).unwrap(); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSImageView); + 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 } } diff --git a/src/image/uikit.rs b/src/image/uikit.rs index ef989fe..43acf5d 100644 --- a/src/image/uikit.rs +++ b/src/image/uikit.rs @@ -15,12 +15,17 @@ use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR}; pub(crate) fn register_image_view_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTImageView"; - INIT.call_once(|| unsafe { - let superclass = class!(UIImageView); - let mut decl = ClassDecl::new("RSTImageView", superclass).expect("Failed to get RSTVIEW"); - VIEW_CLASS = decl.register(); - }); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(UIImageView); + let mut decl = ClassDecl::new(CLASS_NAME, superclass).expect("Failed to get RSTVIEW"); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } diff --git a/src/input/appkit.rs b/src/input/appkit.rs index 2138117..560c14e 100644 --- a/src/input/appkit.rs +++ b/src/input/appkit.rs @@ -54,12 +54,17 @@ extern "C" fn text_should_end_editing(this: &mut Object, _ pub(crate) fn register_view_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTTextInputField"; - INIT.call_once(|| unsafe { - let superclass = class!(NSTextField); - let decl = ClassDecl::new("RSTTextInputField", superclass).unwrap(); - VIEW_CLASS = decl.register(); - }); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSTextField); + let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } diff --git a/src/invoker.rs b/src/invoker.rs index 26560f2..51ab45f 100644 --- a/src/invoker.rs +++ b/src/invoker.rs @@ -97,16 +97,23 @@ extern "C" fn perform(this: &mut Object, _: Sel, _sender: id) pub(crate) fn register_invoker_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTTargetActionHandler"; - INIT.call_once(|| unsafe { - let superclass = class!(NSObject); - let mut decl = ClassDecl::new("RSTTargetActionHandler", superclass).unwrap(); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { + VIEW_CLASS = c; + } + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSObject); + let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); - decl.add_ivar::(ACTION_CALLBACK_PTR); - decl.add_method(sel!(perform:), perform:: as extern "C" fn(&mut Object, _, id)); + decl.add_ivar::(ACTION_CALLBACK_PTR); + decl.add_method(sel!(perform:), perform:: as extern "C" fn(&mut Object, _, id)); - VIEW_CLASS = decl.register(); - }); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } diff --git a/src/listview/appkit.rs b/src/listview/appkit.rs index f2c0391..95c5fd3 100644 --- a/src/listview/appkit.rs +++ b/src/listview/appkit.rs @@ -187,12 +187,17 @@ extern "C" fn dragging_exited(this: &mut Object, _: Sel, in pub(crate) fn register_listview_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &'static str = "RSTListView"; - INIT.call_once(|| unsafe { - let superclass = class!(NSTableView); - let decl = ClassDecl::new("RSTListView", superclass).unwrap(); - VIEW_CLASS = decl.register(); - }); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSTableView); + let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } diff --git a/src/listview/row/appkit.rs b/src/listview/row/appkit.rs index d6f4749..25a96e1 100644 --- a/src/listview/row/appkit.rs +++ b/src/listview/row/appkit.rs @@ -109,15 +109,20 @@ extern "C" fn dealloc(this: &Object, _: Sel) { pub(crate) fn register_listview_row_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTTableViewRow"; - INIT.call_once(|| unsafe { - let superclass = class!(NSView); - let mut decl = ClassDecl::new("RSTTableViewRow", superclass).unwrap(); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSView); + 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 } } @@ -127,46 +132,51 @@ pub(crate) fn register_listview_row_class() -> *const Class { pub(crate) fn register_listview_row_class_with_delegate() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTableViewRowWithDelegate"; - INIT.call_once(|| unsafe { - let superclass = class!(NSView); - let mut decl = ClassDecl::new("RSTableViewRowWithDelegate", superclass).unwrap(); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSView); + 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 - // move. - decl.add_ivar::(LISTVIEW_ROW_DELEGATE_PTR); - decl.add_ivar::(BACKGROUND_COLOR); + // A pointer to the "view controller" on the Rust side. It's expected that this doesn't + // move. + decl.add_ivar::(LISTVIEW_ROW_DELEGATE_PTR); + decl.add_ivar::(BACKGROUND_COLOR); - 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!(isFlipped), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL); + decl.add_method(sel!(updateLayer), update_layer as extern "C" fn(&Object, _)); - // Drag and drop operations (e.g, accepting files) - decl.add_method( - sel!(draggingEntered:), - dragging_entered:: as extern "C" fn(&mut Object, _, _) -> NSUInteger - ); - decl.add_method( - sel!(prepareForDragOperation:), - prepare_for_drag_operation:: as extern "C" fn(&mut Object, _, _) -> BOOL - ); - decl.add_method( - sel!(performDragOperation:), - perform_drag_operation:: as extern "C" fn(&mut Object, _, _) -> BOOL - ); - decl.add_method( - sel!(concludeDragOperation:), - conclude_drag_operation:: as extern "C" fn(&mut Object, _, _) - ); - decl.add_method( - sel!(draggingExited:), - dragging_exited:: as extern "C" fn(&mut Object, _, _) - ); + // Drag and drop operations (e.g, accepting files) + decl.add_method( + sel!(draggingEntered:), + dragging_entered:: as extern "C" fn(&mut Object, _, _) -> NSUInteger + ); + decl.add_method( + sel!(prepareForDragOperation:), + prepare_for_drag_operation:: as extern "C" fn(&mut Object, _, _) -> BOOL + ); + decl.add_method( + sel!(performDragOperation:), + perform_drag_operation:: as extern "C" fn(&mut Object, _, _) -> BOOL + ); + decl.add_method( + sel!(concludeDragOperation:), + conclude_drag_operation:: as extern "C" fn(&mut Object, _, _) + ); + decl.add_method( + sel!(draggingExited:), + dragging_exited:: as extern "C" fn(&mut Object, _, _) + ); - // Cleanup - decl.add_method(sel!(dealloc), dealloc:: as extern "C" fn(&Object, _)); + // Cleanup + decl.add_method(sel!(dealloc), dealloc:: as extern "C" fn(&Object, _)); - VIEW_CLASS = decl.register(); - }); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } diff --git a/src/listview/row/uikit.rs b/src/listview/row/uikit.rs index 1e835ed..1ea8ce4 100644 --- a/src/listview/row/uikit.rs +++ b/src/listview/row/uikit.rs @@ -16,12 +16,17 @@ use crate::utils::load; pub(crate) fn register_view_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTView"; - INIT.call_once(|| unsafe { - let superclass = class!(UIView); - let mut decl = ClassDecl::new("RSTView", superclass).unwrap(); - VIEW_CLASS = decl.register(); - }); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(UIView); + let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } @@ -31,15 +36,18 @@ pub(crate) fn register_view_class() -> *const Class { pub(crate) fn register_view_class_with_delegate() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTViewWithDelegate"; - 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(); - }); - - unsafe { - VIEW_CLASS + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(UIView); + let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); + decl.add_ivar::(VIEW_DELEGATE_PTR); + VIEW_CLASS = decl.register(); + }); } + + unsafe { VIEW_CLASS } } diff --git a/src/scrollview/appkit.rs b/src/scrollview/appkit.rs index f686f20..d325465 100644 --- a/src/scrollview/appkit.rs +++ b/src/scrollview/appkit.rs @@ -79,12 +79,17 @@ extern "C" fn dragging_exited(this: &mut Object, _: Sel, pub(crate) fn register_scrollview_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &'static str = "RSTScrollView"; - INIT.call_once(|| unsafe { - let superclass = class!(NSScrollView); - let decl = ClassDecl::new("RSTScrollView", superclass).unwrap(); - VIEW_CLASS = decl.register(); - }); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSScrollView); + let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } @@ -94,41 +99,46 @@ pub(crate) fn register_scrollview_class() -> *const Class { pub(crate) fn register_scrollview_class_with_delegate() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &'static str = "RSTScrollViewWithDelegate"; - INIT.call_once(|| unsafe { - let superclass = class!(NSScrollView); - let mut decl = ClassDecl::new("RSTScrollViewWithDelegate", superclass).unwrap(); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSScrollView); + 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 - // move. - decl.add_ivar::(SCROLLVIEW_DELEGATE_PTR); + // A pointer to the "view controller" on the Rust side. It's expected that this doesn't + // move. + decl.add_ivar::(SCROLLVIEW_DELEGATE_PTR); - 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); - // Drag and drop operations (e.g, accepting files) - decl.add_method( - sel!(draggingEntered:), - dragging_entered:: as extern "C" fn(&mut Object, _, _) -> NSUInteger - ); - decl.add_method( - sel!(prepareForDragOperation:), - prepare_for_drag_operation:: as extern "C" fn(&mut Object, _, _) -> BOOL - ); - decl.add_method( - sel!(performDragOperation:), - perform_drag_operation:: as extern "C" fn(&mut Object, _, _) -> BOOL - ); - decl.add_method( - sel!(concludeDragOperation:), - conclude_drag_operation:: as extern "C" fn(&mut Object, _, _) - ); - decl.add_method( - sel!(draggingExited:), - dragging_exited:: as extern "C" fn(&mut Object, _, _) - ); + // Drag and drop operations (e.g, accepting files) + decl.add_method( + sel!(draggingEntered:), + dragging_entered:: as extern "C" fn(&mut Object, _, _) -> NSUInteger + ); + decl.add_method( + sel!(prepareForDragOperation:), + prepare_for_drag_operation:: as extern "C" fn(&mut Object, _, _) -> BOOL + ); + decl.add_method( + sel!(performDragOperation:), + perform_drag_operation:: as extern "C" fn(&mut Object, _, _) -> BOOL + ); + decl.add_method( + sel!(concludeDragOperation:), + conclude_drag_operation:: as extern "C" fn(&mut Object, _, _) + ); + decl.add_method( + sel!(draggingExited:), + dragging_exited:: as extern "C" fn(&mut Object, _, _) + ); - VIEW_CLASS = decl.register(); - }); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } diff --git a/src/select/mod.rs b/src/select/mod.rs index 7eab27d..2cbdd2e 100644 --- a/src/select/mod.rs +++ b/src/select/mod.rs @@ -270,12 +270,17 @@ impl Drop for Select { fn register_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "CacaoSelect"; - INIT.call_once(|| unsafe { - let superclass = class!(NSPopUpButton); - let decl = ClassDecl::new("CacaoSelect", superclass).unwrap(); - VIEW_CLASS = decl.register(); - }); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSPopUpButton); + let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } diff --git a/src/switch.rs b/src/switch.rs index eab6b38..5d04c87 100644 --- a/src/switch.rs +++ b/src/switch.rs @@ -180,12 +180,19 @@ impl Drop for Switch { fn register_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTSwitch"; - INIT.call_once(|| unsafe { - let superclass = class!(NSButton); - let decl = ClassDecl::new("RSTSwitch", superclass).unwrap(); - VIEW_CLASS = decl.register(); - }); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { + VIEW_CLASS = c; + } + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSButton); + let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } diff --git a/src/text/label/appkit.rs b/src/text/label/appkit.rs index 1b3b681..e27fe1b 100644 --- a/src/text/label/appkit.rs +++ b/src/text/label/appkit.rs @@ -25,12 +25,17 @@ use crate::utils::load; pub(crate) fn register_view_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTTextField"; - INIT.call_once(|| unsafe { - let superclass = class!(NSTextField); - let decl = ClassDecl::new("RSTTextField", superclass).unwrap(); - VIEW_CLASS = decl.register(); - }); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSTextField); + let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } @@ -40,17 +45,22 @@ pub(crate) fn register_view_class() -> *const Class { pub(crate) fn register_view_class_with_delegate() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTTextFieldWithDelegate"; - INIT.call_once(|| unsafe { - let superclass = class!(NSView); - let mut decl = ClassDecl::new("RSTTextFieldWithDelegate", superclass).unwrap(); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSView); + 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 - // move. - decl.add_ivar::(LABEL_DELEGATE_PTR); + // A pointer to the "view controller" on the Rust side. It's expected that this doesn't + // move. + decl.add_ivar::(LABEL_DELEGATE_PTR); - VIEW_CLASS = decl.register(); - }); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } diff --git a/src/uikit/app/class.rs b/src/uikit/app/class.rs index 3baf350..37909f0 100644 --- a/src/uikit/app/class.rs +++ b/src/uikit/app/class.rs @@ -12,12 +12,17 @@ use objc::runtime::Class; pub(crate) fn register_app_class() -> *const Class { static mut APP_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTApplication"; - INIT.call_once(|| unsafe { - let superclass = class!(UIApplication); - let decl = ClassDecl::new("RSTApplication", superclass).unwrap(); - APP_CLASS = decl.register(); - }); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { APP_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(UIApplication); + let decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); + APP_CLASS = decl.register(); + }); + } unsafe { APP_CLASS } } diff --git a/src/uikit/app/delegate.rs b/src/uikit/app/delegate.rs index aba45ed..5462b69 100644 --- a/src/uikit/app/delegate.rs +++ b/src/uikit/app/delegate.rs @@ -51,29 +51,34 @@ extern "C" fn configuration_for_scene_session(this: &Object, _: pub(crate) fn register_app_delegate_class() -> *const Class { static mut DELEGATE_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTAppDelegate"; - INIT.call_once(|| unsafe { - let superclass = class!(NSObject); - let mut decl = ClassDecl::new("RSTAppDelegate", superclass).unwrap(); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { DELEGATE_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSObject); + let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); - // Launching Applications - decl.add_method( - sel!(application:didFinishLaunchingWithOptions:), - did_finish_launching:: as extern "C" fn(&Object, _, _, id) -> BOOL - ); + // Launching Applications + decl.add_method( + sel!(application:didFinishLaunchingWithOptions:), + did_finish_launching:: as extern "C" fn(&Object, _, _, id) -> BOOL + ); - // Scenes - decl.add_method( - sel!(application:configurationForConnectingSceneSession:options:), - configuration_for_scene_session:: as extern "C" fn(&Object, _, _, id, id) -> id - ); - /*decl.add_method( - sel!(application:didDiscardSceneSessions:), - did_discard_scene_sessions:: as extern "C" fn(&Object, _, _, id) - );*/ + // Scenes + decl.add_method( + sel!(application:configurationForConnectingSceneSession:options:), + configuration_for_scene_session:: as extern "C" fn(&Object, _, _, id, id) -> id + ); + /*decl.add_method( + sel!(application:didDiscardSceneSessions:), + did_discard_scene_sessions:: as extern "C" fn(&Object, _, _, id) + );*/ - DELEGATE_CLASS = decl.register(); - }); + DELEGATE_CLASS = decl.register(); + }); + } unsafe { DELEGATE_CLASS } } diff --git a/src/uikit/scene/delegate.rs b/src/uikit/scene/delegate.rs index 75aa69a..2406f84 100644 --- a/src/uikit/scene/delegate.rs +++ b/src/uikit/scene/delegate.rs @@ -62,30 +62,35 @@ extern "C" fn scene_will_connect_to_session_with_options pub(crate) fn register_window_scene_delegate_class Box>() -> *const Class { static mut DELEGATE_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTWindowSceneDelegate"; - use objc::runtime::{class_addProtocol, Protocol}; - INIT.call_once(|| unsafe { - let superclass = class!(UIResponder); - let mut decl = ClassDecl::new("RSTWindowSceneDelegate", superclass).unwrap(); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { DELEGATE_CLASS = c }; + } else { + use objc::runtime::Protocol; + INIT.call_once(|| unsafe { + let superclass = class!(UIResponder); + let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); - let p = Protocol::get("UIWindowSceneDelegate").unwrap(); + let p = Protocol::get("UIWindowSceneDelegate").unwrap(); - // A spot to hold a pointer to - decl.add_ivar::(WINDOW_SCENE_PTR); - decl.add_protocol(p); + // A spot to hold a pointer to + decl.add_ivar::(WINDOW_SCENE_PTR); + decl.add_protocol(p); - // Override the `init` call to handle creating and attaching a WindowSceneDelegate. - decl.add_method(sel!(init), init:: as extern "C" fn(&mut Object, _) -> id); + // Override the `init` call to handle creating and attaching a WindowSceneDelegate. + decl.add_method(sel!(init), init:: as extern "C" fn(&mut Object, _) -> id); - // UIWindowSceneDelegate API - decl.add_method( - sel!(scene:willConnectToSession:options:), - scene_will_connect_to_session_with_options:: as extern "C" fn(&Object, _, _, _, _) - ); + // UIWindowSceneDelegate API + decl.add_method( + sel!(scene:willConnectToSession:options:), + scene_will_connect_to_session_with_options:: as extern "C" fn(&Object, _, _, _, _) + ); - // Launching Applications - DELEGATE_CLASS = decl.register(); - }); + // Launching Applications + DELEGATE_CLASS = decl.register(); + }); + } unsafe { DELEGATE_CLASS } } diff --git a/src/view/appkit.rs b/src/view/appkit.rs index 27b047e..85bc096 100644 --- a/src/view/appkit.rs +++ b/src/view/appkit.rs @@ -94,19 +94,24 @@ extern "C" fn update_layer(this: &Object, _: Sel) { pub(crate) fn register_view_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTView"; - INIT.call_once(|| unsafe { - let superclass = class!(NSView); - let mut decl = ClassDecl::new("RSTView", superclass).unwrap(); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(NSView); + 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!(updateLayer), update_layer as extern "C" fn(&Object, _)); - decl.add_method(sel!(wantsUpdateLayer), 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!(wantsUpdateLayer), enforce_normalcy as extern "C" fn(&Object, _) -> BOOL); - decl.add_ivar::(BACKGROUND_COLOR); + decl.add_ivar::(BACKGROUND_COLOR); - VIEW_CLASS = decl.register(); - }); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } diff --git a/src/view/splitviewcontroller/ios.rs b/src/view/splitviewcontroller/ios.rs index fe2ab7b..bb4cf59 100644 --- a/src/view/splitviewcontroller/ios.rs +++ b/src/view/splitviewcontroller/ios.rs @@ -53,20 +53,30 @@ extern "C" fn did_disappear(this: &mut Object, _: Sel, animated pub(crate) fn register_view_controller_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTViewController"; - INIT.call_once(|| unsafe { - let superclass = class!(UIViewController); - let mut decl = ClassDecl::new("RSTViewController", superclass).unwrap(); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(UIViewController); + let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); - decl.add_ivar::(VIEW_DELEGATE_PTR); + decl.add_ivar::(VIEW_DELEGATE_PTR); - decl.add_method(sel!(viewWillAppear:), will_appear:: as extern "C" fn(&mut Object, _, BOOL)); - decl.add_method(sel!(viewDidAppear:), did_appear:: as extern "C" fn(&mut Object, _, BOOL)); - decl.add_method(sel!(viewWillDisappear:), will_disappear:: as extern "C" fn(&mut Object, _, BOOL)); - decl.add_method(sel!(viewDidDisappear:), did_disappear:: as extern "C" fn(&mut Object, _, BOOL)); - - VIEW_CLASS = decl.register(); - }); + decl.add_method(sel!(viewWillAppear:), will_appear:: as extern "C" fn(&mut Object, _, BOOL)); + decl.add_method(sel!(viewDidAppear:), did_appear:: as extern "C" fn(&mut Object, _, BOOL)); + decl.add_method( + sel!(viewWillDisappear:), + will_disappear:: as extern "C" fn(&mut Object, _, BOOL) + ); + decl.add_method( + sel!(viewDidDisappear:), + did_disappear:: as extern "C" fn(&mut Object, _, BOOL) + ); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } diff --git a/src/view/uikit.rs b/src/view/uikit.rs index 4b697d9..54015ce 100644 --- a/src/view/uikit.rs +++ b/src/view/uikit.rs @@ -16,12 +16,17 @@ use crate::view::{ViewDelegate, VIEW_DELEGATE_PTR}; pub(crate) fn register_view_class() -> *const Class { static mut VIEW_CLASS: *const Class = 0 as *const Class; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTView"; - INIT.call_once(|| unsafe { - let superclass = class!(UIView); - let mut decl = ClassDecl::new("RSTView", superclass).unwrap(); - VIEW_CLASS = decl.register(); - }); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { VIEW_CLASS = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = class!(UIView); + let mut decl = ClassDecl::new(CLASS_NAME, superclass).unwrap(); + VIEW_CLASS = decl.register(); + }); + } unsafe { VIEW_CLASS } } diff --git a/src/webview/process_pool.rs b/src/webview/process_pool.rs index 8b5c630..718b292 100644 --- a/src/webview/process_pool.rs +++ b/src/webview/process_pool.rs @@ -28,17 +28,22 @@ extern "C" fn download_delegate(this: &Object, _: Sel) -> id { pub fn register_process_pool() -> *const Object { static mut PROCESS_POOL: *const Object = 0 as *const Object; static INIT: Once = Once::new(); + const CLASS_NAME: &str = "RSTWebViewProcessPool"; - INIT.call_once(|| unsafe { - let superclass = Class::get("WKProcessPool").unwrap(); - let mut decl = ClassDecl::new("RSTWebViewProcessPool", superclass).unwrap(); + if let Some(c) = Class::get(CLASS_NAME) { + unsafe { PROCESS_POOL = c }; + } else { + INIT.call_once(|| unsafe { + let superclass = Class::get("WKProcessPool").unwrap(); + let mut decl = ClassDecl::new("RSTWebViewProcessPool", superclass).unwrap(); - //decl.add_ivar::(DOWNLOAD_DELEGATE_PTR); - decl.add_method(sel!(_downloadDelegate), download_delegate as extern "C" fn(&Object, _) -> id); + //decl.add_ivar::(DOWNLOAD_DELEGATE_PTR); + decl.add_method(sel!(_downloadDelegate), download_delegate as extern "C" fn(&Object, _) -> id); - //PROCESS_POOL = decl.register(); - PROCESS_POOL = msg_send![decl.register(), new]; - }); + //PROCESS_POOL = decl.register(); + PROCESS_POOL = msg_send![decl.register(), new]; + }); + } unsafe { PROCESS_POOL } }