gstreamer/subclass/
bin.rs1use glib::{prelude::*, subclass::prelude::*, translate::*};
4
5use super::prelude::*;
6use crate::{Bin, Element, LoggableError, Message, ffi};
7
8pub trait BinImpl: ElementImpl + ObjectSubclass<Type: IsA<Bin>> {
9 fn add_element(&self, element: &Element) -> Result<(), LoggableError> {
17 self.parent_add_element(element)
18 }
19
20 fn remove_element(&self, element: &Element) -> Result<(), LoggableError> {
28 self.parent_remove_element(element)
29 }
30
31 fn do_latency(&self) -> Result<(), LoggableError> {
32 self.parent_do_latency()
33 }
34
35 fn handle_message(&self, message: Message) {
39 self.parent_handle_message(message)
40 }
41}
42
43pub trait BinImplExt: BinImpl {
44 fn parent_add_element(&self, element: &Element) -> Result<(), LoggableError> {
45 unsafe {
46 let data = Self::type_data();
47 let parent_class = data.as_ref().parent_class() as *mut ffi::GstBinClass;
48 let f = (*parent_class).add_element.ok_or_else(|| {
49 loggable_error!(
50 crate::CAT_RUST,
51 "Parent function `add_element` is not defined"
52 )
53 })?;
54 result_from_gboolean!(
55 f(
56 self.obj().unsafe_cast_ref::<crate::Bin>().to_glib_none().0,
57 element.to_glib_none().0
58 ),
59 crate::CAT_RUST,
60 "Failed to add the element using the parent function"
61 )
62 }
63 }
64
65 fn parent_remove_element(&self, element: &Element) -> Result<(), LoggableError> {
66 unsafe {
67 let data = Self::type_data();
68 let parent_class = data.as_ref().parent_class() as *mut ffi::GstBinClass;
69 let f = (*parent_class).remove_element.ok_or_else(|| {
70 loggable_error!(
71 crate::CAT_RUST,
72 "Parent function `remove_element` is not defined"
73 )
74 })?;
75 result_from_gboolean!(
76 f(
77 self.obj().unsafe_cast_ref::<crate::Bin>().to_glib_none().0,
78 element.to_glib_none().0
79 ),
80 crate::CAT_RUST,
81 "Failed to remove the element using the parent function"
82 )
83 }
84 }
85
86 fn parent_do_latency(&self) -> Result<(), LoggableError> {
87 unsafe {
88 let data = Self::type_data();
89 let parent_class = data.as_ref().parent_class() as *mut ffi::GstBinClass;
90 let f = (*parent_class).do_latency.ok_or_else(|| {
91 loggable_error!(
92 crate::CAT_RUST,
93 "Parent function `do_latency` is not defined"
94 )
95 })?;
96 result_from_gboolean!(
97 f(self.obj().unsafe_cast_ref::<crate::Bin>().to_glib_none().0,),
98 crate::CAT_RUST,
99 "Failed to update latency using the parent function"
100 )
101 }
102 }
103
104 fn parent_handle_message(&self, message: Message) {
105 unsafe {
106 let data = Self::type_data();
107 let parent_class = data.as_ref().parent_class() as *mut ffi::GstBinClass;
108 if let Some(ref f) = (*parent_class).handle_message {
109 f(
110 self.obj().unsafe_cast_ref::<crate::Bin>().to_glib_none().0,
111 message.into_glib_ptr(),
112 );
113 }
114 }
115 }
116}
117
118impl<T: BinImpl> BinImplExt for T {}
119
120unsafe impl<T: BinImpl> IsSubclassable<T> for Bin {
121 fn class_init(klass: &mut glib::Class<Self>) {
122 Self::parent_class_init::<T>(klass);
123 let klass = klass.as_mut();
124 klass.add_element = Some(bin_add_element::<T>);
125 klass.remove_element = Some(bin_remove_element::<T>);
126 klass.do_latency = Some(bin_do_latency::<T>);
127 klass.handle_message = Some(bin_handle_message::<T>);
128 }
129}
130
131unsafe extern "C" fn bin_add_element<T: BinImpl>(
132 ptr: *mut ffi::GstBin,
133 element: *mut ffi::GstElement,
134) -> glib::ffi::gboolean {
135 unsafe {
136 let instance = &*(ptr as *mut T::Instance);
137 let imp = instance.imp();
138
139 panic_to_error!(imp, false, {
140 match imp.add_element(&from_glib_none(element)) {
141 Ok(()) => true,
142 Err(err) => {
143 err.log_with_imp(imp);
144 false
145 }
146 }
147 })
148 .into_glib()
149 }
150}
151
152unsafe extern "C" fn bin_remove_element<T: BinImpl>(
153 ptr: *mut ffi::GstBin,
154 element: *mut ffi::GstElement,
155) -> glib::ffi::gboolean {
156 unsafe {
157 let instance = &*(ptr as *mut T::Instance);
158 let imp = instance.imp();
159
160 if glib::gobject_ffi::g_object_is_floating(element as *mut glib::gobject_ffi::GObject)
164 != glib::ffi::GFALSE
165 {
166 return glib::ffi::GFALSE;
167 }
168
169 panic_to_error!(imp, false, {
170 match imp.remove_element(&from_glib_none(element)) {
171 Ok(()) => true,
172 Err(err) => {
173 err.log_with_imp(imp);
174 false
175 }
176 }
177 })
178 .into_glib()
179 }
180}
181
182unsafe extern "C" fn bin_do_latency<T: BinImpl>(ptr: *mut ffi::GstBin) -> glib::ffi::gboolean {
183 unsafe {
184 let instance = &*(ptr as *mut T::Instance);
185 let imp = instance.imp();
186
187 panic_to_error!(imp, false, {
188 match imp.do_latency() {
189 Ok(()) => true,
190 Err(err) => {
191 err.log_with_imp(imp);
192 false
193 }
194 }
195 })
196 .into_glib()
197 }
198}
199
200unsafe extern "C" fn bin_handle_message<T: BinImpl>(
201 ptr: *mut ffi::GstBin,
202 message: *mut ffi::GstMessage,
203) {
204 unsafe {
205 let instance = &*(ptr as *mut T::Instance);
206 let imp = instance.imp();
207
208 panic_to_error!(imp, (), { imp.handle_message(from_glib_full(message)) });
209 }
210}