Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial conversion to objc2 #30

Merged
merged 19 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 15 additions & 16 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,7 @@ impl View {
center_x: LayoutAnchorX::center(view),
center_y: LayoutAnchorY::center(view),

layer: Layer::wrap(unsafe {
msg_send![view, layer]
}),
layer: Layer::from_id(unsafe { msg_send_id![view, layer] }),

objc: ObjcProperty::retain(view),
}
Expand Down Expand Up @@ -293,7 +291,8 @@ impl<T> View<T> {

#[cfg(target_os = "macos")]
self.objc.with_mut(|obj| unsafe {
(&mut *obj).set_ivar(BACKGROUND_COLOR, color);
// TODO: Fix this unnecessary retain!
(&mut *obj).set_ivar::<id>(BACKGROUND_COLOR, msg_send![color, retain]);
});

#[cfg(target_os = "ios")]
Expand Down Expand Up @@ -352,22 +351,22 @@ 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 {
let superclass = class!(NSView);
let mut decl = ClassDecl::new("RSTView", 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(_, _) -> _);

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

VIEW_CLASS = decl.register();
VIEW_CLASS = Some(decl.register());
});

unsafe { VIEW_CLASS }
unsafe { VIEW_CLASS.unwrap() }
}
```

Expand All @@ -377,19 +376,19 @@ 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<T: ViewDelegate>(instance: &T) -> *const Class {
pub(crate) fn register_view_class_with_delegate<T: ViewDelegate>(instance: &T) -> &'static Class {
load_or_register_class("NSView", instance.subclass_name(), |decl| unsafe {
decl.add_ivar::<usize>(VIEW_DELEGATE_PTR);
decl.add_ivar::<id>(BACKGROUND_COLOR);

decl.add_method(
sel!(isFlipped),
enforce_normalcy as extern "C" fn(&Object, _) -> BOOL
enforce_normalcy as extern "C" fn(_, _) -> _,
);

decl.add_method(
sel!(draggingEntered:),
dragging_entered::<T> as extern "C" fn (&mut Object, _, _) -> NSUInteger
dragging_entered::<T> as extern "C" fn (_, _, _) -> _,
);
})
}
Expand All @@ -401,18 +400,18 @@ to the Rust `ViewDelegate` implementation.
The methods we're setting up can range from simple to complex - take `isFlipped`:

``` rust
extern "C" fn is_flipped(_: &Object, _: Sel) -> BOOL {
return YES;
extern "C" fn is_flipped(_: &Object, _: Sel) -> Bool {
return Bool::YES;
}
```

Here, we just want to tell `NSView` to use top,left as the origin point, so we need to respond `YES` in this subclass method.
Here, we just want to tell `NSView` to use top,left as the origin point, so we need to respond `Bool::YES` in this subclass method.

``` rust
extern "C" fn dragging_entered<T: ViewDelegate>(this: &mut Object, _: Sel, info: id) -> NSUInteger {
let view = utils::load::<T>(this, VIEW_DELEGATE_PTR);
view.dragging_entered(DragInfo {
info: unsafe { Id::from_ptr(info) }
info: unsafe { Id::retain(info).unwrap() }
}).into()
}
```
Expand Down
11 changes: 6 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ rustdoc-args = ["--cfg", "docsrs"]

[dependencies]
bitmask-enum = "2.2.1"
block = "0.1.6"
core-foundation = "0.9"
core-graphics = "0.23"
objc = { version = "=0.3.0-beta.2", package = "objc2" }
block = { version = "=0.2.0-alpha.6", package = "block2" }
# Temporary: Patched versions that implement `Encode` for common types
# Branch: `objc2`
core-foundation = { git = "https://github.com/madsmtm/core-foundation-rs.git", rev = "7d593d016175755e492a92ef89edca68ac3bd5cd" }
core-graphics = { git = "https://github.com/madsmtm/core-foundation-rs.git", rev = "7d593d016175755e492a92ef89edca68ac3bd5cd" }
dispatch = "0.2.0"
infer = { version = "0.15", optional = true }
lazy_static = "1.4.0"
libc = "0.2"
objc = "0.2.7"
objc_id = "0.1.1"
os_info = "3.0.1"
url = "2.1.1"
uuid = { version = "1.1", features = ["v4"], optional = true }
Expand Down
6 changes: 3 additions & 3 deletions examples/browser/toolbar.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cacao::objc::{msg_send, sel, sel_impl};
use cacao::objc::{msg_send, sel};

use cacao::button::Button;
use cacao::input::{TextField, TextFieldDelegate};
Expand Down Expand Up @@ -35,12 +35,12 @@ impl BrowserToolbar {
let back_button = Button::new("Back");
let mut back_item = ToolbarItem::new(BACK_BUTTON);
back_item.set_button(back_button);
back_item.set_action(|| Action::Back.dispatch());
back_item.set_action(|_| Action::Back.dispatch());

let forwards_button = Button::new("Forwards");
let mut forwards_item = ToolbarItem::new(FWDS_BUTTON);
forwards_item.set_button(forwards_button);
forwards_item.set_action(|| Action::Forwards.dispatch());
forwards_item.set_action(|_| Action::Forwards.dispatch());

let url_bar = TextField::with(URLBar);
let url_bar_item = ToolbarItem::new(URL_BAR);
Expand Down
16 changes: 8 additions & 8 deletions src/appkit/alert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@
//! }
//! ```

use objc::rc::{Id, Owned};
use objc::runtime::Object;
use objc::{class, msg_send, sel, sel_impl};
use objc_id::Id;
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<Object>);
pub struct Alert(Id<Object, Owned>);

impl Alert {
/// Creates a basic `NSAlert`, storing a pointer to it in the Objective C runtime.
Expand All @@ -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];
let _: () = msg_send![&mut alert, setMessageText: &*title];
let _: () = msg_send![&mut alert, setInformativeText: &*message];
let _: () = msg_send![&mut alert, addButtonWithTitle: &*ok];
alert
})
}

Expand Down
11 changes: 7 additions & 4 deletions src/appkit/animation.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use block::ConcreteBlock;
use objc::{class, msg_send, sel, sel_impl};
use objc::{class, msg_send, sel};

use crate::foundation::id;

Expand Down Expand Up @@ -39,7 +39,7 @@ impl AnimationContext {

unsafe {
//let context: id = msg_send![class!(NSAnimationContext), currentContext];
let _: () = msg_send![class!(NSAnimationContext), runAnimationGroup: block];
let _: () = msg_send![class!(NSAnimationContext), runAnimationGroup: &*block];
}
}

Expand All @@ -66,8 +66,11 @@ impl AnimationContext {

unsafe {
//let context: id = msg_send![class!(NSAnimationContext), currentContext];
let _: () = msg_send![class!(NSAnimationContext), runAnimationGroup:block
completionHandler:completion_block];
let _: () = msg_send![
class!(NSAnimationContext),
runAnimationGroup: &*block,
completionHandler: &*completion_block,
];
}
}
}
2 changes: 1 addition & 1 deletion src/appkit/app/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ use objc::runtime::Class;
use crate::foundation::load_or_register_class;

/// Used for injecting a custom NSApplication. Currently does nothing.
pub(crate) fn register_app_class() -> *const Class {
pub(crate) fn register_app_class() -> &'static Class {
load_or_register_class("NSApplication", "RSTApplication", |decl| unsafe {})
}
Loading
Loading