1 | // Take a look at the license at the top of the repository in the LICENSE file. |
2 | |
3 | use std::fmt; |
4 | |
5 | use glib::translate::*; |
6 | |
7 | pub trait IsMiniObject: |
8 | AsRef<Self::RefType> + FromGlibPtrFull<*mut Self::FfiType> + Send + Sync + 'static |
9 | { |
10 | type RefType; |
11 | type FfiType; |
12 | } |
13 | |
14 | #[macro_export ] |
15 | macro_rules! mini_object_wrapper ( |
16 | ($name:ident, $ref_name:ident, $ffi_name:path) => { |
17 | #[repr(transparent)] |
18 | pub struct $name { |
19 | obj: std::ptr::NonNull<$ffi_name>, |
20 | } |
21 | |
22 | #[repr(transparent)] |
23 | pub struct $ref_name($ffi_name); |
24 | |
25 | impl $crate::miniobject::IsMiniObject for $name { |
26 | type RefType = $ref_name; |
27 | type FfiType = $ffi_name; |
28 | } |
29 | |
30 | impl $name { |
31 | #[inline] |
32 | pub unsafe fn from_glib_none(ptr: *const $ffi_name) -> Self { |
33 | skip_assert_initialized!(); |
34 | debug_assert!(!ptr.is_null()); |
35 | |
36 | $crate::ffi::gst_mini_object_ref(ptr as *mut $crate::ffi::GstMiniObject); |
37 | |
38 | $name { |
39 | obj: std::ptr::NonNull::new_unchecked(ptr as *mut $ffi_name), |
40 | } |
41 | } |
42 | |
43 | #[inline] |
44 | pub unsafe fn from_glib_full(ptr: *const $ffi_name) -> Self { |
45 | skip_assert_initialized!(); |
46 | debug_assert!(!ptr.is_null()); |
47 | |
48 | $name { |
49 | obj: std::ptr::NonNull::new_unchecked(ptr as *mut $ffi_name), |
50 | } |
51 | } |
52 | |
53 | #[inline] |
54 | pub unsafe fn from_glib_borrow(ptr: *const $ffi_name) -> $crate::glib::translate::Borrowed<Self> { |
55 | skip_assert_initialized!(); |
56 | debug_assert!(!ptr.is_null()); |
57 | |
58 | $crate::glib::translate::Borrowed::new($name { |
59 | obj: std::ptr::NonNull::new_unchecked(ptr as *mut $ffi_name), |
60 | }) |
61 | } |
62 | |
63 | #[inline] |
64 | pub unsafe fn replace_ptr(&mut self, ptr: *mut $ffi_name) { |
65 | debug_assert!(!ptr.is_null()); |
66 | self.obj = std::ptr::NonNull::new_unchecked(ptr); |
67 | } |
68 | |
69 | #[inline] |
70 | #[doc(alias = "gst_mini_object_make_writable" )] |
71 | pub fn make_mut(&mut self) -> &mut $ref_name { |
72 | unsafe { |
73 | if self.is_writable() { |
74 | return &mut *(self.obj.as_mut() as *mut $ffi_name as *mut $ref_name); |
75 | } |
76 | |
77 | let ptr = $crate::ffi::gst_mini_object_make_writable( |
78 | self.as_mut_ptr() as *mut $crate::ffi::GstMiniObject |
79 | ); |
80 | self.replace_ptr(ptr as *mut $ffi_name); |
81 | debug_assert!(self.is_writable()); |
82 | |
83 | &mut *(self.obj.as_mut() as *mut $ffi_name as *mut $ref_name) |
84 | } |
85 | } |
86 | |
87 | #[inline] |
88 | pub fn get_mut(&mut self) -> Option<&mut $ref_name> { |
89 | if self.is_writable() { |
90 | Some(unsafe { &mut *(self.obj.as_mut() as *mut $ffi_name as *mut $ref_name) }) |
91 | } else { |
92 | None |
93 | } |
94 | } |
95 | |
96 | #[doc(alias = "gst_mini_object_is_writable" )] |
97 | #[inline] |
98 | pub fn is_writable(&self) -> bool { |
99 | unsafe { |
100 | $crate::glib::translate::from_glib($crate::ffi::gst_mini_object_is_writable( |
101 | self.as_ptr() as *const $crate::ffi::GstMiniObject |
102 | )) |
103 | } |
104 | } |
105 | |
106 | #[must_use] |
107 | #[inline] |
108 | pub fn upcast(self) -> $crate::miniobject::MiniObject { |
109 | use $crate::glib::translate::IntoGlibPtr; |
110 | |
111 | unsafe { |
112 | from_glib_full(self.into_glib_ptr() as *mut $crate::ffi::GstMiniObject) |
113 | } |
114 | } |
115 | } |
116 | |
117 | impl $crate::glib::translate::IntoGlibPtr<*mut $ffi_name> for $name { |
118 | #[inline] |
119 | unsafe fn into_glib_ptr(self) -> *mut $ffi_name { |
120 | let s = std::mem::ManuallyDrop::new(self); |
121 | s.as_mut_ptr() |
122 | } |
123 | } |
124 | |
125 | impl Clone for $name { |
126 | #[inline] |
127 | fn clone(&self) -> Self { |
128 | unsafe { $name::from_glib_none(self.as_ptr()) } |
129 | } |
130 | } |
131 | |
132 | impl Drop for $name { |
133 | #[inline] |
134 | fn drop(&mut self) { |
135 | unsafe { |
136 | $crate::ffi::gst_mini_object_unref(self.as_mut_ptr() as *mut $crate::ffi::GstMiniObject); |
137 | } |
138 | } |
139 | } |
140 | |
141 | impl std::ops::Deref for $name { |
142 | type Target = $ref_name; |
143 | |
144 | #[inline] |
145 | fn deref(&self) -> &Self::Target { |
146 | unsafe { &*(self.obj.as_ref() as *const $ffi_name as *const $ref_name) } |
147 | } |
148 | } |
149 | |
150 | impl AsRef<$ref_name> for $name { |
151 | #[inline] |
152 | fn as_ref(&self) -> &$ref_name { |
153 | &*self |
154 | } |
155 | } |
156 | |
157 | impl std::borrow::Borrow<$ref_name> for $name { |
158 | #[inline] |
159 | fn borrow(&self) -> &$ref_name { |
160 | &*self |
161 | } |
162 | } |
163 | |
164 | impl<'a> $crate::glib::translate::ToGlibPtr<'a, *const $ffi_name> for $name { |
165 | type Storage = std::marker::PhantomData<&'a Self>; |
166 | |
167 | #[inline] |
168 | fn to_glib_none(&'a self) -> $crate::glib::translate::Stash<'a, *const $ffi_name, Self> { |
169 | $crate::glib::translate::Stash(self.as_ptr(), std::marker::PhantomData) |
170 | } |
171 | |
172 | #[inline] |
173 | fn to_glib_full(&self) -> *const $ffi_name { |
174 | unsafe { |
175 | $crate::ffi::gst_mini_object_ref(self.as_mut_ptr() as *mut $crate::ffi::GstMiniObject); |
176 | self.as_ptr() |
177 | } |
178 | } |
179 | } |
180 | |
181 | impl<'a> $crate::glib::translate::ToGlibPtr<'a, *mut $ffi_name> for $name { |
182 | type Storage = std::marker::PhantomData<&'a Self>; |
183 | |
184 | #[inline] |
185 | fn to_glib_none(&'a self) -> $crate::glib::translate::Stash<'a, *mut $ffi_name, Self> { |
186 | $crate::glib::translate::Stash(self.as_mut_ptr(), std::marker::PhantomData) |
187 | } |
188 | |
189 | #[inline] |
190 | fn to_glib_full(&self) -> *mut $ffi_name { |
191 | unsafe { |
192 | $crate::ffi::gst_mini_object_ref(self.as_mut_ptr() as *mut $crate::ffi::GstMiniObject); |
193 | self.as_mut_ptr() |
194 | } |
195 | } |
196 | } |
197 | |
198 | impl<'a> $crate::glib::translate::ToGlibPtrMut<'a, *mut $ffi_name> for $name { |
199 | type Storage = std::marker::PhantomData<&'a mut Self>; |
200 | |
201 | #[inline] |
202 | fn to_glib_none_mut(&'a mut self) -> $crate::glib::translate::StashMut<*mut $ffi_name, Self> { |
203 | self.make_mut(); |
204 | $crate::glib::translate::StashMut(self.as_mut_ptr(), std::marker::PhantomData) |
205 | } |
206 | } |
207 | |
208 | impl<'a> $crate::glib::translate::ToGlibContainerFromSlice<'a, *mut *mut $ffi_name> for $name { |
209 | #[allow(clippy::type_complexity)] |
210 | type Storage = ( |
211 | std::marker::PhantomData<&'a [$name]>, |
212 | Option<Vec<*mut $ffi_name>>, |
213 | ); |
214 | |
215 | fn to_glib_none_from_slice(t: &'a [$name]) -> (*mut *mut $ffi_name, Self::Storage) { |
216 | skip_assert_initialized!(); |
217 | let mut v_ptr = Vec::with_capacity(t.len() + 1); |
218 | unsafe { |
219 | let ptr = v_ptr.as_mut_ptr(); |
220 | std::ptr::copy_nonoverlapping(t.as_ptr() as *mut *mut $ffi_name, ptr, t.len()); |
221 | std::ptr::write(ptr.add(t.len()), std::ptr::null_mut()); |
222 | v_ptr.set_len(t.len() + 1); |
223 | } |
224 | |
225 | (v_ptr.as_ptr() as *mut *mut $ffi_name, (std::marker::PhantomData, Some(v_ptr))) |
226 | } |
227 | |
228 | fn to_glib_container_from_slice(t: &'a [$name]) -> (*mut *mut $ffi_name, Self::Storage) { |
229 | skip_assert_initialized!(); |
230 | |
231 | let v_ptr = unsafe { |
232 | let v_ptr = $crate::glib::ffi::g_malloc(std::mem::size_of::<*mut $ffi_name>() * t.len() + 1) |
233 | as *mut *mut $ffi_name; |
234 | |
235 | std::ptr::copy_nonoverlapping(t.as_ptr() as *mut *mut $ffi_name, v_ptr, t.len()); |
236 | std::ptr::write(v_ptr.add(t.len()), std::ptr::null_mut()); |
237 | |
238 | v_ptr |
239 | }; |
240 | |
241 | (v_ptr, (std::marker::PhantomData, None)) |
242 | } |
243 | |
244 | fn to_glib_full_from_slice(t: &[$name]) -> *mut *mut $ffi_name { |
245 | skip_assert_initialized!(); |
246 | unsafe { |
247 | let v_ptr = $crate::glib::ffi::g_malloc(std::mem::size_of::<*mut $ffi_name>() * t.len() + 1) |
248 | as *mut *mut $ffi_name; |
249 | |
250 | for (i, s) in t.iter().enumerate() { |
251 | std::ptr::write(v_ptr.add(i), $crate::glib::translate::ToGlibPtr::to_glib_full(s)); |
252 | } |
253 | std::ptr::write(v_ptr.add(t.len()), std::ptr::null_mut()); |
254 | |
255 | v_ptr |
256 | } |
257 | } |
258 | } |
259 | |
260 | impl<'a> $crate::glib::translate::ToGlibContainerFromSlice<'a, *const *mut $ffi_name> |
261 | for $name |
262 | { |
263 | #[allow(clippy::type_complexity)] |
264 | type Storage = ( |
265 | std::marker::PhantomData<&'a [$name]>, |
266 | Option<Vec<*mut $ffi_name>>, |
267 | ); |
268 | |
269 | fn to_glib_none_from_slice(t: &'a [$name]) -> (*const *mut $ffi_name, Self::Storage) { |
270 | skip_assert_initialized!(); |
271 | let (ptr, stash) = |
272 | $crate::glib::translate::ToGlibContainerFromSlice::<'a, *mut *mut $ffi_name>::to_glib_none_from_slice(t); |
273 | (ptr as *const *mut $ffi_name, stash) |
274 | } |
275 | |
276 | fn to_glib_container_from_slice(_: &'a [$name]) -> (*const *mut $ffi_name, Self::Storage) { |
277 | skip_assert_initialized!(); |
278 | // Can't have consumer free a *const pointer |
279 | unimplemented!() |
280 | } |
281 | |
282 | fn to_glib_full_from_slice(_: &[$name]) -> *const *mut $ffi_name { |
283 | skip_assert_initialized!(); |
284 | // Can't have consumer free a *const pointer |
285 | unimplemented!() |
286 | } |
287 | } |
288 | |
289 | impl $crate::glib::translate::FromGlibPtrNone<*const $ffi_name> for $name { |
290 | #[inline] |
291 | unsafe fn from_glib_none(ptr: *const $ffi_name) -> Self { |
292 | Self::from_glib_none(ptr) |
293 | } |
294 | } |
295 | |
296 | impl $crate::glib::translate::FromGlibPtrNone<*mut $ffi_name> for $name { |
297 | #[inline] |
298 | unsafe fn from_glib_none(ptr: *mut $ffi_name) -> Self { |
299 | Self::from_glib_none(ptr) |
300 | } |
301 | } |
302 | |
303 | impl $crate::glib::translate::FromGlibPtrFull<*const $ffi_name> for $name { |
304 | #[inline] |
305 | unsafe fn from_glib_full(ptr: *const $ffi_name) -> Self { |
306 | Self::from_glib_full(ptr) |
307 | } |
308 | } |
309 | |
310 | impl $crate::glib::translate::FromGlibPtrFull<*mut $ffi_name> for $name { |
311 | #[inline] |
312 | unsafe fn from_glib_full(ptr: *mut $ffi_name) -> Self { |
313 | Self::from_glib_full(ptr) |
314 | } |
315 | } |
316 | |
317 | impl $crate::glib::translate::FromGlibPtrBorrow<*const $ffi_name> for $name { |
318 | #[inline] |
319 | unsafe fn from_glib_borrow(ptr: *const $ffi_name) -> $crate::glib::translate::Borrowed<Self> { |
320 | Self::from_glib_borrow(ptr) |
321 | } |
322 | } |
323 | |
324 | impl $crate::glib::translate::FromGlibPtrBorrow<*mut $ffi_name> for $name { |
325 | #[inline] |
326 | unsafe fn from_glib_borrow(ptr: *mut $ffi_name) -> $crate::glib::translate::Borrowed<Self> { |
327 | Self::from_glib_borrow(ptr) |
328 | } |
329 | } |
330 | |
331 | impl $crate::glib::translate::FromGlibContainerAsVec<*mut $ffi_name, *mut *mut $ffi_name> |
332 | for $name |
333 | { |
334 | unsafe fn from_glib_none_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> { |
335 | if num == 0 || ptr.is_null() { |
336 | return Vec::new(); |
337 | } |
338 | |
339 | let mut res = Vec::<Self>::with_capacity(num); |
340 | let res_ptr = res.as_mut_ptr(); |
341 | for i in 0..num { |
342 | ::std::ptr::write(res_ptr.add(i), $crate::glib::translate::from_glib_none(std::ptr::read(ptr.add(i)))); |
343 | } |
344 | res.set_len(num); |
345 | res |
346 | } |
347 | |
348 | unsafe fn from_glib_container_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> { |
349 | let res = $crate::glib::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, num); |
350 | $crate::glib::ffi::g_free(ptr as *mut _); |
351 | res |
352 | } |
353 | |
354 | unsafe fn from_glib_full_num_as_vec(ptr: *mut *mut $ffi_name, num: usize) -> Vec<Self> { |
355 | if num == 0 || ptr.is_null() { |
356 | return Vec::new(); |
357 | } |
358 | |
359 | let mut res = Vec::with_capacity(num); |
360 | let res_ptr = res.as_mut_ptr(); |
361 | ::std::ptr::copy_nonoverlapping(ptr as *mut Self, res_ptr, num); |
362 | res.set_len(num); |
363 | $crate::glib::ffi::g_free(ptr as *mut _); |
364 | res |
365 | } |
366 | } |
367 | |
368 | impl $crate::glib::translate::FromGlibPtrArrayContainerAsVec<*mut $ffi_name, *mut *mut $ffi_name> |
369 | for $name |
370 | { |
371 | unsafe fn from_glib_none_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> { |
372 | $crate::glib::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr, glib::translate::c_ptr_array_len(ptr)) |
373 | } |
374 | |
375 | unsafe fn from_glib_container_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> { |
376 | $crate::glib::translate::FromGlibContainerAsVec::from_glib_container_num_as_vec(ptr, glib::translate::c_ptr_array_len(ptr)) |
377 | } |
378 | |
379 | unsafe fn from_glib_full_as_vec(ptr: *mut *mut $ffi_name) -> Vec<Self> { |
380 | $crate::glib::translate::FromGlibContainerAsVec::from_glib_full_num_as_vec(ptr, glib::translate::c_ptr_array_len(ptr)) |
381 | } |
382 | } |
383 | |
384 | impl $crate::glib::translate::FromGlibContainerAsVec<*mut $ffi_name, *const *mut $ffi_name> |
385 | for $name |
386 | { |
387 | unsafe fn from_glib_none_num_as_vec(ptr: *const *mut $ffi_name, num: usize) -> Vec<Self> { |
388 | $crate::glib::translate::FromGlibContainerAsVec::from_glib_none_num_as_vec(ptr as *mut *mut _, num) |
389 | } |
390 | |
391 | unsafe fn from_glib_container_num_as_vec(_: *const *mut $ffi_name, _: usize) -> Vec<Self> { |
392 | // Can't free a *const |
393 | unimplemented!() |
394 | } |
395 | |
396 | unsafe fn from_glib_full_num_as_vec(_: *const *mut $ffi_name, _: usize) -> Vec<Self> { |
397 | // Can't free a *const |
398 | unimplemented!() |
399 | } |
400 | } |
401 | |
402 | impl $crate::glib::translate::FromGlibPtrArrayContainerAsVec<*mut $ffi_name, *const *mut $ffi_name> for $name |
403 | { |
404 | unsafe fn from_glib_none_as_vec(ptr: *const *mut $ffi_name) -> Vec<Self> { |
405 | $crate::glib::translate::FromGlibPtrArrayContainerAsVec::from_glib_none_as_vec(ptr as *mut *mut _) |
406 | } |
407 | |
408 | unsafe fn from_glib_container_as_vec(_: *const *mut $ffi_name) -> Vec<Self> { |
409 | // Can't free a *const |
410 | unimplemented!() |
411 | } |
412 | |
413 | unsafe fn from_glib_full_as_vec(_: *const *mut $ffi_name) -> Vec<Self> { |
414 | // Can't free a *const |
415 | unimplemented!() |
416 | } |
417 | } |
418 | |
419 | impl $crate::glib::translate::GlibPtrDefault for $name { |
420 | type GlibType = *mut $ffi_name; |
421 | } |
422 | |
423 | unsafe impl $crate::glib::translate::TransparentPtrType for $name {} |
424 | |
425 | impl $ref_name { |
426 | #[inline] |
427 | pub fn as_ptr(&self) -> *const $ffi_name { |
428 | self as *const Self as *const $ffi_name |
429 | } |
430 | |
431 | #[inline] |
432 | pub fn as_mut_ptr(&self) -> *mut $ffi_name { |
433 | self as *const Self as *mut $ffi_name |
434 | } |
435 | |
436 | #[inline] |
437 | pub unsafe fn from_ptr<'a>(ptr: *const $ffi_name) -> &'a Self { |
438 | debug_assert!(!ptr.is_null()); |
439 | &*(ptr as *const Self) |
440 | } |
441 | |
442 | #[inline] |
443 | pub unsafe fn from_mut_ptr<'a>(ptr: *mut $ffi_name) -> &'a mut Self { |
444 | debug_assert!(!ptr.is_null()); |
445 | debug_assert_ne!( |
446 | $crate::ffi::gst_mini_object_is_writable(ptr as *mut $crate::ffi::GstMiniObject), |
447 | $crate::glib::ffi::GFALSE |
448 | ); |
449 | &mut *(ptr as *mut Self) |
450 | } |
451 | |
452 | #[doc(alias = "gst_mini_object_copy" )] |
453 | #[inline] |
454 | pub fn copy(&self) -> $name { |
455 | unsafe { |
456 | $name::from_glib_full($crate::ffi::gst_mini_object_copy( |
457 | self.as_ptr() as *const $crate::ffi::GstMiniObject |
458 | ) as *const $ffi_name) |
459 | } |
460 | } |
461 | |
462 | #[inline] |
463 | pub fn upcast_ref(&self) -> &$crate::miniobject::MiniObjectRef { |
464 | unsafe { |
465 | &*(self.as_ptr() as *const $crate::miniobject::MiniObjectRef) |
466 | } |
467 | } |
468 | |
469 | #[inline] |
470 | pub fn upcast_mut(&mut self) -> &mut $crate::miniobject::MiniObjectRef { |
471 | unsafe { |
472 | &mut *(self.as_mut_ptr() as *mut $crate::miniobject::MiniObjectRef) |
473 | } |
474 | } |
475 | |
476 | #[inline] |
477 | pub fn ptr_eq(this: &$ref_name, other: &$ref_name) -> bool { |
478 | skip_assert_initialized!(); |
479 | this.as_ptr() == other.as_ptr() |
480 | } |
481 | } |
482 | |
483 | impl $crate::glib::translate::GlibPtrDefault for $ref_name { |
484 | type GlibType = *mut $ffi_name; |
485 | } |
486 | |
487 | impl ToOwned for $ref_name { |
488 | type Owned = $name; |
489 | |
490 | #[inline] |
491 | fn to_owned(&self) -> $name { |
492 | self.copy() |
493 | } |
494 | } |
495 | |
496 | unsafe impl Sync for $ref_name {} |
497 | unsafe impl Send for $ref_name {} |
498 | unsafe impl Sync for $name {} |
499 | unsafe impl Send for $name {} |
500 | }; |
501 | ($name:ident, $ref_name:ident, $ffi_name:path, $get_type:expr) => { |
502 | $crate::mini_object_wrapper!($name, $ref_name, $ffi_name); |
503 | |
504 | impl $crate::glib::types::StaticType for $name { |
505 | #[inline] |
506 | fn static_type() -> $crate::glib::types::Type { |
507 | $ref_name::static_type() |
508 | } |
509 | } |
510 | |
511 | #[allow(clippy::redundant_closure_call)] |
512 | impl $crate::glib::types::StaticType for $ref_name { |
513 | #[inline] |
514 | fn static_type() -> $crate::glib::types::Type { |
515 | unsafe { $crate::glib::translate::from_glib($get_type()) } |
516 | } |
517 | } |
518 | |
519 | impl glib::value::ValueType for $name { |
520 | type Type = Self; |
521 | } |
522 | |
523 | impl glib::value::ValueTypeOptional for $name { } |
524 | |
525 | unsafe impl<'a> $crate::glib::value::FromValue<'a> for $name { |
526 | type Checker = $crate::glib::value::GenericValueTypeOrNoneChecker<Self>; |
527 | |
528 | #[inline] |
529 | unsafe fn from_value(value: &'a $crate::glib::Value) -> Self { |
530 | skip_assert_initialized!(); |
531 | $crate::glib::translate::from_glib_none( |
532 | $crate::glib::gobject_ffi::g_value_get_boxed($crate::glib::translate::ToGlibPtr::to_glib_none(value).0) as *mut $ffi_name |
533 | ) |
534 | } |
535 | } |
536 | |
537 | unsafe impl<'a> $crate::glib::value::FromValue<'a> for &'a $name { |
538 | type Checker = $crate::glib::value::GenericValueTypeOrNoneChecker<Self>; |
539 | |
540 | #[inline] |
541 | unsafe fn from_value(value: &'a $crate::glib::Value) -> Self { |
542 | skip_assert_initialized!(); |
543 | assert_eq!(std::mem::size_of::<$name>(), std::mem::size_of::<$crate::glib::ffi::gpointer>()); |
544 | let value = &*(value as *const $crate::glib::Value as *const $crate::glib::gobject_ffi::GValue); |
545 | let ptr = &value.data[0].v_pointer as *const $crate::glib::ffi::gpointer as *const *const $ffi_name; |
546 | debug_assert!(!(*ptr).is_null()); |
547 | &*(ptr as *const $name) |
548 | } |
549 | } |
550 | |
551 | impl $crate::glib::value::ToValue for $name { |
552 | #[inline] |
553 | fn to_value(&self) -> $crate::glib::Value { |
554 | let mut value = $crate::glib::Value::for_value_type::<Self>(); |
555 | unsafe { |
556 | $crate::glib::gobject_ffi::g_value_set_boxed( |
557 | $crate::glib::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0, |
558 | $crate::glib::translate::ToGlibPtr::<*const $ffi_name>::to_glib_none(self).0 as *mut _, |
559 | ) |
560 | } |
561 | value |
562 | } |
563 | |
564 | #[inline] |
565 | fn value_type(&self) -> $crate::glib::Type { |
566 | <Self as $crate::glib::StaticType>::static_type() |
567 | } |
568 | } |
569 | |
570 | impl $crate::glib::value::ToValueOptional for $name { |
571 | #[inline] |
572 | fn to_value_optional(s: Option<&Self>) -> $crate::glib::Value { |
573 | skip_assert_initialized!(); |
574 | let mut value = $crate::glib::Value::for_value_type::<Self>(); |
575 | unsafe { |
576 | $crate::glib::gobject_ffi::g_value_set_boxed( |
577 | $crate::glib::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0, |
578 | $crate::glib::translate::ToGlibPtr::<*const $ffi_name>::to_glib_none(&s).0 as *mut _, |
579 | ) |
580 | } |
581 | value |
582 | } |
583 | } |
584 | |
585 | impl From<$name> for $crate::glib::Value { |
586 | #[inline] |
587 | fn from(v: $name) -> $crate::glib::Value { |
588 | skip_assert_initialized!(); |
589 | let mut value = $crate::glib::Value::for_value_type::<$name>(); |
590 | unsafe { |
591 | $crate::glib::gobject_ffi::g_value_take_boxed( |
592 | $crate::glib::translate::ToGlibPtrMut::to_glib_none_mut(&mut value).0, |
593 | $crate::glib::translate::IntoGlibPtr::<*mut $ffi_name>::into_glib_ptr(v) as *mut _, |
594 | ) |
595 | } |
596 | value |
597 | } |
598 | } |
599 | |
600 | unsafe impl<'a> $crate::glib::value::FromValue<'a> for &'a $ref_name { |
601 | type Checker = $crate::glib::value::GenericValueTypeOrNoneChecker<Self>; |
602 | |
603 | #[inline] |
604 | unsafe fn from_value(value: &'a $crate::glib::Value) -> Self { |
605 | skip_assert_initialized!(); |
606 | &*($crate::glib::gobject_ffi::g_value_get_boxed($crate::glib::translate::ToGlibPtr::to_glib_none(value).0) as *const $ref_name) |
607 | } |
608 | } |
609 | |
610 | // Can't have SetValue/SetValueOptional impls as otherwise one could use it to get |
611 | // immutable references from a mutable reference without borrowing via the value |
612 | |
613 | impl $crate::glib::HasParamSpec for $name { |
614 | type ParamSpec = $crate::glib::ParamSpecBoxed; |
615 | type SetValue = Self; |
616 | type BuilderFn = fn(&str) -> $crate::glib::ParamSpecBoxedBuilder<Self>; |
617 | |
618 | fn param_spec_builder() -> Self::BuilderFn { |
619 | |name| Self::ParamSpec::builder(name) |
620 | } |
621 | } |
622 | }; |
623 | ); |
624 | |
625 | #[cfg (not(any(feature = "v1_20" , docsrs)))] |
626 | mini_object_wrapper!(MiniObject, MiniObjectRef, ffi::GstMiniObject); |
627 | |
628 | #[cfg (feature = "v1_20" )] |
629 | mini_object_wrapper!(MiniObject, MiniObjectRef, ffi::GstMiniObject, || { |
630 | ffi::gst_mini_object_get_type() |
631 | }); |
632 | |
633 | impl MiniObject { |
634 | #[inline ] |
635 | pub fn downcast<T: IsMiniObject + glib::StaticType>(self) -> Result<T, Self> { |
636 | if self.type_().is_a(T::static_type()) { |
637 | unsafe { Ok(from_glib_full(self.into_glib_ptr() as *mut T::FfiType)) } |
638 | } else { |
639 | Err(self) |
640 | } |
641 | } |
642 | } |
643 | |
644 | impl fmt::Debug for MiniObject { |
645 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
646 | self.as_ref().fmt(f) |
647 | } |
648 | } |
649 | |
650 | impl fmt::Debug for MiniObjectRef { |
651 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
652 | f&mut DebugStruct<'_, '_>.debug_struct("MiniObject" ) |
653 | .field("ptr" , &self.as_ptr()) |
654 | .field(name:"type" , &self.type_()) |
655 | .finish() |
656 | } |
657 | } |
658 | |
659 | impl MiniObjectRef { |
660 | #[inline ] |
661 | pub fn type_(&self) -> glib::Type { |
662 | unsafe { from_glib((*self.as_ptr()).type_) } |
663 | } |
664 | |
665 | #[inline ] |
666 | pub fn downcast_ref<T: IsMiniObject + glib::StaticType>(&self) -> Option<&T::RefType> { |
667 | if self.type_().is_a(T::static_type()) { |
668 | unsafe { Some(&*(self as *const Self as *const T::RefType)) } |
669 | } else { |
670 | None |
671 | } |
672 | } |
673 | |
674 | #[inline ] |
675 | pub fn downcast_mut<T: IsMiniObject + glib::StaticType>(&mut self) -> Option<&mut T::RefType> { |
676 | if self.type_().is_a(T::static_type()) { |
677 | unsafe { Some(&mut *(self as *mut Self as *mut T::RefType)) } |
678 | } else { |
679 | None |
680 | } |
681 | } |
682 | } |
683 | |