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