1macro_rules! ffi_callback {
2 ($fn_name:ident, $target_type:ty, $target_rust_type:ty) => {
3 extern "C" fn $fn_name(target: $target_type, _: *mut c_void) {
4 if let Ok(ptr) = INSTANCES.try_lock() {
5 if let Some(target) = ptr.get(&(target as usize)) {
6 target.$fn_name();
7 }
8 }
9 }
10 };
11 ($fn_name:ident, $target_type:ty, $target_rust_type:ty, $arg1_ty1:ty) => {
12 unsafe extern "C" fn $fn_name(target: $target_type, _: *mut c_void, arg1: $arg1_ty1) {
13 if let Ok(ptr) = INSTANCES.try_lock() {
14 if let Some(target) = ptr.get(&(target as usize)) {
15 target.$fn_name(arg1.into());
16 }
17 }
18 }
19 };
20 ($fn_name:ident, $target_type:ty, $target_rust_type:ty, $arg1_ty:ty, $arg2_ty:ty) => {
21 unsafe extern "C" fn $fn_name(
22 target: $target_type,
23 _: *mut c_void,
24 arg1: $arg1_ty,
25 arg2: $arg2_ty,
26 ) {
27 if let Ok(ptr) = INSTANCES.try_lock() {
28 if let Some(target) = ptr.get(&(target as usize)) {
29 target.$fn_name(arg1.into(), arg2.into());
30 }
31 }
32 }
33 };
34 ($fn_name:ident, $target_type:ty, $target_rust_type:ty, $arg1_ty:ty, $arg2_ty:ty, $arg3_ty:ty) => {
35 unsafe extern "C" fn $fn_name(
36 target: $target_type,
37 _: *mut c_void,
38 arg1: $arg1_ty,
39 arg2: $arg2_ty,
40 arg3: $arg3_ty,
41 ) {
42 if let Ok(ptr) = INSTANCES.try_lock() {
43 if let Some(target) = ptr.get(&(target as usize)) {
44 target.$fn_name(arg1.into(), arg2.into(), arg3.into());
45 }
46 }
47 }
48 };
49}
50
51macro_rules! ffi_callback_with_return_user_data {
52 ($fn_name:ident, $target_type:ty, $return_type:ty) => {
53 unsafe extern "C" fn $fn_name(_: $target_type, user_data: *mut c_void) -> $return_type {
54 let result: OtcBool = if let Ok(ptr) = INSTANCES.try_lock() {
55 if let Some(target) = ptr.get(&(user_data as usize)) {
56 target.$fn_name().into()
57 } else {
58 false.into()
59 }
60 } else {
61 false.into()
62 };
63 result.0
64 }
65 };
66 ($fn_name:ident, $target_type:ty, $arg1_type:ty, $return_type:ty) => {
67 unsafe extern "C" fn $fn_name(
68 _: $target_type,
69 user_data: *mut c_void,
70 arg1: $arg1_type,
71 ) -> $return_type {
72 let result: OtcBool = if let Ok(ptr) = INSTANCES.try_lock() {
73 if let Some(target) = ptr.get(&(user_data as usize)) {
74 target.$fn_name(arg1).into()
75 } else {
76 false.into()
77 }
78 } else {
79 false.into()
80 };
81 result.0
82 }
83 };
84}
85
86macro_rules! ffi_callback_with_return_singleton {
87 ($fn_name:ident, $target_type:ty, $return_type:ty) => {
88 unsafe extern "C" fn $fn_name(_: $target_type, _: *mut c_void) -> $return_type {
89 let result: OtcBool = if let Ok(singleton) = SINGLETON.try_lock() {
90 singleton.$fn_name().into()
91 } else {
92 false.into()
93 };
94 result.0
95 }
96 };
97 ($fn_name:ident, $target_type:ty, $arg1_type:ty, $return_type:ty) => {
98 unsafe extern "C" fn $fn_name(
99 _: $target_type,
100 user_data: *mut c_void,
101 arg1: $arg1_type,
102 ) -> $return_type {
103 let result: OtcBool = if let Ok(singleton) = SINGLETON.try_lock() {
104 singleton.$fn_name(arg1).into()
105 } else {
106 false.into()
107 };
108 result.0
109 }
110 };
111}
112
113macro_rules! callback {
114 ($fn_name:ident, $target:ty) => {
115 pub fn $fn_name(&self, target: $target) {
116 if let Some(ref callback) = self.$fn_name {
117 callback(target);
118 }
119 }
120 };
121 ($fn_name:ident, $target:ty, $ty1:ty) => {
122 pub fn $fn_name(&self, target: $target, arg1: $ty1) {
123 if let Some(ref callback) = self.$fn_name {
124 callback(target, arg1);
125 }
126 }
127 };
128 ($fn_name:ident, $target:ty, $ty1:ty, $ty2:ty) => {
129 pub fn $fn_name(&self, target: $target, arg1: $ty1, arg2: $ty2) {
130 if let Some(ref callback) = self.$fn_name {
131 callback(target, arg1, arg2);
132 }
133 }
134 };
135 ($fn_name:ident, $target:ty, $ty1:ty, $ty2:ty, $ty3:ty) => {
136 pub fn $fn_name(&self, target: $target, arg1: $ty1, arg2: $ty2, arg3: $ty3) {
137 if let Some(ref callback) = self.$fn_name {
138 callback(target, arg1, arg2, arg3);
139 }
140 }
141 };
142}
143
144macro_rules! callback_with_return {
145 ($fn_name:ident, $target:ty, $ret:ty) => {
146 pub fn $fn_name(&self, target: $target) -> $ret {
147 if let Some(ref callback) = self.$fn_name {
148 return callback(target);
149 }
150 Ok(())
151 }
152 };
153 ($fn_name:ident, $target:ty, $ty1:ty, $ret:ty) => {
154 pub fn $fn_name(&self, target: $target, arg1: $ty1) -> $ret {
155 if let Some(ref callback) = self.$fn_name {
156 return callback(target, arg1);
157 }
158 Ok(())
159 }
160 };
161 ($fn_name:ident, $target:ty, $ty1:ty, $ty2:ty, $ret:ty) => {
162 pub fn $fn_name(&self, target: $target, arg1: $ty1, arg2: $ty2) -> $ret {
163 if let Some(ref callback) = self.$fn_name {
164 return callback(target, arg1, arg2);
165 }
166 Ok(())
167 }
168 };
169 ($fn_name:ident, $target:ty, $ty1:ty, $ty2:ty, $ty3:ty, $ret:ty) => {
170 pub fn $fn_name(&self, target: $target, arg1: $ty1, arg2: $ty2, arg3: $ty3) -> $ret {
171 if let Some(ref callback) = self.$fn_name {
172 return callback(target, arg1, arg2, arg3);
173 }
174 Ok(())
175 }
176 };
177}
178
179macro_rules! callback_setter {
180 ($fn_name:ident, $target:ty) => {
181 pub fn $fn_name<F: Fn($target) + Send + Sync + 'static>(self, callback: F) -> Self {
182 Self {
183 $fn_name: Some(Box::new(callback)),
184 ..self
185 }
186 }
187 };
188 ($fn_name:ident, $target:ty, $ty1:ty) => {
189 pub fn $fn_name<F: Fn($target, $ty1) + Send + Sync + 'static>(self, callback: F) -> Self {
190 Self {
191 $fn_name: Some(Box::new(callback)),
192 ..self
193 }
194 }
195 };
196 ($fn_name:ident, $target:ty, $ty1:ty, $ty2:ty) => {
197 pub fn $fn_name<F: Fn($target, $ty1, $ty2) + 'static + Send + Sync + 'static>(
198 self,
199 callback: F,
200 ) -> Self {
201 Self {
202 $fn_name: Some(Box::new(callback)),
203 ..self
204 }
205 }
206 };
207 ($fn_name:ident, $target:ty, $ty1:ty, $ty2:ty, $ty3:ty) => {
208 pub fn $fn_name<F: Fn($target, $ty1, $ty2, $ty3) + Send + Sync + 'static>(
209 self,
210 callback: F,
211 ) -> Self {
212 Self {
213 $fn_name: Some(Box::new(callback)),
214 ..self
215 }
216 }
217 };
218 ($fn_name:ident, $target:ty, $ty1:ty, $ty2:ty, $ty3:ty, $t4:ty) => {
219 pub fn $fn_name<F: Fn($target, $ty1, $ty2, $ty3, $t4) + Send + Sync + 'static>(
220 self,
221 callback: F,
222 ) -> Self {
223 Self {
224 $fn_name: Some(Box::new(callback)),
225 ..self
226 }
227 }
228 };
229}
230
231macro_rules! callback_setter_with_return {
232 ($fn_name:ident, $target:ty, $ret:ty) => {
233 pub fn $fn_name<F: Fn($target) -> $ret + Send + Sync + 'static>(self, callback: F) -> Self {
234 Self {
235 $fn_name: Some(Box::new(callback)),
236 ..self
237 }
238 }
239 };
240 ($fn_name:ident, $target:ty, $ty1:ty, $ret:ty) => {
241 pub fn $fn_name<F: Fn($target, $ty1) -> $ret + Send + Sync + 'static>(
242 self,
243 callback: F,
244 ) -> Self {
245 Self {
246 $fn_name: Some(Box::new(callback)),
247 ..self
248 }
249 }
250 };
251 ($fn_name:ident, $target:ty, $ty1:ty, $ty2:ty, $ret:ty) => {
252 pub fn $fn_name<F: Fn($target, $ty1, $ty2) -> $ret + Send + Sync + 'static>(
253 self,
254 callback: F,
255 ) -> Self {
256 Self {
257 $fn_name: Some(Box::new(callback)),
258 ..self
259 }
260 }
261 };
262 ($fn_name:ident, $target:ty, $ty1:ty, $ty2:ty, $ty3:ty, $ret:ty) => {
263 pub fn $fn_name<F: Fn($target, $ty1, $ty2, $ty3) -> $ret + Send + Sync + 'static>(
264 self,
265 callback: F,
266 ) -> Self {
267 Self {
268 $fn_name: Some(Box::new(callback)),
269 ..self
270 }
271 }
272 };
273 ($fn_name:ident, $target:ty, $ty1:ty, $ty2:ty, $ty3:ty, $t4:ty, $ret:ty) => {
274 pub fn $fn_name<F: Fn($target, $ty1, $ty2, $ty3, $t4) -> $ret + Send + Sync + 'static>(
275 self,
276 callback: F,
277 ) -> Self {
278 Self {
279 $fn_name: Some(Box::new(callback)),
280 ..self
281 }
282 }
283 };
284}
285
286macro_rules! callback_call {
287 ($fn_name:ident) => {
288 fn $fn_name(&self) {
289 if let Ok(callbacks) = self.callbacks.try_lock() {
290 callbacks.$fn_name(self);
291 }
292 }
293 };
294 ($fn_name:ident, $ty1:ty) => {
295 fn $fn_name(&self, arg1: $ty1) {
296 if let Ok(callbacks) = self.callbacks.try_lock() {
297 callbacks.$fn_name(self, arg1.into());
298 }
299 }
300 };
301 ($fn_name:ident, $ty1:ty, $ty2:ty) => {
302 fn $fn_name(&self, arg1: $ty1, arg2: $ty2) {
303 if let Ok(callbacks) = self.callbacks.try_lock() {
304 callbacks.$fn_name(self, arg1.into(), arg2.into());
305 }
306 }
307 };
308 ($fn_name:ident, $ty1:ty, $ty2:ty, $ty3:ty) => {
309 fn $fn_name(&self, arg1: $ty1, arg2: $ty2, arg3: $ty3) {
310 if let Ok(callbacks) = self.callbacks.try_lock() {
311 callbacks.$fn_name(self, arg1.into(), arg2.into(), arg3.into());
312 }
313 }
314 };
315}
316
317macro_rules! callback_call_with_return {
318 ($fn_name:ident, $ret:ty) => {
319 fn $fn_name(&self) -> $ret {
320 self.callbacks.lock().unwrap().$fn_name(self)
321 }
322 };
323 ($fn_name:ident, $ty1:ty, $ret:ty) => {
324 fn $fn_name(&self, arg1: $ty1) -> $ret {
325 self.callbacks.lock().unwrap().$fn_name(self, arg1.into())
326 }
327 };
328 ($fn_name:ident, $ty1:ty, $ty2:ty, $ret:ty) => {
329 fn $fn_name(&self, arg1: $ty1, arg2: $ty2) -> $ret {
330 self.callbacks
331 .lock()
332 .unwrap()
333 .$fn_name(self, arg1.into(), arg2.into())
334 }
335 };
336 ($fn_name:ident, $ty1:ty, $ty2:ty, $ty3:ty, $ret:ty) => {
337 fn $fn_name(&self, arg1: $ty1, arg2: $ty2, arg3: $ty3) -> $ret {
338 self.callbacks
339 .lock()
340 .unwrap()
341 .$fn_name(self, arg1.into(), arg2.into(), arg3.into())
342 }
343 };
344}
345
346macro_rules! string_getter {
347 ($(#[$attr:meta])* => ($method:ident, $ffi:ident)) => {
348 pub fn $method(&self) -> String {
349 let property = unsafe { ffi::$ffi(self.ptr.load(Ordering::Relaxed) as *const _) };
350 let property: &CStr = unsafe { CStr::from_ptr(property) };
351 property.to_str().unwrap().to_owned()
352 }
353 };
354}