diff --git a/crates/icrate/examples/browser.rs b/crates/icrate/examples/browser.rs index 37c256ddf..d25d71038 100644 --- a/crates/icrate/examples/browser.rs +++ b/crates/icrate/examples/browser.rs @@ -1,5 +1,5 @@ #![deny(unsafe_op_in_unsafe_fn)] -use core::{cell::RefCell, ptr::NonNull}; +use core::{cell::OnceCell, ptr::NonNull}; use icrate::{ AppKit::{ @@ -26,20 +26,29 @@ use objc2::{ sel, ClassType, }; -type IdCell = Box>>>; +type IdCell = Box>>; macro_rules! idcell { + ($name:ident => $this:expr) => { + $this.$name.set($name).expect(&format!( + "ivar should not already be initialized: `{}`", + concat!(stringify!($name)) + )); + }; ($name:ident <= $this:expr) => { - let $name = $this.$name.borrow(); - let $name = $name - .as_ref() - .expect(concat!(stringify!($name), " ivar should be initialized")); + let Some($name) = $this.$name.get() else { + // NOTE: could use `core::hint::unreachable_unchecked` here + unreachable!( + "ivar should be initialized: `{}`", + concat!(stringify!($name)) + ) + }; }; } declare_class!( struct Delegate { - text_field: IvarDrop, "_text_field">, + nav_url: IvarDrop, "_nav_url">, web_view: IvarDrop, "_web_view">, window: IvarDrop, "_window">, } @@ -56,7 +65,7 @@ declare_class!( unsafe fn init(this: *mut Self) -> Option> { let this: Option<&mut Self> = msg_send![super(this), init]; this.map(|this| { - Ivar::write(&mut this.text_field, IdCell::default()); + Ivar::write(&mut this.nav_url, IdCell::default()); Ivar::write(&mut this.web_view, IdCell::default()); Ivar::write(&mut this.window, IdCell::default()); NonNull::from(this) @@ -234,9 +243,9 @@ declare_class!( web_view.loadRequest(&request); } - self.text_field.replace(Some(nav_url)); - self.web_view.replace(Some(web_view)); - self.window.replace(Some(window)); + idcell!(nav_url => self); + idcell!(web_view => self); + idcell!(window => self); } } @@ -270,10 +279,10 @@ declare_class!( web_view: &WKWebView, _navigation: Option<&WKNavigation>, ) { - idcell!(text_field <= self); + idcell!(nav_url <= self); unsafe { if let Some(url) = web_view.URL().and_then(|url| url.absoluteString()) { - text_field.setStringValue(&url); + nav_url.setStringValue(&url); } } } diff --git a/crates/icrate/examples/metal.rs b/crates/icrate/examples/metal.rs index 8c64ae2cd..ea93be322 100644 --- a/crates/icrate/examples/metal.rs +++ b/crates/icrate/examples/metal.rs @@ -1,6 +1,6 @@ #![deny(unsafe_op_in_unsafe_fn)] -use core::{cell::RefCell, ptr::NonNull}; +use core::{cell::OnceCell, ptr::NonNull}; use icrate::{ AppKit::{ @@ -101,14 +101,23 @@ pub struct Color { pub b: f32, } -type IdCell = Box>>>; +type IdCell = Box>>; macro_rules! idcell { + ($name:ident => $this:expr) => { + $this.$name.set($name).expect(&format!( + "ivar should not already be initialized: `{}`", + concat!(stringify!($name)) + )); + }; ($name:ident <= $this:expr) => { - let $name = $this.$name.borrow(); - let $name = $name - .as_ref() - .expect(concat!(stringify!($name), " ivar should be initialized")); + let Some($name) = $this.$name.get() else { + // NOTE: could use `core::hint::unreachable_unchecked` here + unreachable!( + "ivar should be initialized: `{}`", + concat!(stringify!($name)) + ) + }; }; } @@ -231,9 +240,9 @@ declare_class!( } // initialize the delegate state - self.command_queue.replace(Some(command_queue)); - self.pipeline_state.replace(Some(pipeline_state)); - self.window.replace(Some(window)); + idcell!(command_queue => self); + idcell!(pipeline_state => self); + idcell!(window => self); } }