Rust 與 Objective-C 互操做

項目地址:github.com/gfx-rs/meta…git

Rust 表達 Objective-C new操做

pub enum MTLHeapDescriptor {}

foreign_obj_type! {
    type CType = MTLHeapDescriptor;
    pub struct HeapDescriptor;
    pub struct HeapDescriptorRef;
}

impl HeapDescriptor {
    pub fn new() -> Self {
        unsafe {
            let class = class!(MTLHeapDescriptor);
            msg_send![class, new]
        }
    }
}

impl HeapDescriptorRef {
    pub fn cpu_cache_mode(&self) -> MTLCPUCacheMode {
        unsafe { msg_send![self, cpuCacheMode] }
    }

    pub fn set_cpu_cache_mode(&self, mode: MTLCPUCacheMode) {
        unsafe { msg_send![self, setCpuCacheMode: mode] }
    }

    pub fn storage_mode(&self) -> MTLStorageMode {
        unsafe { msg_send![self, storageMode] }
    }

    pub fn set_storage_mode(&self, mode: MTLStorageMode) {
        unsafe { msg_send![self, setStorageMode: mode] }
    }

    pub fn size(&self) -> NSUInteger {
        unsafe { msg_send![self, size] }
    }

    pub fn set_size(&self, size: NSUInteger) {
        unsafe {
            msg_send![self, setSize: size];
        }
    }
}
複製代碼

Rust 表達 Objective-C 繼承關係

父類CAMetalDrawable繼承自NSObject,用Rust表達以下。github

pub enum MTLDrawable {}

foreign_obj_type! {
    type CType = MTLDrawable;
    pub struct Drawable;
    pub struct DrawableRef;
}


impl DrawableRef {
    pub fn present(&self) {
        unsafe {
            msg_send![self, present]
        }
    }
}
複製代碼

子類CAMetalDrawable用Rust表達以下。ide

pub enum CAMetalDrawable {}

foreign_obj_type! {
    type CType = CAMetalDrawable;
    pub struct CoreAnimationDrawable;
    pub struct CoreAnimationDrawableRef;
    type ParentType = DrawableRef;
}

impl CoreAnimationDrawableRef {
    pub fn texture(&self) -> &TextureRef {
        unsafe { msg_send![self, texture] }
    }
}
複製代碼

工具宏

macro_rules! foreign_obj_type {
    {type CType = $raw_ident:ident;
    pub struct $owned_ident:ident;
    pub struct $ref_ident:ident;
    type ParentType = $parent_ref:ident;
    } => {
        foreign_obj_type! {
            type CType = $raw_ident;
            pub struct $owned_ident;
            pub struct $ref_ident;
        }

        impl ::std::ops::Deref for $ref_ident {
            type Target = $parent_ref;

            fn deref(&self) -> &$parent_ref {
                unsafe { &*(self as *const $ref_ident as *const $parent_ref)  }
            }
        }
    };
    {type CType = $raw_ident:ident;
    pub struct $owned_ident:ident;
    pub struct $ref_ident:ident;
    } => {
        foreign_type! {
            type CType = $raw_ident;
            fn drop = ::obj_drop; fn clone = ::obj_clone; pub struct $owned_ident; pub struct $ref_ident; } unsafe impl ::objc::Message for $raw_ident { } unsafe impl ::objc::Message for $ref_ident { } impl ::std::fmt::Debug for $ref_ident { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                unsafe {
                    use ::objc_foundation::INSString;
                    // TODO: might leak, not 100% sure...
                    let string: &::objc_foundation::NSString = msg_send![self, debugDescription];
                    write!(f, "{}", string.as_str())
                }
            }
        }

        impl ::std::fmt::Debug for $owned_ident {
            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                ::std::ops::Deref::deref(self).fmt(f)
            }
        }
    };
}
複製代碼

輔助項目

上述操做依賴以下項目:工具

相關文章
相關標籤/搜索