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 {
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 }
}

View file

@ -297,173 +297,178 @@ extern "C" fn delegate_handles_key<T: AppDelegate>(this: &Object, _: Sel, _: id,
pub(crate) fn register_app_delegate_class<T: AppDelegate + AppDelegate>() -> *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::<usize>(APP_PTR);
decl.add_ivar::<usize>(APP_PTR);
// Launching Applications
decl.add_method(
sel!(applicationWillFinishLaunching:),
will_finish_launching::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationDidFinishLaunching:),
did_finish_launching::<T> as extern "C" fn(&Object, _, _)
);
// Launching Applications
decl.add_method(
sel!(applicationWillFinishLaunching:),
will_finish_launching::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationDidFinishLaunching:),
did_finish_launching::<T> as extern "C" fn(&Object, _, _)
);
// Managing Active Status
decl.add_method(
sel!(applicationWillBecomeActive:),
will_become_active::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationDidBecomeActive:),
did_become_active::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationWillResignActive:),
will_resign_active::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationDidResignActive:),
did_resign_active::<T> as extern "C" fn(&Object, _, _)
);
// Managing Active Status
decl.add_method(
sel!(applicationWillBecomeActive:),
will_become_active::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationDidBecomeActive:),
did_become_active::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationWillResignActive:),
will_resign_active::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationDidResignActive:),
did_resign_active::<T> as extern "C" fn(&Object, _, _)
);
// Terminating Applications
decl.add_method(
sel!(applicationShouldTerminate:),
should_terminate::<T> as extern "C" fn(&Object, _, _) -> NSUInteger
);
decl.add_method(
sel!(applicationWillTerminate:),
will_terminate::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationShouldTerminateAfterLastWindowClosed:),
should_terminate_after_last_window_closed::<T> as extern "C" fn(&Object, _, _) -> BOOL
);
// Terminating Applications
decl.add_method(
sel!(applicationShouldTerminate:),
should_terminate::<T> as extern "C" fn(&Object, _, _) -> NSUInteger
);
decl.add_method(
sel!(applicationWillTerminate:),
will_terminate::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationShouldTerminateAfterLastWindowClosed:),
should_terminate_after_last_window_closed::<T> as extern "C" fn(&Object, _, _) -> BOOL
);
// Hiding Applications
decl.add_method(sel!(applicationWillHide:), will_hide::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(applicationDidHide:), did_hide::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(applicationWillUnhide:), will_unhide::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(applicationDidUnhide:), did_unhide::<T> as extern "C" fn(&Object, _, _));
// Hiding Applications
decl.add_method(sel!(applicationWillHide:), will_hide::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(applicationDidHide:), did_hide::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(applicationWillUnhide:), will_unhide::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(applicationDidUnhide:), did_unhide::<T> as extern "C" fn(&Object, _, _));
// Managing Windows
decl.add_method(sel!(applicationWillUpdate:), will_update::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(applicationDidUpdate:), did_update::<T> as extern "C" fn(&Object, _, _));
decl.add_method(
sel!(applicationShouldHandleReopen:hasVisibleWindows:),
should_handle_reopen::<T> as extern "C" fn(&Object, _, _, BOOL) -> BOOL
);
// Managing Windows
decl.add_method(sel!(applicationWillUpdate:), will_update::<T> as extern "C" fn(&Object, _, _));
decl.add_method(sel!(applicationDidUpdate:), did_update::<T> as extern "C" fn(&Object, _, _));
decl.add_method(
sel!(applicationShouldHandleReopen:hasVisibleWindows:),
should_handle_reopen::<T> as extern "C" fn(&Object, _, _, BOOL) -> BOOL
);
// Dock Menu
decl.add_method(
sel!(applicationDockMenu:),
dock_menu::<T> as extern "C" fn(&Object, _, _) -> id
);
// Dock Menu
decl.add_method(
sel!(applicationDockMenu:),
dock_menu::<T> as extern "C" fn(&Object, _, _) -> id
);
// Displaying Errors
decl.add_method(
sel!(application:willPresentError:),
will_present_error::<T> as extern "C" fn(&Object, _, _, id) -> id
);
// Displaying Errors
decl.add_method(
sel!(application:willPresentError:),
will_present_error::<T> as extern "C" fn(&Object, _, _, id) -> id
);
// Managing the Screen
decl.add_method(
sel!(applicationDidChangeScreenParameters:),
did_change_screen_parameters::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationDidChangeOcclusionState:),
did_change_occlusion_state::<T> as extern "C" fn(&Object, _, _)
);
// Managing the Screen
decl.add_method(
sel!(applicationDidChangeScreenParameters:),
did_change_screen_parameters::<T> as extern "C" fn(&Object, _, _)
);
decl.add_method(
sel!(applicationDidChangeOcclusionState:),
did_change_occlusion_state::<T> as extern "C" fn(&Object, _, _)
);
// User Activities
decl.add_method(
sel!(application:willContinueUserActivityWithType:),
will_continue_user_activity_with_type::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
decl.add_method(
sel!(application:continueUserActivity:restorationHandler:),
continue_user_activity::<T> as extern "C" fn(&Object, _, _, id, id) -> BOOL
);
decl.add_method(
sel!(application:didFailToContinueUserActivityWithType:error:),
failed_to_continue_user_activity::<T> as extern "C" fn(&Object, _, _, id, id)
);
decl.add_method(
sel!(application:didUpdateUserActivity:),
did_update_user_activity::<T> as extern "C" fn(&Object, _, _, id)
);
// User Activities
decl.add_method(
sel!(application:willContinueUserActivityWithType:),
will_continue_user_activity_with_type::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
decl.add_method(
sel!(application:continueUserActivity:restorationHandler:),
continue_user_activity::<T> as extern "C" fn(&Object, _, _, id, id) -> BOOL
);
decl.add_method(
sel!(application:didFailToContinueUserActivityWithType:error:),
failed_to_continue_user_activity::<T> as extern "C" fn(&Object, _, _, id, id)
);
decl.add_method(
sel!(application:didUpdateUserActivity:),
did_update_user_activity::<T> as extern "C" fn(&Object, _, _, id)
);
// Handling push notifications
decl.add_method(
sel!(application:didRegisterForRemoteNotificationsWithDeviceToken:),
registered_for_remote_notifications::<T> as extern "C" fn(&Object, _, _, id)
);
decl.add_method(
sel!(application:didFailToRegisterForRemoteNotificationsWithError:),
failed_to_register_for_remote_notifications::<T> as extern "C" fn(&Object, _, _, id)
);
decl.add_method(
sel!(application:didReceiveRemoteNotification:),
did_receive_remote_notification::<T> as extern "C" fn(&Object, _, _, id)
);
// Handling push notifications
decl.add_method(
sel!(application:didRegisterForRemoteNotificationsWithDeviceToken:),
registered_for_remote_notifications::<T> as extern "C" fn(&Object, _, _, id)
);
decl.add_method(
sel!(application:didFailToRegisterForRemoteNotificationsWithError:),
failed_to_register_for_remote_notifications::<T> as extern "C" fn(&Object, _, _, id)
);
decl.add_method(
sel!(application:didReceiveRemoteNotification:),
did_receive_remote_notification::<T> as extern "C" fn(&Object, _, _, id)
);
// CloudKit
#[cfg(feature = "cloudkit")]
decl.add_method(
sel!(application:userDidAcceptCloudKitShareWithMetadata:),
accepted_cloudkit_share::<T> as extern "C" fn(&Object, _, _, id)
);
// CloudKit
#[cfg(feature = "cloudkit")]
decl.add_method(
sel!(application:userDidAcceptCloudKitShareWithMetadata:),
accepted_cloudkit_share::<T> as extern "C" fn(&Object, _, _, id)
);
// Opening Files
decl.add_method(
sel!(application:openURLs:),
open_urls::<T> as extern "C" fn(&Object, _, _, id)
);
decl.add_method(
sel!(application:openFileWithoutUI:),
open_file_without_ui::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
decl.add_method(
sel!(applicationShouldOpenUntitledFile:),
should_open_untitled_file::<T> as extern "C" fn(&Object, _, _) -> BOOL
);
decl.add_method(
sel!(applicationOpenUntitledFile:),
open_untitled_file::<T> as extern "C" fn(&Object, _, _) -> BOOL
);
decl.add_method(
sel!(application:openTempFile:),
open_temp_file::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
// Opening Files
decl.add_method(
sel!(application:openURLs:),
open_urls::<T> as extern "C" fn(&Object, _, _, id)
);
decl.add_method(
sel!(application:openFileWithoutUI:),
open_file_without_ui::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
decl.add_method(
sel!(applicationShouldOpenUntitledFile:),
should_open_untitled_file::<T> as extern "C" fn(&Object, _, _) -> BOOL
);
decl.add_method(
sel!(applicationOpenUntitledFile:),
open_untitled_file::<T> as extern "C" fn(&Object, _, _) -> BOOL
);
decl.add_method(
sel!(application:openTempFile:),
open_temp_file::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
// Printing
decl.add_method(
sel!(application:printFile:),
print_file::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
decl.add_method(
sel!(application:printFiles:withSettings:showPrintPanels:),
print_files::<T> as extern "C" fn(&Object, _, id, id, id, BOOL) -> NSUInteger
);
// Printing
decl.add_method(
sel!(application:printFile:),
print_file::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
decl.add_method(
sel!(application:printFiles:withSettings:showPrintPanels:),
print_files::<T> 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::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
// Scripting
decl.add_method(
sel!(application:delegateHandlesKey:),
delegate_handles_key::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
DELEGATE_CLASS = decl.register();
});
DELEGATE_CLASS = decl.register();
});
}
unsafe { DELEGATE_CLASS }
}

View file

@ -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::<usize>(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::<usize>(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 }
}

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 {
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::<usize>(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::<usize>(WINDOW_DELEGATE_PTR);
DELEGATE_CLASS = decl.register();
});
}
unsafe { DELEGATE_CLASS }
}

View file

@ -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 }
}

View file

@ -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::<id>(AQUA_LIGHT_COLOR_NORMAL_CONTRAST);
decl.add_ivar::<id>(AQUA_LIGHT_COLOR_HIGH_CONTRAST);
decl.add_ivar::<id>(AQUA_DARK_COLOR_NORMAL_CONTRAST);
decl.add_ivar::<id>(AQUA_DARK_COLOR_HIGH_CONTRAST);
decl.add_ivar::<id>(AQUA_LIGHT_COLOR_NORMAL_CONTRAST);
decl.add_ivar::<id>(AQUA_LIGHT_COLOR_HIGH_CONTRAST);
decl.add_ivar::<id>(AQUA_DARK_COLOR_NORMAL_CONTRAST);
decl.add_ivar::<id>(AQUA_DARK_COLOR_HIGH_CONTRAST);
VIEW_CLASS = decl.register();
});
VIEW_CLASS = decl.register();
});
}
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 {
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 }
}

View file

@ -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 }
}

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 {
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 }
}

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 {
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::<usize>(ACTION_CALLBACK_PTR);
decl.add_method(sel!(perform:), perform::<F> as extern "C" fn(&mut Object, _, id));
decl.add_ivar::<usize>(ACTION_CALLBACK_PTR);
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 }
}

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 {
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 }
}

View file

@ -109,15 +109,20 @@ extern "C" fn dealloc<T: ViewDelegate>(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<T: ViewDelegate>() -> *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::<usize>(LISTVIEW_ROW_DELEGATE_PTR);
decl.add_ivar::<id>(BACKGROUND_COLOR);
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't
// move.
decl.add_ivar::<usize>(LISTVIEW_ROW_DELEGATE_PTR);
decl.add_ivar::<id>(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::<T> as extern "C" fn(&mut Object, _, _) -> NSUInteger
);
decl.add_method(
sel!(prepareForDragOperation:),
prepare_for_drag_operation::<T> as extern "C" fn(&mut Object, _, _) -> BOOL
);
decl.add_method(
sel!(performDragOperation:),
perform_drag_operation::<T> as extern "C" fn(&mut Object, _, _) -> BOOL
);
decl.add_method(
sel!(concludeDragOperation:),
conclude_drag_operation::<T> as extern "C" fn(&mut Object, _, _)
);
decl.add_method(
sel!(draggingExited:),
dragging_exited::<T> as extern "C" fn(&mut Object, _, _)
);
// Drag and drop operations (e.g, accepting files)
decl.add_method(
sel!(draggingEntered:),
dragging_entered::<T> as extern "C" fn(&mut Object, _, _) -> NSUInteger
);
decl.add_method(
sel!(prepareForDragOperation:),
prepare_for_drag_operation::<T> as extern "C" fn(&mut Object, _, _) -> BOOL
);
decl.add_method(
sel!(performDragOperation:),
perform_drag_operation::<T> as extern "C" fn(&mut Object, _, _) -> BOOL
);
decl.add_method(
sel!(concludeDragOperation:),
conclude_drag_operation::<T> as extern "C" fn(&mut Object, _, _)
);
decl.add_method(
sel!(draggingExited:),
dragging_exited::<T> as extern "C" fn(&mut Object, _, _)
);
// Cleanup
decl.add_method(sel!(dealloc), dealloc::<T> as extern "C" fn(&Object, _));
// Cleanup
decl.add_method(sel!(dealloc), dealloc::<T> as extern "C" fn(&Object, _));
VIEW_CLASS = decl.register();
});
VIEW_CLASS = decl.register();
});
}
unsafe { VIEW_CLASS }
}

View file

@ -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<T: ViewDelegate>() -> *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::<usize>(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::<usize>(VIEW_DELEGATE_PTR);
VIEW_CLASS = decl.register();
});
}
unsafe { 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 {
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<T: ScrollViewDelegate>() -> *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::<usize>(SCROLLVIEW_DELEGATE_PTR);
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't
// move.
decl.add_ivar::<usize>(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::<T> as extern "C" fn(&mut Object, _, _) -> NSUInteger
);
decl.add_method(
sel!(prepareForDragOperation:),
prepare_for_drag_operation::<T> as extern "C" fn(&mut Object, _, _) -> BOOL
);
decl.add_method(
sel!(performDragOperation:),
perform_drag_operation::<T> as extern "C" fn(&mut Object, _, _) -> BOOL
);
decl.add_method(
sel!(concludeDragOperation:),
conclude_drag_operation::<T> as extern "C" fn(&mut Object, _, _)
);
decl.add_method(
sel!(draggingExited:),
dragging_exited::<T> as extern "C" fn(&mut Object, _, _)
);
// Drag and drop operations (e.g, accepting files)
decl.add_method(
sel!(draggingEntered:),
dragging_entered::<T> as extern "C" fn(&mut Object, _, _) -> NSUInteger
);
decl.add_method(
sel!(prepareForDragOperation:),
prepare_for_drag_operation::<T> as extern "C" fn(&mut Object, _, _) -> BOOL
);
decl.add_method(
sel!(performDragOperation:),
perform_drag_operation::<T> as extern "C" fn(&mut Object, _, _) -> BOOL
);
decl.add_method(
sel!(concludeDragOperation:),
conclude_drag_operation::<T> as extern "C" fn(&mut Object, _, _)
);
decl.add_method(
sel!(draggingExited:),
dragging_exited::<T> as extern "C" fn(&mut Object, _, _)
);
VIEW_CLASS = decl.register();
});
VIEW_CLASS = decl.register();
});
}
unsafe { VIEW_CLASS }
}

View file

@ -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 }
}

View file

@ -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 }
}

View file

@ -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<T: LabelDelegate>() -> *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::<usize>(LABEL_DELEGATE_PTR);
// A pointer to the "view controller" on the Rust side. It's expected that this doesn't
// move.
decl.add_ivar::<usize>(LABEL_DELEGATE_PTR);
VIEW_CLASS = decl.register();
});
VIEW_CLASS = decl.register();
});
}
unsafe { VIEW_CLASS }
}

View file

@ -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 }
}

View file

@ -51,29 +51,34 @@ extern "C" fn configuration_for_scene_session<T: AppDelegate>(this: &Object, _:
pub(crate) fn register_app_delegate_class<T: AppDelegate>() -> *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::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
// Launching Applications
decl.add_method(
sel!(application:didFinishLaunchingWithOptions:),
did_finish_launching::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
// Scenes
decl.add_method(
sel!(application:configurationForConnectingSceneSession:options:),
configuration_for_scene_session::<T> as extern "C" fn(&Object, _, _, id, id) -> id
);
/*decl.add_method(
sel!(application:didDiscardSceneSessions:),
did_discard_scene_sessions::<T> as extern "C" fn(&Object, _, _, id)
);*/
// Scenes
decl.add_method(
sel!(application:configurationForConnectingSceneSession:options:),
configuration_for_scene_session::<T> as extern "C" fn(&Object, _, _, id, id) -> id
);
/*decl.add_method(
sel!(application:didDiscardSceneSessions:),
did_discard_scene_sessions::<T> as extern "C" fn(&Object, _, _, id)
);*/
DELEGATE_CLASS = decl.register();
});
DELEGATE_CLASS = decl.register();
});
}
unsafe { DELEGATE_CLASS }
}

View file

@ -62,30 +62,35 @@ 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 {
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::<usize>(WINDOW_SCENE_PTR);
decl.add_protocol(p);
// A spot to hold a pointer to
decl.add_ivar::<usize>(WINDOW_SCENE_PTR);
decl.add_protocol(p);
// Override the `init` call to handle creating and attaching a WindowSceneDelegate.
decl.add_method(sel!(init), init::<T, F> as extern "C" fn(&mut Object, _) -> id);
// Override the `init` call to handle creating and attaching a WindowSceneDelegate.
decl.add_method(sel!(init), init::<T, F> as extern "C" fn(&mut Object, _) -> id);
// UIWindowSceneDelegate API
decl.add_method(
sel!(scene:willConnectToSession:options:),
scene_will_connect_to_session_with_options::<T> as extern "C" fn(&Object, _, _, _, _)
);
// UIWindowSceneDelegate API
decl.add_method(
sel!(scene:willConnectToSession:options:),
scene_will_connect_to_session_with_options::<T> as extern "C" fn(&Object, _, _, _, _)
);
// Launching Applications
DELEGATE_CLASS = decl.register();
});
// Launching Applications
DELEGATE_CLASS = decl.register();
});
}
unsafe { DELEGATE_CLASS }
}

View file

@ -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::<id>(BACKGROUND_COLOR);
decl.add_ivar::<id>(BACKGROUND_COLOR);
VIEW_CLASS = decl.register();
});
VIEW_CLASS = decl.register();
});
}
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 {
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::<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!(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(sel!(viewDidDisappear:), did_disappear::<T> as extern "C" fn(&mut Object, _, BOOL));
VIEW_CLASS = decl.register();
});
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!(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();
});
}
unsafe { VIEW_CLASS }
}

View file

@ -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 }
}

View file

@ -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::<id>(DOWNLOAD_DELEGATE_PTR);
decl.add_method(sel!(_downloadDelegate), download_delegate as extern "C" fn(&Object, _) -> id);
//decl.add_ivar::<id>(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 }
}