Created
April 30, 2014 08:15
-
-
Save fjolnir/347f9860683edfe749a7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![feature(macro_rules)] | |
extern crate libc; | |
extern crate sync; | |
use std::cast::transmute; | |
use std::c_str::CString; | |
use std::sync::atomics::{ AtomicUint, INIT_ATOMIC_UINT, SeqCst }; | |
type Sel = uint; | |
enum ObjcObject {} | |
type Class<'a> = &'a ObjcObject; | |
type Id<'a> = &'a ObjcObject; | |
type NSObjectClass<'a> = Class<'a>; | |
type NSObject<'a> = Id<'a>; | |
type NSMutableArrayClass<'a> = NSObjectClass<'a>; | |
type NSMutableArray<'a> = NSObject<'a>; | |
type NSStringClass<'a> = NSObjectClass<'a>; | |
type NSString<'a> = NSObject<'a>; | |
#[link(name = "Foundation", kind = "framework")] | |
extern "C" { | |
fn sel_registerName(sel: *libc::c_char) -> Sel; | |
fn objc_msgSend(object: Id, sel: Sel, ...) -> Id; | |
#[link_name="OBJC_CLASS_$_NSMutableArray"] | |
static NSMutableArrayKlass:ObjcObject; | |
// #[link_name="OBJC_CLASS_$_NSString"] | |
// static NSStringKlass:ObjcObject; | |
} | |
trait ObjcSelector { | |
fn as_selector(self) -> Sel; | |
} | |
impl ObjcSelector for Sel { | |
fn as_selector(self) -> Sel { self } | |
} | |
impl<'a> ObjcSelector for &'a str { | |
#[inline] | |
fn as_selector(self) -> Sel { | |
unsafe { | |
self.with_c_str(|cstr| sel_registerName(cstr) ) | |
} | |
} | |
} | |
#[inline] | |
fn cache_sel(container:&'static AtomicUint, name:&str) -> Sel | |
{ | |
let mut sel:Sel = container.load(SeqCst); | |
if sel == 0 { | |
container.store(name.as_selector(), SeqCst); | |
sel = container.load(SeqCst); | |
} | |
sel | |
} | |
trait NSObjectClassInterface { | |
unsafe fn alloc(self) -> Id; | |
unsafe fn new(self) -> Id; | |
} | |
impl <'a>NSObjectClassInterface for NSObjectClass<'a> { | |
unsafe fn alloc(self) -> Id { | |
static mut sel:AtomicUint = INIT_ATOMIC_UINT; | |
objc_msgSend(self, cache_sel(&sel, "alloc")) | |
} | |
unsafe fn new(self) -> Id { | |
static mut sel:AtomicUint = INIT_ATOMIC_UINT; | |
objc_msgSend(self, cache_sel(&sel, "new")) | |
} | |
} | |
trait NSObjectInterface { | |
unsafe fn init(self) -> Id; | |
unsafe fn description(self) -> NSString; | |
} | |
impl <'a>NSObjectInterface for NSObjectClass<'a> { | |
unsafe fn init(self) -> Id { | |
static mut sel:AtomicUint = INIT_ATOMIC_UINT; | |
objc_msgSend(self, cache_sel(&sel, "init")) | |
} | |
unsafe fn description(self) -> NSString { | |
static mut sel:AtomicUint = INIT_ATOMIC_UINT; | |
objc_msgSend(self, cache_sel(&sel, "description")) | |
} | |
} | |
trait NSStringInterface { | |
unsafe fn UTF8String(self) -> *u8; | |
} | |
impl <'a>NSStringInterface for NSStringClass<'a> { | |
unsafe fn UTF8String(self) -> *u8 { | |
static mut sel:AtomicUint = INIT_ATOMIC_UINT; | |
let imp: extern "C" fn(Id, Sel, ...) -> *u8 = std::cast::transmute(objc_msgSend); | |
imp(self, cache_sel(&sel, "UTF8String")) | |
} | |
} | |
fn main() { | |
let arr:NSMutableArrayClass = &NSMutableArrayKlass; | |
println!("{}", arr as *_ as uint); | |
unsafe { | |
let inst = arr.alloc().init(); | |
let inst2 = arr.new(); | |
println!("{}", inst as *_ as uint); | |
println!("{}", inst2 as *_ as uint); | |
let buf = arr.description().UTF8String(); | |
println!("{} '{}''", buf, CString::new(buf as *i8, false).as_str()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment