1 // Take a look at the license at the top of the repository in the LICENSE file.
2
3 use glib::prelude::*;
4 use glib::translate::*;
5
6 use super::prelude::*;
7 use glib::subclass::prelude::*;
8
9 use crate::Bin;
10 use crate::Element;
11 use crate::LoggableError;
12 use crate::Message;
13
14 pub trait BinImpl: BinImplExt + ElementImpl {
add_element(&self, bin: &Self::Type, element: &Element) -> Result<(), LoggableError>15 fn add_element(&self, bin: &Self::Type, element: &Element) -> Result<(), LoggableError> {
16 self.parent_add_element(bin, element)
17 }
18
remove_element(&self, bin: &Self::Type, element: &Element) -> Result<(), LoggableError>19 fn remove_element(&self, bin: &Self::Type, element: &Element) -> Result<(), LoggableError> {
20 self.parent_remove_element(bin, element)
21 }
22
handle_message(&self, bin: &Self::Type, message: Message)23 fn handle_message(&self, bin: &Self::Type, message: Message) {
24 self.parent_handle_message(bin, message)
25 }
26 }
27
28 pub trait BinImplExt: ObjectSubclass {
parent_add_element(&self, bin: &Self::Type, element: &Element) -> Result<(), LoggableError>29 fn parent_add_element(&self, bin: &Self::Type, element: &Element) -> Result<(), LoggableError>;
30
parent_remove_element( &self, bin: &Self::Type, element: &Element, ) -> Result<(), LoggableError>31 fn parent_remove_element(
32 &self,
33 bin: &Self::Type,
34 element: &Element,
35 ) -> Result<(), LoggableError>;
36
parent_handle_message(&self, bin: &Self::Type, message: Message)37 fn parent_handle_message(&self, bin: &Self::Type, message: Message);
38 }
39
40 impl<T: BinImpl> BinImplExt for T {
parent_add_element(&self, bin: &Self::Type, element: &Element) -> Result<(), LoggableError>41 fn parent_add_element(&self, bin: &Self::Type, element: &Element) -> Result<(), LoggableError> {
42 unsafe {
43 let data = Self::type_data();
44 let parent_class = data.as_ref().parent_class() as *mut ffi::GstBinClass;
45 let f = (*parent_class).add_element.ok_or_else(|| {
46 loggable_error!(
47 crate::CAT_RUST,
48 "Parent function `add_element` is not defined"
49 )
50 })?;
51 result_from_gboolean!(
52 f(
53 bin.unsafe_cast_ref::<crate::Bin>().to_glib_none().0,
54 element.to_glib_none().0
55 ),
56 crate::CAT_RUST,
57 "Failed to add the element using the parent function"
58 )
59 }
60 }
61
parent_remove_element( &self, bin: &Self::Type, element: &Element, ) -> Result<(), LoggableError>62 fn parent_remove_element(
63 &self,
64 bin: &Self::Type,
65 element: &Element,
66 ) -> Result<(), LoggableError> {
67 unsafe {
68 let data = Self::type_data();
69 let parent_class = data.as_ref().parent_class() as *mut ffi::GstBinClass;
70 let f = (*parent_class).remove_element.ok_or_else(|| {
71 loggable_error!(
72 crate::CAT_RUST,
73 "Parent function `remove_element` is not defined"
74 )
75 })?;
76 result_from_gboolean!(
77 f(
78 bin.unsafe_cast_ref::<crate::Bin>().to_glib_none().0,
79 element.to_glib_none().0
80 ),
81 crate::CAT_RUST,
82 "Failed to remove the element using the parent function"
83 )
84 }
85 }
86
parent_handle_message(&self, bin: &Self::Type, message: Message)87 fn parent_handle_message(&self, bin: &Self::Type, message: Message) {
88 unsafe {
89 let data = Self::type_data();
90 let parent_class = data.as_ref().parent_class() as *mut ffi::GstBinClass;
91 if let Some(ref f) = (*parent_class).handle_message {
92 f(
93 bin.unsafe_cast_ref::<crate::Bin>().to_glib_none().0,
94 message.into_ptr(),
95 );
96 }
97 }
98 }
99 }
100
101 unsafe impl<T: BinImpl> IsSubclassable<T> for Bin {
class_init(klass: &mut glib::Class<Self>)102 fn class_init(klass: &mut glib::Class<Self>) {
103 <crate::Element as IsSubclassable<T>>::class_init(klass);
104 let klass = klass.as_mut();
105 klass.add_element = Some(bin_add_element::<T>);
106 klass.remove_element = Some(bin_remove_element::<T>);
107 klass.handle_message = Some(bin_handle_message::<T>);
108 }
109
instance_init(instance: &mut glib::subclass::InitializingObject<T>)110 fn instance_init(instance: &mut glib::subclass::InitializingObject<T>) {
111 <crate::Element as IsSubclassable<T>>::instance_init(instance);
112 }
113 }
114
bin_add_element<T: BinImpl>( ptr: *mut ffi::GstBin, element: *mut ffi::GstElement, ) -> glib::ffi::gboolean115 unsafe extern "C" fn bin_add_element<T: BinImpl>(
116 ptr: *mut ffi::GstBin,
117 element: *mut ffi::GstElement,
118 ) -> glib::ffi::gboolean {
119 let instance = &*(ptr as *mut T::Instance);
120 let imp = instance.impl_();
121 let wrap: Borrowed<Bin> = from_glib_borrow(ptr);
122
123 panic_to_error!(&wrap, &imp.panicked(), false, {
124 match imp.add_element(wrap.unsafe_cast_ref(), &from_glib_none(element)) {
125 Ok(()) => true,
126 Err(err) => {
127 err.log_with_object(&*wrap);
128 false
129 }
130 }
131 })
132 .into_glib()
133 }
134
bin_remove_element<T: BinImpl>( ptr: *mut ffi::GstBin, element: *mut ffi::GstElement, ) -> glib::ffi::gboolean135 unsafe extern "C" fn bin_remove_element<T: BinImpl>(
136 ptr: *mut ffi::GstBin,
137 element: *mut ffi::GstElement,
138 ) -> glib::ffi::gboolean {
139 let instance = &*(ptr as *mut T::Instance);
140 let imp = instance.impl_();
141 let wrap: Borrowed<Bin> = from_glib_borrow(ptr);
142
143 // If we get a floating reference passed simply return FALSE here. It can't be
144 // stored inside this bin, and if we continued to use it we would take ownership
145 // of this floating reference.
146 if glib::gobject_ffi::g_object_is_floating(element as *mut glib::gobject_ffi::GObject)
147 != glib::ffi::GFALSE
148 {
149 return glib::ffi::GFALSE;
150 }
151
152 panic_to_error!(&wrap, &imp.panicked(), false, {
153 match imp.remove_element(wrap.unsafe_cast_ref(), &from_glib_none(element)) {
154 Ok(()) => true,
155 Err(err) => {
156 err.log_with_object(&*wrap);
157 false
158 }
159 }
160 })
161 .into_glib()
162 }
163
bin_handle_message<T: BinImpl>( ptr: *mut ffi::GstBin, message: *mut ffi::GstMessage, )164 unsafe extern "C" fn bin_handle_message<T: BinImpl>(
165 ptr: *mut ffi::GstBin,
166 message: *mut ffi::GstMessage,
167 ) {
168 let instance = &*(ptr as *mut T::Instance);
169 let imp = instance.impl_();
170 let wrap: Borrowed<Bin> = from_glib_borrow(ptr);
171
172 panic_to_error!(&wrap, &imp.panicked(), (), {
173 imp.handle_message(wrap.unsafe_cast_ref(), from_glib_full(message))
174 });
175 }
176