gstreamer/auto/
bus.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
4// DO NOT EDIT
5
6use crate::{ffi, ClockTime, Message, Object};
7use glib::{
8    object::ObjectType as _,
9    prelude::*,
10    signal::{connect_raw, SignalHandlerId},
11    translate::*,
12};
13use std::boxed::Box as Box_;
14
15glib::wrapper! {
16    /// The [`Bus`][crate::Bus] is an object responsible for delivering [`Message`][crate::Message] packets in
17    /// a first-in first-out way from the streaming threads (see [`Task`][crate::Task]) to the
18    /// application.
19    ///
20    /// Since the application typically only wants to deal with delivery of these
21    /// messages from one thread, the GstBus will marshall the messages between
22    /// different threads. This is important since the actual streaming of media
23    /// is done in another thread than the application.
24    ///
25    /// The GstBus provides support for [`glib::Source`][crate::glib::Source] based notifications. This makes it
26    /// possible to handle the delivery in the glib `GMainLoop`.
27    ///
28    /// The [`glib::Source`][crate::glib::Source] callback function `gst_bus_async_signal_func()` can be used to
29    /// convert all bus messages into signal emissions.
30    ///
31    /// A message is posted on the bus with the [`post()`][Self::post()] method. With the
32    /// [`peek()`][Self::peek()] and [`pop()`][Self::pop()] methods one can look at or retrieve a
33    /// previously posted message.
34    ///
35    /// The bus can be polled with the [`poll()`][Self::poll()] method. This methods blocks
36    /// up to the specified timeout value until one of the specified messages types
37    /// is posted on the bus. The application can then [`pop()`][Self::pop()] the messages
38    /// from the bus to handle them.
39    /// Alternatively the application can register an asynchronous bus function
40    /// using [`add_watch_full()`][Self::add_watch_full()] or [`add_watch()`][Self::add_watch()]. This function will
41    /// install a [`glib::Source`][crate::glib::Source] in the default glib main loop and will deliver messages
42    /// a short while after they have been posted. Note that the main loop should
43    /// be running for the asynchronous callbacks.
44    ///
45    /// It is also possible to get messages from the bus without any thread
46    /// marshalling with the [`set_sync_handler()`][Self::set_sync_handler()] method. This makes it
47    /// possible to react to a message in the same thread that posted the
48    /// message on the bus. This should only be used if the application is able
49    /// to deal with messages from different threads.
50    ///
51    /// Every [`Pipeline`][crate::Pipeline] has one bus.
52    ///
53    /// Note that a [`Pipeline`][crate::Pipeline] will set its bus into flushing state when changing
54    /// from READY to NULL state.
55    ///
56    /// ## Properties
57    ///
58    ///
59    /// #### `enable-async`
60    ///  Enables async message delivery support for bus watches,
61    /// [`Bus::pop()`][crate::Bus::pop()] and similar API. Without this only the
62    /// synchronous message handlers are called.
63    ///
64    /// This property is used to create the child element buses
65    /// in [`Bin`][crate::Bin].
66    ///
67    /// Writeable | Construct Only
68    /// <details><summary><h4>Object</h4></summary>
69    ///
70    ///
71    /// #### `name`
72    ///  Readable | Writeable | Construct
73    ///
74    ///
75    /// #### `parent`
76    ///  The parent of the object. Please note, that when changing the 'parent'
77    /// property, we don't emit [`notify`][struct@crate::glib::Object#notify] and [`deep-notify`][struct@crate::Object#deep-notify]
78    /// signals due to locking issues. In some cases one can use
79    /// [`element-added`][struct@crate::Bin#element-added] or [`element-removed`][struct@crate::Bin#element-removed] signals on the parent to
80    /// achieve a similar effect.
81    ///
82    /// Readable | Writeable
83    /// </details>
84    ///
85    /// ## Signals
86    ///
87    ///
88    /// #### `message`
89    ///  A message has been posted on the bus. This signal is emitted from a
90    /// [`glib::Source`][crate::glib::Source] added to the mainloop. this signal will only be emitted when
91    /// there is a `GMainLoop` running.
92    ///
93    /// Detailed
94    ///
95    ///
96    /// #### `sync-message`
97    ///  A message has been posted on the bus. This signal is emitted from the
98    /// thread that posted the message so one has to be careful with locking.
99    ///
100    /// This signal will not be emitted by default, you have to call
101    /// [`Bus::enable_sync_message_emission()`][crate::Bus::enable_sync_message_emission()] before.
102    ///
103    /// Detailed
104    /// <details><summary><h4>Object</h4></summary>
105    ///
106    ///
107    /// #### `deep-notify`
108    ///  The deep notify signal is used to be notified of property changes. It is
109    /// typically attached to the toplevel bin to receive notifications from all
110    /// the elements contained in that bin.
111    ///
112    /// Detailed
113    /// </details>
114    ///
115    /// # Implements
116    ///
117    /// [`GstObjectExt`][trait@crate::prelude::GstObjectExt], [`trait@glib::ObjectExt`]
118    #[doc(alias = "GstBus")]
119    pub struct Bus(Object<ffi::GstBus, ffi::GstBusClass>) @extends Object;
120
121    match fn {
122        type_ => || ffi::gst_bus_get_type(),
123    }
124}
125
126impl Bus {
127    /// Creates a new [`Bus`][crate::Bus] instance.
128    ///
129    /// # Returns
130    ///
131    /// a new [`Bus`][crate::Bus] instance
132    #[doc(alias = "gst_bus_new")]
133    pub fn new() -> Bus {
134        assert_initialized_main_thread!();
135        unsafe { from_glib_full(ffi::gst_bus_new()) }
136    }
137
138    /// Adds a bus signal watch to the default main context with the default priority
139    /// ( `G_PRIORITY_DEFAULT` ). It is also possible to use a non-default
140    /// main context set up using [`glib::MainContext::push_thread_default()`][crate::glib::MainContext::push_thread_default()] (before
141    /// one had to create a bus watch source and attach it to the desired main
142    /// context 'manually').
143    ///
144    /// After calling this statement, the bus will emit the "message" signal for each
145    /// message posted on the bus.
146    ///
147    /// This function may be called multiple times. To clean up, the caller is
148    /// responsible for calling [`remove_signal_watch()`][Self::remove_signal_watch()] as many times as this
149    /// function is called.
150    #[doc(alias = "gst_bus_add_signal_watch")]
151    pub fn add_signal_watch(&self) {
152        unsafe {
153            ffi::gst_bus_add_signal_watch(self.to_glib_none().0);
154        }
155    }
156
157    //#[doc(alias = "gst_bus_async_signal_func")]
158    //pub fn async_signal_func(&self, message: &Message, data: /*Unimplemented*/Option<Basic: Pointer>) -> bool {
159    //    unsafe { TODO: call ffi:gst_bus_async_signal_func() }
160    //}
161
162    /// Instructs GStreamer to stop emitting the "sync-message" signal for this bus.
163    /// See [`enable_sync_message_emission()`][Self::enable_sync_message_emission()] for more information.
164    ///
165    /// In the event that multiple pieces of code have called
166    /// [`enable_sync_message_emission()`][Self::enable_sync_message_emission()], the sync-message emissions will only
167    /// be stopped after all calls to [`enable_sync_message_emission()`][Self::enable_sync_message_emission()] were
168    /// "cancelled" by calling this function. In this way the semantics are exactly
169    /// the same as `gst_object_ref()` that which calls enable should also call
170    /// disable.
171    #[doc(alias = "gst_bus_disable_sync_message_emission")]
172    pub fn disable_sync_message_emission(&self) {
173        unsafe {
174            ffi::gst_bus_disable_sync_message_emission(self.to_glib_none().0);
175        }
176    }
177
178    /// Instructs GStreamer to emit the "sync-message" signal after running the bus's
179    /// sync handler. This function is here so that code can ensure that they can
180    /// synchronously receive messages without having to affect what the bin's sync
181    /// handler is.
182    ///
183    /// This function may be called multiple times. To clean up, the caller is
184    /// responsible for calling [`disable_sync_message_emission()`][Self::disable_sync_message_emission()] as many times
185    /// as this function is called.
186    ///
187    /// While this function looks similar to [`add_signal_watch()`][Self::add_signal_watch()], it is not
188    /// exactly the same -- this function enables *synchronous* emission of
189    /// signals when messages arrive; [`add_signal_watch()`][Self::add_signal_watch()] adds an idle callback
190    /// to pop messages off the bus *asynchronously*. The sync-message signal
191    /// comes from the thread of whatever object posted the message; the "message"
192    /// signal is marshalled to the main thread via the `GMainLoop`.
193    #[doc(alias = "gst_bus_enable_sync_message_emission")]
194    pub fn enable_sync_message_emission(&self) {
195        unsafe {
196            ffi::gst_bus_enable_sync_message_emission(self.to_glib_none().0);
197        }
198    }
199
200    //#[doc(alias = "gst_bus_get_pollfd")]
201    //#[doc(alias = "get_pollfd")]
202    //pub fn pollfd(&self, fd: /*Ignored*/glib::PollFD) {
203    //    unsafe { TODO: call ffi:gst_bus_get_pollfd() }
204    //}
205
206    /// Checks if there are pending messages on the bus that
207    /// should be handled.
208    ///
209    /// # Returns
210    ///
211    /// [`true`] if there are messages on the bus to be handled, [`false`]
212    /// otherwise.
213    #[doc(alias = "gst_bus_have_pending")]
214    pub fn have_pending(&self) -> bool {
215        unsafe { from_glib(ffi::gst_bus_have_pending(self.to_glib_none().0)) }
216    }
217
218    /// Peeks the message on the top of the bus' queue. The message will remain
219    /// on the bus' message queue.
220    ///
221    /// # Returns
222    ///
223    /// the [`Message`][crate::Message] that is on the
224    ///  bus, or [`None`] if the bus is empty.
225    #[doc(alias = "gst_bus_peek")]
226    pub fn peek(&self) -> Option<Message> {
227        unsafe { from_glib_full(ffi::gst_bus_peek(self.to_glib_none().0)) }
228    }
229
230    /// Gets a message from the bus.
231    ///
232    /// # Returns
233    ///
234    /// the [`Message`][crate::Message] that is on the
235    ///  bus, or [`None`] if the bus is empty.
236    #[doc(alias = "gst_bus_pop")]
237    pub fn pop(&self) -> Option<Message> {
238        unsafe { from_glib_full(ffi::gst_bus_pop(self.to_glib_none().0)) }
239    }
240
241    /// Posts a message on the given bus. Ownership of the message
242    /// is taken by the bus.
243    /// ## `message`
244    /// the [`Message`][crate::Message] to post
245    ///
246    /// # Returns
247    ///
248    /// [`true`] if the message could be posted, [`false`] if the bus is flushing.
249    #[doc(alias = "gst_bus_post")]
250    pub fn post(&self, message: Message) -> Result<(), glib::error::BoolError> {
251        unsafe {
252            glib::result_from_gboolean!(
253                ffi::gst_bus_post(self.to_glib_none().0, message.into_glib_ptr()),
254                "Failed to post message"
255            )
256        }
257    }
258
259    /// Removes a signal watch previously added with [`add_signal_watch()`][Self::add_signal_watch()].
260    #[doc(alias = "gst_bus_remove_signal_watch")]
261    pub fn remove_signal_watch(&self) {
262        unsafe {
263            ffi::gst_bus_remove_signal_watch(self.to_glib_none().0);
264        }
265    }
266
267    /// Removes an installed bus watch from `self`.
268    ///
269    /// # Returns
270    ///
271    /// [`true`] on success or [`false`] if `self` has no event source.
272    #[doc(alias = "gst_bus_remove_watch")]
273    #[allow(dead_code)]
274    pub(crate) fn remove_watch(&self) -> Result<(), glib::error::BoolError> {
275        unsafe {
276            glib::result_from_gboolean!(
277                ffi::gst_bus_remove_watch(self.to_glib_none().0),
278                "Bus has no event source"
279            )
280        }
281    }
282
283    /// If `flushing`, flushes out and unrefs any messages queued in the bus. Releases
284    /// references to the message origin objects. Will flush future messages until
285    /// [`set_flushing()`][Self::set_flushing()] sets `flushing` to [`false`].
286    /// ## `flushing`
287    /// whether or not to flush the bus
288    #[doc(alias = "gst_bus_set_flushing")]
289    pub fn set_flushing(&self, flushing: bool) {
290        unsafe {
291            ffi::gst_bus_set_flushing(self.to_glib_none().0, flushing.into_glib());
292        }
293    }
294
295    //#[doc(alias = "gst_bus_sync_signal_handler")]
296    //pub fn sync_signal_handler(&self, message: &Message, data: /*Unimplemented*/Option<Basic: Pointer>) -> BusSyncReply {
297    //    unsafe { TODO: call ffi:gst_bus_sync_signal_handler() }
298    //}
299
300    /// Gets a message from the bus, waiting up to the specified timeout.
301    ///
302    /// If `timeout` is 0, this function behaves like [`pop()`][Self::pop()]. If `timeout` is
303    /// `GST_CLOCK_TIME_NONE`, this function will block forever until a message was
304    /// posted on the bus.
305    /// ## `timeout`
306    /// a timeout
307    ///
308    /// # Returns
309    ///
310    /// the [`Message`][crate::Message] that is on the
311    ///  bus after the specified timeout or [`None`] if the bus is empty
312    ///  after the timeout expired.
313    #[doc(alias = "gst_bus_timed_pop")]
314    pub fn timed_pop(&self, timeout: impl Into<Option<ClockTime>>) -> Option<Message> {
315        unsafe {
316            from_glib_full(ffi::gst_bus_timed_pop(
317                self.to_glib_none().0,
318                timeout.into().into_glib(),
319            ))
320        }
321    }
322
323    /// A message has been posted on the bus. This signal is emitted from a
324    /// [`glib::Source`][crate::glib::Source] added to the mainloop. this signal will only be emitted when
325    /// there is a `GMainLoop` running.
326    /// ## `message`
327    /// the message that has been posted asynchronously
328    #[doc(alias = "message")]
329    pub fn connect_message<F: Fn(&Self, &Message) + Send + 'static>(
330        &self,
331        detail: Option<&str>,
332        f: F,
333    ) -> SignalHandlerId {
334        unsafe extern "C" fn message_trampoline<F: Fn(&Bus, &Message) + Send + 'static>(
335            this: *mut ffi::GstBus,
336            message: *mut ffi::GstMessage,
337            f: glib::ffi::gpointer,
338        ) {
339            let f: &F = &*(f as *const F);
340            f(&from_glib_borrow(this), &from_glib_borrow(message))
341        }
342        unsafe {
343            let f: Box_<F> = Box_::new(f);
344            let detailed_signal_name = detail.map(|name| format!("message::{name}\0"));
345            let signal_name: &[u8] = detailed_signal_name
346                .as_ref()
347                .map_or(c"message".to_bytes(), |n| n.as_bytes());
348            connect_raw(
349                self.as_ptr() as *mut _,
350                signal_name.as_ptr() as *const _,
351                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
352                    message_trampoline::<F> as *const (),
353                )),
354                Box_::into_raw(f),
355            )
356        }
357    }
358
359    /// A message has been posted on the bus. This signal is emitted from the
360    /// thread that posted the message so one has to be careful with locking.
361    ///
362    /// This signal will not be emitted by default, you have to call
363    /// [`enable_sync_message_emission()`][Self::enable_sync_message_emission()] before.
364    /// ## `message`
365    /// the message that has been posted synchronously
366    #[doc(alias = "sync-message")]
367    pub fn connect_sync_message<F: Fn(&Self, &Message) + Send + Sync + 'static>(
368        &self,
369        detail: Option<&str>,
370        f: F,
371    ) -> SignalHandlerId {
372        unsafe extern "C" fn sync_message_trampoline<
373            F: Fn(&Bus, &Message) + Send + Sync + 'static,
374        >(
375            this: *mut ffi::GstBus,
376            message: *mut ffi::GstMessage,
377            f: glib::ffi::gpointer,
378        ) {
379            let f: &F = &*(f as *const F);
380            f(&from_glib_borrow(this), &from_glib_borrow(message))
381        }
382        unsafe {
383            let f: Box_<F> = Box_::new(f);
384            let detailed_signal_name = detail.map(|name| format!("sync-message::{name}\0"));
385            let signal_name: &[u8] = detailed_signal_name
386                .as_ref()
387                .map_or(c"sync-message".to_bytes(), |n| n.as_bytes());
388            connect_raw(
389                self.as_ptr() as *mut _,
390                signal_name.as_ptr() as *const _,
391                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
392                    sync_message_trampoline::<F> as *const (),
393                )),
394                Box_::into_raw(f),
395            )
396        }
397    }
398}
399
400impl Default for Bus {
401    fn default() -> Self {
402        Self::new()
403    }
404}
405
406unsafe impl Send for Bus {}
407unsafe impl Sync for Bus {}