diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 522399f6..927f4f9f 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -352,8 +352,8 @@ We'll step through an example (abridged) `View` bridge below, for macOS. You sho For our basic `View` type, we want to just map to the corresponding class on the Objective-C side (in this case, `NSView`), and maybe do a bit of tweaking for sanity reasons. ``` rust -pub(crate) fn register_view_class() -> *const Class { - static mut VIEW_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_view_class() -> &'static Class { + static mut VIEW_CLASS: Option<'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -364,10 +364,10 @@ pub(crate) fn register_view_class() -> *const Class { decl.add_ivar::(BACKGROUND_COLOR); - VIEW_CLASS = decl.register(); + VIEW_CLASS = Some(decl.register()); }); - unsafe { VIEW_CLASS } + unsafe { VIEW_CLASS.unwrap() } } ``` @@ -377,7 +377,7 @@ Objective-C method signatures, as well as provision space for variable storage ( For our _delegate_ types, we need a different class creation method - one that creates a subclass per-unique-type: ``` rust -pub(crate) fn register_view_class_with_delegate(instance: &T) -> *const Class { +pub(crate) fn register_view_class_with_delegate(instance: &T) -> &'static Class { load_or_register_class("NSView", instance.subclass_name(), |decl| unsafe { decl.add_ivar::(VIEW_DELEGATE_PTR); decl.add_ivar::(BACKGROUND_COLOR); @@ -412,7 +412,7 @@ Here, we just want to tell `NSView` to use top,left as the origin point, so we n extern "C" fn dragging_entered(this: &mut Object, _: Sel, info: id) -> NSUInteger { let view = utils::load::(this, VIEW_DELEGATE_PTR); view.dragging_entered(DragInfo { - info: unsafe { Id::from_ptr(info) } + info: unsafe { Id::retain(info).unwrap() } }).into() } ``` diff --git a/src/appkit/alert.rs b/src/appkit/alert.rs index bffc38ec..b9420253 100644 --- a/src/appkit/alert.rs +++ b/src/appkit/alert.rs @@ -24,16 +24,16 @@ //! } //! ``` -use crate::id_shim::Id; +use objc::rc::{Id, Owned}; use objc::runtime::Object; -use objc::{class, msg_send, sel}; +use objc::{class, msg_send, msg_send_id, sel}; use crate::foundation::{id, NSString}; /// Represents an `NSAlert`. Has no information other than the retained pointer to the Objective C /// side, so... don't bother inspecting this. #[derive(Debug)] -pub struct Alert(Id); +pub struct Alert(Id); impl Alert { /// Creates a basic `NSAlert`, storing a pointer to it in the Objective C runtime. @@ -44,11 +44,11 @@ impl Alert { let ok = NSString::new("OK"); Alert(unsafe { - let alert: id = msg_send![class!(NSAlert), new]; - let _: () = msg_send![alert, setMessageText: &*title]; - let _: () = msg_send![alert, setInformativeText: &*message]; - let _: () = msg_send![alert, addButtonWithTitle: &*ok]; - Id::from_ptr(alert) + let mut alert = msg_send_id![class!(NSAlert), new].unwrap(); + let _: () = msg_send![&mut alert, setMessageText: &*title]; + let _: () = msg_send![&mut alert, setInformativeText: &*message]; + let _: () = msg_send![&mut alert, addButtonWithTitle: &*ok]; + alert }) } diff --git a/src/appkit/app/class.rs b/src/appkit/app/class.rs index e53885f4..fa034ba1 100644 --- a/src/appkit/app/class.rs +++ b/src/appkit/app/class.rs @@ -9,15 +9,15 @@ use objc::declare::ClassDecl; use objc::runtime::Class; /// Used for injecting a custom NSApplication. Currently does nothing. -pub(crate) fn register_app_class() -> *const Class { - static mut APP_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_app_class() -> &'static Class { + static mut APP_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { let superclass = class!(NSApplication); let decl = ClassDecl::new("RSTApplication", superclass).unwrap(); - APP_CLASS = decl.register(); + APP_CLASS = Some(decl.register()); }); - unsafe { APP_CLASS } + unsafe { APP_CLASS.unwrap() } } diff --git a/src/appkit/app/delegate.rs b/src/appkit/app/delegate.rs index 0b904ee2..cf5a7438 100644 --- a/src/appkit/app/delegate.rs +++ b/src/appkit/app/delegate.rs @@ -294,8 +294,8 @@ extern "C" fn delegate_handles_key(this: &Object, _: Sel, _: id, /// Registers an `NSObject` application delegate, and configures it for the various callbacks and /// pointers we need to have. -pub(crate) fn register_app_delegate_class() -> *const Class { - static mut DELEGATE_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_app_delegate_class() -> &'static Class { + static mut DELEGATE_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -453,8 +453,8 @@ pub(crate) fn register_app_delegate_class() -> *co delegate_handles_key:: as extern "C" fn(_, _, _, _) -> _ ); - DELEGATE_CLASS = decl.register(); + DELEGATE_CLASS = Some(decl.register()); }); - unsafe { DELEGATE_CLASS } + unsafe { DELEGATE_CLASS.unwrap() } } diff --git a/src/appkit/app/mod.rs b/src/appkit/app/mod.rs index ae0ee2c3..99554580 100644 --- a/src/appkit/app/mod.rs +++ b/src/appkit/app/mod.rs @@ -39,9 +39,9 @@ use std::sync::{Arc, Mutex}; use lazy_static::lazy_static; -use crate::id_shim::Id; +use objc::rc::{Id, Owned}; use objc::runtime::Object; -use objc::{class, msg_send, sel}; +use objc::{class, msg_send, msg_send_id, sel}; use crate::appkit::menu::Menu; use crate::foundation::{id, nil, AutoReleasePool, NSUInteger, NO, YES}; @@ -86,11 +86,11 @@ fn shared_application(handler: F) { /// application. pub struct App { /// The underlying Objective-C Object. - pub objc: Id, + pub objc: Id, /// The underlying Objective-C Object, which in this case is a delegate that forwards to the /// app delegate. - pub objc_delegate: Id, + pub objc_delegate: Id, /// The stored `AppDelegate`. pub delegate: Box, @@ -142,20 +142,17 @@ where let pool = AutoReleasePool::new(); - let objc = unsafe { - let app: id = msg_send![register_app_class(), sharedApplication]; - Id::from_ptr(app) - }; + let objc = unsafe { msg_send_id![register_app_class(), sharedApplication].unwrap() }; let app_delegate = Box::new(delegate); let objc_delegate = unsafe { let delegate_class = register_app_delegate_class::(); - let delegate: id = msg_send![delegate_class, new]; + let mut delegate: Id = msg_send_id![delegate_class, new].unwrap(); let delegate_ptr: *const T = &*app_delegate; - (&mut *delegate).set_ivar(APP_PTR, delegate_ptr as usize); - let _: () = msg_send![&*objc, setDelegate: delegate]; - Id::from_ptr(delegate) + delegate.set_ivar(APP_PTR, delegate_ptr as usize); + let _: () = msg_send![&*objc, setDelegate: &*delegate]; + delegate }; App { diff --git a/src/appkit/event/mod.rs b/src/appkit/event/mod.rs index 8db0239f..fc6bcda6 100644 --- a/src/appkit/event/mod.rs +++ b/src/appkit/event/mod.rs @@ -1,8 +1,8 @@ use block::ConcreteBlock; -use crate::id_shim::Id; +use objc::rc::{Id, Owned}; use objc::runtime::Object; -use objc::{class, msg_send, sel}; +use objc::{class, msg_send, msg_send_id, sel}; use crate::foundation::{id, nil, NSString}; @@ -14,15 +14,15 @@ pub enum EventMask { /// A wrapper over an `NSEvent`. #[derive(Debug)] -pub struct EventMonitor(pub Id); +pub struct EventMonitor(pub Id); /// A wrapper over an `NSEvent`. #[derive(Debug)] -pub struct Event(pub Id); +pub struct Event(pub Id); impl Event { pub(crate) fn new(objc: id) -> Self { - Event(unsafe { Id::from_ptr(objc) }) + Event(unsafe { Id::retain(objc).unwrap() }) } pub fn characters(&self) -> String { @@ -68,11 +68,12 @@ impl Event { let block = block.copy(); EventMonitor(unsafe { - Id::from_ptr(msg_send![ + msg_send_id![ class!(NSEvent), addLocalMonitorForEventsMatchingMask: 1024, handler: &*block, - ]) + ] + .unwrap() }) } } diff --git a/src/appkit/menu/item.rs b/src/appkit/menu/item.rs index a39eaa48..6712c606 100644 --- a/src/appkit/menu/item.rs +++ b/src/appkit/menu/item.rs @@ -5,11 +5,11 @@ use std::fmt; use std::sync::Once; -use crate::id_shim::Id; use block::ConcreteBlock; use objc::declare::ClassDecl; +use objc::rc::{Id, Owned}; use objc::runtime::{Class, Object, Sel}; -use objc::{class, msg_send, sel}; +use objc::{class, msg_send, msg_send_id, sel}; use crate::events::EventModifierFlag; use crate::foundation::{id, nil, NSString, NSUInteger}; @@ -40,7 +40,7 @@ fn make_menu_item>( key: Option<&str>, action: Option, modifiers: Option<&[EventModifierFlag]> -) -> Id { +) -> Id { unsafe { let title = NSString::new(title.as_ref()); @@ -53,14 +53,22 @@ fn make_menu_item>( // Stock menu items that use selectors targeted at system pieces are just standard // `NSMenuItem`s. If there's no custom ones, we use our subclass that has a slot to store a // handler pointer. - let alloc: id = msg_send![register_menu_item_class(), alloc]; - let item = Id::from_retained_ptr(match action { - Some(a) => msg_send![alloc, initWithTitle:&*title action:a keyEquivalent:&*key], - - None => msg_send![alloc, initWithTitle:&*title - action:sel!(fireBlockAction:) - keyEquivalent:&*key] - }); + let alloc = msg_send_id![register_menu_item_class(), alloc]; + let item = match action { + Some(a) => msg_send_id![ + alloc, + initWithTitle: &*title, + action: a, + keyEquivalent: &*key, + ], + None => msg_send_id![ + alloc, + initWithTitle: &*title, + action: sel!(fireBlockAction:), + keyEquivalent: &*key, + ] + } + .unwrap(); if let Some(modifiers) = modifiers { let mut key_mask: NSUInteger = 0; @@ -86,7 +94,7 @@ pub enum MenuItem { /// You can (and should) create this variant via the `new(title)` method, but if you need to do /// something crazier, then wrap it in this and you can hook into the Cacao menu system /// accordingly. - Custom(Id), + Custom(Id), /// Shows a standard "About" item, which will bring up the necessary window when clicked /// (include a `credits.html` in your App to make use of here). The argument baked in here @@ -153,7 +161,7 @@ pub enum MenuItem { impl MenuItem { /// Consumes and returns a handle for the underlying MenuItem. This is internal as we make a few assumptions /// for how it interacts with our `Menu` setup, but this could be made public in the future. - pub(crate) unsafe fn to_objc(self) -> Id { + pub(crate) unsafe fn to_objc(self) -> Id { match self { Self::Custom(objc) => objc, @@ -210,8 +218,7 @@ impl MenuItem { Self::Separator => { let cls = class!(NSMenuItem); - let separator: id = msg_send![cls, separatorItem]; - Id::from_ptr(separator) + msg_send_id![cls, separatorItem].unwrap() } } } @@ -313,8 +320,8 @@ extern "C" fn fire_block_action(this: &Object, _: Sel, _item: id) { /// /// In general, we do not want to do more than we need to here - menus are one of the last areas /// where Carbon still lurks, and subclassing things can get weird. -pub(crate) fn register_menu_item_class() -> *const Class { - static mut APP_CLASS: *const Class = 0 as *const Class; +pub(crate) fn register_menu_item_class() -> &'static Class { + static mut APP_CLASS: Option<&'static Class> = None; static INIT: Once = Once::new(); INIT.call_once(|| unsafe { @@ -325,8 +332,8 @@ pub(crate) fn register_menu_item_class() -> *const Class { decl.add_method(sel!(dealloc), dealloc_cacao_menuitem as extern "C" fn(_, _)); decl.add_method(sel!(fireBlockAction:), fire_block_action as extern "C" fn(_, _, _)); - APP_CLASS = decl.register(); + APP_CLASS = Some(decl.register()); }); - unsafe { APP_CLASS } + unsafe { APP_CLASS.unwrap() } } diff --git a/src/appkit/menu/menu.rs b/src/appkit/menu/menu.rs index 184e8c03..2044c8ae 100644 --- a/src/appkit/menu/menu.rs +++ b/src/appkit/menu/menu.rs @@ -2,9 +2,9 @@ use std::sync::{Arc, Mutex}; -use crate::id_shim::{Id, ShareId}; +use objc::rc::{Id, Owned, Shared}; use objc::runtime::Object; -use objc::{class, msg_send, sel}; +use objc::{class, msg_send, msg_send_id, sel}; use crate::appkit::menu::item::MenuItem; use crate::foundation::{id, NSInteger, NSString}; @@ -12,7 +12,7 @@ use crate::foundation::{id, NSInteger, NSString}; /// A struct that represents an `NSMenu`. It takes ownership of items, and handles instrumenting /// them throughout the application lifecycle. #[derive(Debug)] -pub struct Menu(pub Id); +pub struct Menu(pub Id); impl Menu { /// Creates a new `Menu` with the given title, and uses the passed items as submenu items. @@ -27,16 +27,16 @@ impl Menu { pub fn new(title: &str, items: Vec) -> Self { Menu(unsafe { let cls = class!(NSMenu); - let alloc: id = msg_send![cls, alloc]; + let alloc = msg_send_id![cls, alloc]; let title = NSString::new(title); - let menu: id = msg_send![alloc, initWithTitle:&*title]; + let mut menu = msg_send_id![alloc, initWithTitle: &*title].unwrap(); for item in items.into_iter() { let objc = item.to_objc(); - let _: () = msg_send![menu, addItem:&*objc]; + let _: () = msg_send![&mut menu, addItem:&*objc]; } - Id::from_retained_ptr(menu) + menu }) } diff --git a/src/appkit/printing/settings.rs b/src/appkit/printing/settings.rs index 40df0841..b13281bb 100644 --- a/src/appkit/printing/settings.rs +++ b/src/appkit/printing/settings.rs @@ -1,7 +1,7 @@ //! Represents settings for printing items. Backed by an `NSDictionary` in Objective-C, this struct //! aims to make it easier to query/process printing operations. -use crate::id_shim::ShareId; +use objc::rc::{Id, Shared}; use objc::runtime::Object; use crate::foundation::id; @@ -10,14 +10,14 @@ use crate::foundation::id; /// application/user. #[derive(Clone, Debug)] pub struct PrintSettings { - pub inner: ShareId + pub inner: Id } impl PrintSettings { /// Internal method, constructs a wrapper around the backing `NSDictionary` print settings. pub(crate) fn with_inner(inner: id) -> Self { PrintSettings { - inner: unsafe { ShareId::from_ptr(inner) } + inner: unsafe { Id::retain(inner).unwrap() } } } } diff --git a/src/appkit/toolbar/class.rs b/src/appkit/toolbar/class.rs index 29139fcb..feecfda0 100644 --- a/src/appkit/toolbar/class.rs +++ b/src/appkit/toolbar/class.rs @@ -65,7 +65,7 @@ extern "C" fn item_for_identifier(this: &Object, _: Sel, _: /// Registers a `NSToolbar` subclass, and configures it to hold some ivars for various things we need /// to store. We use it as our delegate as well, just to cut down on moving pieces. -pub(crate) fn register_toolbar_class(instance: &T) -> *const Class { +pub(crate) fn register_toolbar_class(instance: &T) -> &'static Class { load_or_register_class("NSObject", instance.subclass_name(), |decl| unsafe { // For callbacks decl.add_ivar::(TOOLBAR_PTR); diff --git a/src/appkit/toolbar/item.rs b/src/appkit/toolbar/item.rs index c3908ab4..b8a36b80 100644 --- a/src/appkit/toolbar/item.rs +++ b/src/appkit/toolbar/item.rs @@ -6,9 +6,9 @@ use core_graphics::geometry::CGSize; use std::fmt; -use crate::id_shim::{Id, ShareId}; +use objc::rc::{Id, Owned, Shared}; use objc::runtime::Object; -use objc::{class, msg_send, sel}; +use objc::{class, msg_send, msg_send_id, sel}; use crate::button::{BezelStyle, Button}; use crate::foundation::{id, NSString, NO, YES}; @@ -19,7 +19,7 @@ use crate::invoker::TargetActionHandler; #[derive(Debug)] pub struct ToolbarItem { pub identifier: String, - pub objc: Id, + pub objc: Id, pub button: Option