Skip to content

Commit 7e58561

Browse files
authored
Merge pull request #498 from silvanshade/example-refactoring-once-cell
Refactor browser and metal examples to use OnceCell
2 parents c4dfb53 + f9db7ee commit 7e58561

File tree

2 files changed

+40
-22
lines changed

2 files changed

+40
-22
lines changed

crates/icrate/examples/browser.rs

+22-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![deny(unsafe_op_in_unsafe_fn)]
2-
use core::{cell::RefCell, ptr::NonNull};
2+
use core::{cell::OnceCell, ptr::NonNull};
33

44
use icrate::{
55
AppKit::{
@@ -26,20 +26,29 @@ use objc2::{
2626
sel, ClassType,
2727
};
2828

29-
type IdCell<T> = Box<RefCell<Option<Id<T>>>>;
29+
type IdCell<T> = Box<OnceCell<Id<T>>>;
3030

3131
macro_rules! idcell {
32+
($name:ident => $this:expr) => {
33+
$this.$name.set($name).expect(&format!(
34+
"ivar should not already be initialized: `{}`",
35+
stringify!($name)
36+
));
37+
};
3238
($name:ident <= $this:expr) => {
33-
let $name = $this.$name.borrow();
34-
let $name = $name
35-
.as_ref()
36-
.expect(concat!(stringify!($name), " ivar should be initialized"));
39+
#[rustfmt::skip]
40+
let Some($name) = $this.$name.get() else {
41+
unreachable!(
42+
"ivar should be initialized: `{}`",
43+
stringify!($name)
44+
)
45+
};
3746
};
3847
}
3948

4049
declare_class!(
4150
struct Delegate {
42-
text_field: IvarDrop<IdCell<NSTextField>, "_text_field">,
51+
nav_url: IvarDrop<IdCell<NSTextField>, "_nav_url">,
4352
web_view: IvarDrop<IdCell<WKWebView>, "_web_view">,
4453
window: IvarDrop<IdCell<NSWindow>, "_window">,
4554
}
@@ -56,7 +65,7 @@ declare_class!(
5665
unsafe fn init(this: *mut Self) -> Option<NonNull<Self>> {
5766
let this: Option<&mut Self> = msg_send![super(this), init];
5867
this.map(|this| {
59-
Ivar::write(&mut this.text_field, IdCell::default());
68+
Ivar::write(&mut this.nav_url, IdCell::default());
6069
Ivar::write(&mut this.web_view, IdCell::default());
6170
Ivar::write(&mut this.window, IdCell::default());
6271
NonNull::from(this)
@@ -232,9 +241,9 @@ declare_class!(
232241
web_view.loadRequest(&request);
233242
}
234243

235-
self.text_field.replace(Some(nav_url));
236-
self.web_view.replace(Some(web_view));
237-
self.window.replace(Some(window));
244+
idcell!(nav_url => self);
245+
idcell!(web_view => self);
246+
idcell!(window => self);
238247
}
239248
}
240249

@@ -268,10 +277,10 @@ declare_class!(
268277
web_view: &WKWebView,
269278
_navigation: Option<&WKNavigation>,
270279
) {
271-
idcell!(text_field <= self);
280+
idcell!(nav_url <= self);
272281
unsafe {
273282
if let Some(url) = web_view.URL().and_then(|url| url.absoluteString()) {
274-
text_field.setStringValue(&url);
283+
nav_url.setStringValue(&url);
275284
}
276285
}
277286
}

crates/icrate/examples/metal.rs

+18-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![deny(unsafe_op_in_unsafe_fn)]
22

3-
use core::{cell::RefCell, ptr::NonNull};
3+
use core::{cell::OnceCell, ptr::NonNull};
44

55
use icrate::{
66
AppKit::{
@@ -101,14 +101,23 @@ pub struct Color {
101101
pub b: f32,
102102
}
103103

104-
type IdCell<T> = Box<RefCell<Option<Id<T>>>>;
104+
type IdCell<T> = Box<OnceCell<Id<T>>>;
105105

106106
macro_rules! idcell {
107+
($name:ident => $this:expr) => {
108+
$this.$name.set($name).expect(&format!(
109+
"ivar should not already be initialized: `{}`",
110+
stringify!($name)
111+
));
112+
};
107113
($name:ident <= $this:expr) => {
108-
let $name = $this.$name.borrow();
109-
let $name = $name
110-
.as_ref()
111-
.expect(concat!(stringify!($name), " ivar should be initialized"));
114+
#[rustfmt::skip]
115+
let Some($name) = $this.$name.get() else {
116+
unreachable!(
117+
"ivar should be initialized: `{}`",
118+
stringify!($name)
119+
)
120+
};
112121
};
113122
}
114123

@@ -229,9 +238,9 @@ declare_class!(
229238
window.makeKeyAndOrderFront(None);
230239

231240
// initialize the delegate state
232-
self.command_queue.replace(Some(command_queue));
233-
self.pipeline_state.replace(Some(pipeline_state));
234-
self.window.replace(Some(window));
241+
idcell!(command_queue => self);
242+
idcell!(pipeline_state => self);
243+
idcell!(window => self);
235244
}
236245
}
237246

0 commit comments

Comments
 (0)