1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
extern crate objc;
extern crate objc_foundation;
use objc::runtime::Class;
#[cfg(feature = "objc_wrapper")]
use objc::runtime::{Object, Sel};
#[cfg(feature = "objc_wrapper")]
use std::sync::{Once, ONCE_INIT};
#[cfg(feature = "objc_wrapper")]
use objc::Message;
#[cfg(feature = "objc_wrapper")]
use objc::declare::ClassDecl;
#[cfg(feature = "objc_wrapper")]
use self::objc_foundation::INSObject;
#[cfg(not(feature = "objc_wrapper"))]
#[macro_export]
macro_rules! objc_subclass {
( $newclass:ident, $superclass:ident, $unique_newclass:ident ) => {
pub struct $newclass {}
impl $newclass {
pub fn class() -> &'static Class {
Class::get(stringify!($superclass)).unwrap()
}
}
}
}
#[cfg(feature = "objc_wrapper")]
#[macro_export]
macro_rules! objc_subclass {
( $newclass:ident, $superclass:ident, $unique_newclass:ident ) => {
pub enum $newclass {}
impl $newclass {}
unsafe impl Message for $newclass { }
static $unique_newclass: Once = ONCE_INIT;
impl $newclass {
fn str_name(this: &mut Object) -> String {
let ptr = this as *mut Object;
format!("{}({:x})", stringify!($newclass), ptr as u64)
}
}
impl INSObject for $newclass {
fn class() -> &'static Class {
$unique_newclass.call_once(|| {
let superclass = Class::get(stringify!($superclass)).unwrap();
let mut decl = ClassDecl::new(stringify!($newclass), superclass).unwrap();
decl.add_ivar::<u64>("_retain_count");
extern fn objc_retain(this: &mut Object, _cmd: Sel) -> *mut Object {
unsafe {
let superclass = Class::get(stringify!($superclass)).unwrap();
let obj: *mut Object = msg_send![super(this, superclass), retain];
obj
}
}
extern fn objc_release(this: &mut Object, _cmd: Sel) {
unsafe {
let superclass = Class::get(stringify!($superclass)).unwrap();
let _: () = msg_send![super(this, superclass), release];
}
}
extern fn objc_dealloc(this: &mut Object, _cmd: Sel) {
unsafe {
info!("{} dealloc", $newclass::str_name(this));
let superclass = Class::get(stringify!($superclass)).unwrap();
let _: () = msg_send![super(this, superclass), dealloc];
}
}
unsafe {
let f: extern fn(&mut Object, Sel) -> *mut Object = objc_retain;
decl.add_method(sel!(retain), f);
let f: extern fn(&mut Object, Sel) = objc_release;
decl.add_method(sel!(release), f);
let f: extern fn(&mut Object, Sel) = objc_dealloc;
decl.add_method(sel!(dealloc), f);
}
decl.register();
});
Class::get(stringify!($newclass)).unwrap()
}
}
};
}
objc_subclass!(RRScrubber, NSScrubber, RRSCRUBBER_CLASS);
objc_subclass!(RRTouchBar, NSTouchBar, RRTOUCHBAR_CLASS);
objc_subclass!(RRCustomTouchBarItem, NSCustomTouchBarItem, RRCUSTOMITEM_CLASS);
objc_subclass!(RRPopoverTouchBarItem, NSPopoverTouchBarItem, RRPOPOVERITEM_CLASS);
objc_subclass!(RRSliderTouchBarItem, NSSliderTouchBarItem, RRSLIDER_CLASS);