Skip to content

Commit

Permalink
continue on watchos support
Browse files Browse the repository at this point in the history
yury committed Jan 3, 2025

Unverified

This user has not yet uploaded their public signing key.
1 parent 35f32a7 commit 077a976
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 {
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;
85 changes: 83 additions & 2 deletions cidre/src/objc.rs
Original file line number Diff line number Diff line change
@@ -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]
@@ -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 {
@@ -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,
@@ -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 _;
@@ -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() }
}
}
};
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 {
@@ -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>;

0 comments on commit 077a976

Please sign in to comment.