Skip to content

Commit 6806194

Browse files
committed
Use msg_send_id! and rc::Id
1 parent 8357f38 commit 6806194

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+657
-684
lines changed

ARCHITECTURE.md

+6-6
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,8 @@ We'll step through an example (abridged) `View` bridge below, for macOS. You sho
352352
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.
353353

354354
``` rust
355-
pub(crate) fn register_view_class() -> *const Class {
356-
static mut VIEW_CLASS: *const Class = 0 as *const Class;
355+
pub(crate) fn register_view_class() -> &'static Class {
356+
static mut VIEW_CLASS: Option<'static Class> = None;
357357
static INIT: Once = Once::new();
358358

359359
INIT.call_once(|| unsafe {
@@ -364,10 +364,10 @@ pub(crate) fn register_view_class() -> *const Class {
364364

365365
decl.add_ivar::<id>(BACKGROUND_COLOR);
366366

367-
VIEW_CLASS = decl.register();
367+
VIEW_CLASS = Some(decl.register());
368368
});
369369

370-
unsafe { VIEW_CLASS }
370+
unsafe { VIEW_CLASS.unwrap() }
371371
}
372372
```
373373

@@ -377,7 +377,7 @@ Objective-C method signatures, as well as provision space for variable storage (
377377
For our _delegate_ types, we need a different class creation method - one that creates a subclass per-unique-type:
378378

379379
``` rust
380-
pub(crate) fn register_view_class_with_delegate<T: ViewDelegate>(instance: &T) -> *const Class {
380+
pub(crate) fn register_view_class_with_delegate<T: ViewDelegate>(instance: &T) -> &'static Class {
381381
load_or_register_class("NSView", instance.subclass_name(), |decl| unsafe {
382382
decl.add_ivar::<usize>(VIEW_DELEGATE_PTR);
383383
decl.add_ivar::<id>(BACKGROUND_COLOR);
@@ -412,7 +412,7 @@ Here, we just want to tell `NSView` to use top,left as the origin point, so we n
412412
extern "C" fn dragging_entered<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) -> NSUInteger {
413413
let view = utils::load::<T>(this, VIEW_DELEGATE_PTR);
414414
view.dragging_entered(DragInfo {
415-
info: unsafe { Id::from_ptr(info) }
415+
info: unsafe { Id::retain(info).unwrap() }
416416
}).into()
417417
}
418418
```

src/appkit/alert.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@
2424
//! }
2525
//! ```
2626
27-
use crate::id_shim::Id;
27+
use objc::rc::{Id, Owned};
2828
use objc::runtime::Object;
29-
use objc::{class, msg_send, sel};
29+
use objc::{class, msg_send, msg_send_id, sel};
3030

3131
use crate::foundation::{id, NSString};
3232

3333
/// Represents an `NSAlert`. Has no information other than the retained pointer to the Objective C
3434
/// side, so... don't bother inspecting this.
3535
#[derive(Debug)]
36-
pub struct Alert(Id<Object>);
36+
pub struct Alert(Id<Object, Owned>);
3737

3838
impl Alert {
3939
/// Creates a basic `NSAlert`, storing a pointer to it in the Objective C runtime.
@@ -44,11 +44,11 @@ impl Alert {
4444
let ok = NSString::new("OK");
4545

4646
Alert(unsafe {
47-
let alert: id = msg_send![class!(NSAlert), new];
48-
let _: () = msg_send![alert, setMessageText: &*title];
49-
let _: () = msg_send![alert, setInformativeText: &*message];
50-
let _: () = msg_send![alert, addButtonWithTitle: &*ok];
51-
Id::from_ptr(alert)
47+
let mut alert = msg_send_id![class!(NSAlert), new].unwrap();
48+
let _: () = msg_send![&mut alert, setMessageText: &*title];
49+
let _: () = msg_send![&mut alert, setInformativeText: &*message];
50+
let _: () = msg_send![&mut alert, addButtonWithTitle: &*ok];
51+
alert
5252
})
5353
}
5454

src/appkit/app/class.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ use objc::declare::ClassDecl;
99
use objc::runtime::Class;
1010

1111
/// Used for injecting a custom NSApplication. Currently does nothing.
12-
pub(crate) fn register_app_class() -> *const Class {
13-
static mut APP_CLASS: *const Class = 0 as *const Class;
12+
pub(crate) fn register_app_class() -> &'static Class {
13+
static mut APP_CLASS: Option<&'static Class> = None;
1414
static INIT: Once = Once::new();
1515

1616
INIT.call_once(|| unsafe {
1717
let superclass = class!(NSApplication);
1818
let decl = ClassDecl::new("RSTApplication", superclass).unwrap();
19-
APP_CLASS = decl.register();
19+
APP_CLASS = Some(decl.register());
2020
});
2121

22-
unsafe { APP_CLASS }
22+
unsafe { APP_CLASS.unwrap() }
2323
}

src/appkit/app/delegate.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,8 @@ extern "C" fn delegate_handles_key<T: AppDelegate>(this: &Object, _: Sel, _: id,
294294

295295
/// Registers an `NSObject` application delegate, and configures it for the various callbacks and
296296
/// pointers we need to have.
297-
pub(crate) fn register_app_delegate_class<T: AppDelegate + AppDelegate>() -> *const Class {
298-
static mut DELEGATE_CLASS: *const Class = 0 as *const Class;
297+
pub(crate) fn register_app_delegate_class<T: AppDelegate + AppDelegate>() -> &'static Class {
298+
static mut DELEGATE_CLASS: Option<&'static Class> = None;
299299
static INIT: Once = Once::new();
300300

301301
INIT.call_once(|| unsafe {
@@ -453,8 +453,8 @@ pub(crate) fn register_app_delegate_class<T: AppDelegate + AppDelegate>() -> *co
453453
delegate_handles_key::<T> as extern "C" fn(_, _, _, _) -> _
454454
);
455455

456-
DELEGATE_CLASS = decl.register();
456+
DELEGATE_CLASS = Some(decl.register());
457457
});
458458

459-
unsafe { DELEGATE_CLASS }
459+
unsafe { DELEGATE_CLASS.unwrap() }
460460
}

src/appkit/app/mod.rs

+9-12
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ use std::sync::{Arc, Mutex};
3939

4040
use lazy_static::lazy_static;
4141

42-
use crate::id_shim::Id;
42+
use objc::rc::{Id, Owned};
4343
use objc::runtime::Object;
44-
use objc::{class, msg_send, sel};
44+
use objc::{class, msg_send, msg_send_id, sel};
4545

4646
use crate::appkit::menu::Menu;
4747
use crate::foundation::{id, nil, AutoReleasePool, NSUInteger, NO, YES};
@@ -86,11 +86,11 @@ fn shared_application<F: Fn(id)>(handler: F) {
8686
/// application.
8787
pub struct App<T = (), M = ()> {
8888
/// The underlying Objective-C Object.
89-
pub objc: Id<Object>,
89+
pub objc: Id<Object, Owned>,
9090

9191
/// The underlying Objective-C Object, which in this case is a delegate that forwards to the
9292
/// app delegate.
93-
pub objc_delegate: Id<Object>,
93+
pub objc_delegate: Id<Object, Owned>,
9494

9595
/// The stored `AppDelegate`.
9696
pub delegate: Box<T>,
@@ -142,20 +142,17 @@ where
142142

143143
let pool = AutoReleasePool::new();
144144

145-
let objc = unsafe {
146-
let app: id = msg_send![register_app_class(), sharedApplication];
147-
Id::from_ptr(app)
148-
};
145+
let objc = unsafe { msg_send_id![register_app_class(), sharedApplication].unwrap() };
149146

150147
let app_delegate = Box::new(delegate);
151148

152149
let objc_delegate = unsafe {
153150
let delegate_class = register_app_delegate_class::<T>();
154-
let delegate: id = msg_send![delegate_class, new];
151+
let mut delegate: Id<Object, Owned> = msg_send_id![delegate_class, new].unwrap();
155152
let delegate_ptr: *const T = &*app_delegate;
156-
(&mut *delegate).set_ivar(APP_PTR, delegate_ptr as usize);
157-
let _: () = msg_send![&*objc, setDelegate: delegate];
158-
Id::from_ptr(delegate)
153+
delegate.set_ivar(APP_PTR, delegate_ptr as usize);
154+
let _: () = msg_send![&*objc, setDelegate: &*delegate];
155+
delegate
159156
};
160157

161158
App {

src/appkit/event/mod.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use block::ConcreteBlock;
22

3-
use crate::id_shim::Id;
3+
use objc::rc::{Id, Owned};
44
use objc::runtime::Object;
5-
use objc::{class, msg_send, sel};
5+
use objc::{class, msg_send, msg_send_id, sel};
66

77
use crate::foundation::{id, nil, NSString};
88

@@ -14,15 +14,15 @@ pub enum EventMask {
1414

1515
/// A wrapper over an `NSEvent`.
1616
#[derive(Debug)]
17-
pub struct EventMonitor(pub Id<Object>);
17+
pub struct EventMonitor(pub Id<Object, Owned>);
1818

1919
/// A wrapper over an `NSEvent`.
2020
#[derive(Debug)]
21-
pub struct Event(pub Id<Object>);
21+
pub struct Event(pub Id<Object, Owned>);
2222

2323
impl Event {
2424
pub(crate) fn new(objc: id) -> Self {
25-
Event(unsafe { Id::from_ptr(objc) })
25+
Event(unsafe { Id::retain(objc).unwrap() })
2626
}
2727

2828
pub fn characters(&self) -> String {
@@ -68,11 +68,12 @@ impl Event {
6868
let block = block.copy();
6969

7070
EventMonitor(unsafe {
71-
Id::from_ptr(msg_send![
71+
msg_send_id![
7272
class!(NSEvent),
7373
addLocalMonitorForEventsMatchingMask: 1024,
7474
handler: &*block,
75-
])
75+
]
76+
.unwrap()
7677
})
7778
}
7879
}

src/appkit/menu/item.rs

+26-19
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
use std::fmt;
66
use std::sync::Once;
77

8-
use crate::id_shim::Id;
98
use block::ConcreteBlock;
109
use objc::declare::ClassDecl;
10+
use objc::rc::{Id, Owned};
1111
use objc::runtime::{Class, Object, Sel};
12-
use objc::{class, msg_send, sel};
12+
use objc::{class, msg_send, msg_send_id, sel};
1313

1414
use crate::events::EventModifierFlag;
1515
use crate::foundation::{id, nil, NSString, NSUInteger};
@@ -40,7 +40,7 @@ fn make_menu_item<S: AsRef<str>>(
4040
key: Option<&str>,
4141
action: Option<Sel>,
4242
modifiers: Option<&[EventModifierFlag]>
43-
) -> Id<Object> {
43+
) -> Id<Object, Owned> {
4444
unsafe {
4545
let title = NSString::new(title.as_ref());
4646

@@ -53,14 +53,22 @@ fn make_menu_item<S: AsRef<str>>(
5353
// Stock menu items that use selectors targeted at system pieces are just standard
5454
// `NSMenuItem`s. If there's no custom ones, we use our subclass that has a slot to store a
5555
// handler pointer.
56-
let alloc: id = msg_send![register_menu_item_class(), alloc];
57-
let item = Id::from_retained_ptr(match action {
58-
Some(a) => msg_send![alloc, initWithTitle:&*title action:a keyEquivalent:&*key],
59-
60-
None => msg_send![alloc, initWithTitle:&*title
61-
action:sel!(fireBlockAction:)
62-
keyEquivalent:&*key]
63-
});
56+
let alloc = msg_send_id![register_menu_item_class(), alloc];
57+
let item = match action {
58+
Some(a) => msg_send_id![
59+
alloc,
60+
initWithTitle: &*title,
61+
action: a,
62+
keyEquivalent: &*key,
63+
],
64+
None => msg_send_id![
65+
alloc,
66+
initWithTitle: &*title,
67+
action: sel!(fireBlockAction:),
68+
keyEquivalent: &*key,
69+
]
70+
}
71+
.unwrap();
6472

6573
if let Some(modifiers) = modifiers {
6674
let mut key_mask: NSUInteger = 0;
@@ -86,7 +94,7 @@ pub enum MenuItem {
8694
/// You can (and should) create this variant via the `new(title)` method, but if you need to do
8795
/// something crazier, then wrap it in this and you can hook into the Cacao menu system
8896
/// accordingly.
89-
Custom(Id<Object>),
97+
Custom(Id<Object, Owned>),
9098

9199
/// Shows a standard "About" item, which will bring up the necessary window when clicked
92100
/// (include a `credits.html` in your App to make use of here). The argument baked in here
@@ -153,7 +161,7 @@ pub enum MenuItem {
153161
impl MenuItem {
154162
/// Consumes and returns a handle for the underlying MenuItem. This is internal as we make a few assumptions
155163
/// for how it interacts with our `Menu` setup, but this could be made public in the future.
156-
pub(crate) unsafe fn to_objc(self) -> Id<Object> {
164+
pub(crate) unsafe fn to_objc(self) -> Id<Object, Owned> {
157165
match self {
158166
Self::Custom(objc) => objc,
159167

@@ -210,8 +218,7 @@ impl MenuItem {
210218

211219
Self::Separator => {
212220
let cls = class!(NSMenuItem);
213-
let separator: id = msg_send![cls, separatorItem];
214-
Id::from_ptr(separator)
221+
msg_send_id![cls, separatorItem].unwrap()
215222
}
216223
}
217224
}
@@ -313,8 +320,8 @@ extern "C" fn fire_block_action(this: &Object, _: Sel, _item: id) {
313320
///
314321
/// In general, we do not want to do more than we need to here - menus are one of the last areas
315322
/// where Carbon still lurks, and subclassing things can get weird.
316-
pub(crate) fn register_menu_item_class() -> *const Class {
317-
static mut APP_CLASS: *const Class = 0 as *const Class;
323+
pub(crate) fn register_menu_item_class() -> &'static Class {
324+
static mut APP_CLASS: Option<&'static Class> = None;
318325
static INIT: Once = Once::new();
319326

320327
INIT.call_once(|| unsafe {
@@ -325,8 +332,8 @@ pub(crate) fn register_menu_item_class() -> *const Class {
325332
decl.add_method(sel!(dealloc), dealloc_cacao_menuitem as extern "C" fn(_, _));
326333
decl.add_method(sel!(fireBlockAction:), fire_block_action as extern "C" fn(_, _, _));
327334

328-
APP_CLASS = decl.register();
335+
APP_CLASS = Some(decl.register());
329336
});
330337

331-
unsafe { APP_CLASS }
338+
unsafe { APP_CLASS.unwrap() }
332339
}

src/appkit/menu/menu.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
33
use std::sync::{Arc, Mutex};
44

5-
use crate::id_shim::{Id, ShareId};
5+
use objc::rc::{Id, Owned, Shared};
66
use objc::runtime::Object;
7-
use objc::{class, msg_send, sel};
7+
use objc::{class, msg_send, msg_send_id, sel};
88

99
use crate::appkit::menu::item::MenuItem;
1010
use crate::foundation::{id, NSInteger, NSString};
1111

1212
/// A struct that represents an `NSMenu`. It takes ownership of items, and handles instrumenting
1313
/// them throughout the application lifecycle.
1414
#[derive(Debug)]
15-
pub struct Menu(pub Id<Object>);
15+
pub struct Menu(pub Id<Object, Owned>);
1616

1717
impl Menu {
1818
/// Creates a new `Menu` with the given title, and uses the passed items as submenu items.
@@ -27,16 +27,16 @@ impl Menu {
2727
pub fn new(title: &str, items: Vec<MenuItem>) -> Self {
2828
Menu(unsafe {
2929
let cls = class!(NSMenu);
30-
let alloc: id = msg_send![cls, alloc];
30+
let alloc = msg_send_id![cls, alloc];
3131
let title = NSString::new(title);
32-
let menu: id = msg_send![alloc, initWithTitle:&*title];
32+
let mut menu = msg_send_id![alloc, initWithTitle: &*title].unwrap();
3333

3434
for item in items.into_iter() {
3535
let objc = item.to_objc();
36-
let _: () = msg_send![menu, addItem:&*objc];
36+
let _: () = msg_send![&mut menu, addItem:&*objc];
3737
}
3838

39-
Id::from_retained_ptr(menu)
39+
menu
4040
})
4141
}
4242

src/appkit/printing/settings.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Represents settings for printing items. Backed by an `NSDictionary` in Objective-C, this struct
22
//! aims to make it easier to query/process printing operations.
33
4-
use crate::id_shim::ShareId;
4+
use objc::rc::{Id, Shared};
55
use objc::runtime::Object;
66

77
use crate::foundation::id;
@@ -10,14 +10,14 @@ use crate::foundation::id;
1010
/// application/user.
1111
#[derive(Clone, Debug)]
1212
pub struct PrintSettings {
13-
pub inner: ShareId<Object>
13+
pub inner: Id<Object, Shared>
1414
}
1515

1616
impl PrintSettings {
1717
/// Internal method, constructs a wrapper around the backing `NSDictionary` print settings.
1818
pub(crate) fn with_inner(inner: id) -> Self {
1919
PrintSettings {
20-
inner: unsafe { ShareId::from_ptr(inner) }
20+
inner: unsafe { Id::retain(inner).unwrap() }
2121
}
2222
}
2323
}

src/appkit/toolbar/class.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ extern "C" fn item_for_identifier<T: ToolbarDelegate>(this: &Object, _: Sel, _:
6565

6666
/// Registers a `NSToolbar` subclass, and configures it to hold some ivars for various things we need
6767
/// to store. We use it as our delegate as well, just to cut down on moving pieces.
68-
pub(crate) fn register_toolbar_class<T: ToolbarDelegate>(instance: &T) -> *const Class {
68+
pub(crate) fn register_toolbar_class<T: ToolbarDelegate>(instance: &T) -> &'static Class {
6969
load_or_register_class("NSObject", instance.subclass_name(), |decl| unsafe {
7070
// For callbacks
7171
decl.add_ivar::<usize>(TOOLBAR_PTR);

0 commit comments

Comments
 (0)