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