Skip to content

Commit

Permalink
continue on watchos support
Browse files Browse the repository at this point in the history
  • Loading branch information
yury committed Jan 3, 2025
1 parent 35f32a7 commit 077a976
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 4 deletions.
1 change: 1 addition & 0 deletions cidre/src/core_motion/accelerometer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{core_motion as cm, define_obj_type, objc};

#[doc(alias = "CMAcceleration")]
#[derive(Debug, Copy, Clone, PartialEq)]
#[repr(C)]
pub struct Acceleration {
Expand Down
1 change: 1 addition & 0 deletions cidre/src/ns/date.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{arc, define_obj_type, ns, objc};

#[doc(alias = "NSTimeInterval")]
pub type TimeInterval = f64;

pub const TIME_INTERVAL_SINCE_1970: TimeInterval = 978307200.0f64;
Expand Down
85 changes: 83 additions & 2 deletions cidre/src/objc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,67 @@ impl<T: Obj> Class<T> {
#[derive(Debug)]
#[repr(transparent)]
pub struct ClassInstExtra<T: Obj, I: Sized>(Class<T>, PhantomData<I>);
pub const NS_OBJECT_SIZE: usize = 8;

impl<T: Obj, I: Sized> std::ops::Deref for ClassInstExtra<T, I> {
type Target = Class<T>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

// class_getInstanceSize([NSObject class]);
pub const NS_OBJECT_SIZE: usize = std::mem::size_of::<usize>();

#[macro_export]
macro_rules! init_with_default {
($NewType:ty, $InnerType:ty) => {{
trait A {
fn init_fn(&self) -> Option<extern "C" fn()>;
}

struct B<T: ?Sized>(core::marker::PhantomData<T>);

impl<T: ?Sized> core::ops::Deref for B<T> {
type Target = ();
fn deref(&self) -> &Self::Target {
&()
}
}

impl<T: ?Sized> A for B<T>
where
T: Default,
{
fn init_fn(&self) -> Option<extern "C" fn()> {
extern "C" fn impl_init<T: Default>(
s: &mut $NewType,
_sel: Option<$crate::objc::Sel>,
) -> $crate::arc::R<$NewType> {
unsafe {
let ptr: *mut u8 = std::mem::transmute(s);
let d_ptr: *mut std::mem::ManuallyDrop<T> =
ptr.add($crate::objc::NS_OBJECT_SIZE) as _;
*d_ptr = std::mem::ManuallyDrop::new(T::default());

std::mem::transmute(ptr)
}
}

let ptr = unsafe { std::mem::transmute(impl_init::<T> as *const u8) };
Some(ptr)
}
}

impl A for () {
fn init_fn(&self) -> Option<extern "C" fn()> {
None
}
}

B::<$InnerType>(core::marker::PhantomData).init_fn()
}};
}

impl<T: Obj, I: Sized> ClassInstExtra<T, I> {
#[inline]
Expand All @@ -54,6 +114,12 @@ impl<T: Obj, I: Sized> ClassInstExtra<T, I> {
}
}

impl<T: Obj, I: Sized + Default> ClassInstExtra<T, I> {
pub fn new(&self) -> arc::R<T> {
unsafe { self.alloc_init(Default::default()).unwrap_unchecked() }
}
}

impl<T: Obj> Class<T> {
#[inline]
pub fn as_type_ref(&self) -> &Type {
Expand Down Expand Up @@ -264,6 +330,13 @@ extern "C-unwind" {
types: *const u8,
) -> bool;

pub fn class_replaceMethod(
cls: &Class<Id>,
name: &Sel,
imp: extern "C" fn(),
types: *const u8,
) -> Option<extern "C" fn()>;

pub fn objc_allocateClassPair(
super_cls: &Class<Id>,
name: *const u8,
Expand Down Expand Up @@ -403,6 +476,14 @@ macro_rules! define_obj_type {
$(<Self as $TraitImpl>::cls_add_methods(cls);)*
$(<Self as $TraitImpl>::cls_add_protocol(cls);)*

if let Some(init_fn_ptr) = $crate::init_with_default!($NewType, $InnerType) {
unsafe {
let sel = $crate::objc::sel_reg_name(c"init".as_ptr() as _);
let imp: extern "C" fn() = init_fn_ptr;
$crate::objc::class_addMethod(cls, sel, imp, std::ptr::null());
}
}

if std::mem::needs_drop::<$InnerType>() {
extern "C" fn impl_dealloc(s: &mut $NewType, _sel: Option<$crate::objc::Sel>) {
let ptr = s.inner_mut() as *mut _;
Expand Down Expand Up @@ -476,7 +557,7 @@ macro_rules! define_obj_type {

#[allow(dead_code)]
pub fn new() -> $crate::arc::R<Self> {
unsafe { Self::cls().alloc_init(()).unwrap_unchecked() }
unsafe { Self::cls().new() }
}
}
};
Expand Down
29 changes: 27 additions & 2 deletions cidre/src/ui/application.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{arc, define_obj_type, objc, ui};
use crate::{arc, define_obj_type, ns, objc, ui};

#[objc::protocol(UIApplication)]
pub trait AppDelegate {
Expand All @@ -22,14 +22,39 @@ pub trait AppDelegate {
#[objc::optional]
#[objc::msg_send(setWindow:)]
fn set_window(&mut self, val: Option<&ui::Window>);

#[objc::optional]
#[objc::msg_send(applicationDidBecomeActive:)]
fn app_did_become_active(&mut self, app: &App);
}

define_obj_type!(
pub App(ui::Responder),
UI_APPLICATION
);

impl App {}
define_obj_type!(
pub AnyAppDelegate(ns::Id)
);

impl AppDelegate for AnyAppDelegate {}

impl App {
#[objc::msg_send(delegate)]
pub fn delegate(&self) -> Option<&AnyAppDelegate>;

#[objc::msg_send(delegate)]
pub fn delegate_mut(&self) -> Option<&mut AnyAppDelegate>;

#[objc::msg_send(setDelegate:)]
pub fn set_delegate(&mut self, val: Option<&AnyAppDelegate>);

#[objc::msg_send(sharedApplication)]
pub fn shared() -> &'static Self;

#[objc::msg_send(sharedApplication)]
pub fn shared_mut() -> &'static mut Self;
}

extern "C" {
static UI_APPLICATION: &'static objc::Class<App>;
Expand Down

0 comments on commit 077a976

Please # to comment.