gstreamer/subclass/
bin.rs
1use glib::{prelude::*, subclass::prelude::*, translate::*};
4
5use super::prelude::*;
6use crate::{ffi, Bin, Element, LoggableError, Message};
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 let instance = &*(ptr as *mut T::Instance);
136 let imp = instance.imp();
137
138 panic_to_error!(imp, false, {
139 match imp.add_element(&from_glib_none(element)) {
140 Ok(()) => true,
141 Err(err) => {
142 err.log_with_imp(imp);
143 false
144 }
145 }
146 })
147 .into_glib()
148}
149
150unsafe extern "C" fn bin_remove_element<T: BinImpl>(
151 ptr: *mut ffi::GstBin,
152 element: *mut ffi::GstElement,
153) -> glib::ffi::gboolean {
154 let instance = &*(ptr as *mut T::Instance);
155 let imp = instance.imp();
156
157 if glib::gobject_ffi::g_object_is_floating(element as *mut glib::gobject_ffi::GObject)
161 != glib::ffi::GFALSE
162 {
163 return glib::ffi::GFALSE;
164 }
165
166 panic_to_error!(imp, false, {
167 match imp.remove_element(&from_glib_none(element)) {
168 Ok(()) => true,
169 Err(err) => {
170 err.log_with_imp(imp);
171 false
172 }
173 }
174 })
175 .into_glib()
176}
177
178unsafe extern "C" fn bin_do_latency<T: BinImpl>(ptr: *mut ffi::GstBin) -> glib::ffi::gboolean {
179 let instance = &*(ptr as *mut T::Instance);
180 let imp = instance.imp();
181
182 panic_to_error!(imp, false, {
183 match imp.do_latency() {
184 Ok(()) => true,
185 Err(err) => {
186 err.log_with_imp(imp);
187 false
188 }
189 }
190 })
191 .into_glib()
192}
193
194unsafe extern "C" fn bin_handle_message<T: BinImpl>(
195 ptr: *mut ffi::GstBin,
196 message: *mut ffi::GstMessage,
197) {
198 let instance = &*(ptr as *mut T::Instance);
199 let imp = instance.imp();
200
201 panic_to_error!(imp, (), { imp.handle_message(from_glib_full(message)) });
202}