Update functions returning bool to use Result<(), glib::BoolError>

See https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/issues/171
This commit is contained in:
François Laignel 2019-01-16 21:23:56 +01:00
parent ee87f286a0
commit 333d71f92b
20 changed files with 229 additions and 110 deletions

View file

@ -86,6 +86,11 @@ name = "Gst.Bin"
subclassing = true subclassing = true
status = "generate" status = "generate"
trait_name = "GstBinExt" trait_name = "GstBinExt"
[[object.signal]]
name = "do-latency"
# Use Result<(), glib::BoolError>
ignore = true
[[object.function]] [[object.function]]
name = "add" name = "add"
[object.function.return] [object.function.return]
@ -133,6 +138,11 @@ trait = false
# More convenient manual implementation # More convenient manual implementation
ignore = true ignore = true
[[object.function]]
name = "remove_watch"
[object.function.return]
bool_return_is_error = "Bus has no event source"
[[object.signal]] [[object.signal]]
name = "message" name = "message"
concurrency = "send" concurrency = "send"
@ -547,6 +557,11 @@ status = "generate"
[object.function.return] [object.function.return]
bool_return_is_error = "Failed to start" bool_return_is_error = "Failed to start"
[[object.function]]
name = "remove_filter"
[object.function.return]
bool_return_is_error = "Failed to remove the filter"
[[object]] [[object]]
name = "Gst.Device" name = "Gst.Device"
status = "generate" status = "generate"
@ -560,6 +575,11 @@ status = "generate"
[object.function.return] [object.function.return]
nullable = false nullable = false
[[object.function]]
name = "reconfigure_element"
[object.function.return]
bool_return_is_error = "Failed to reconfigure the element to use this device"
[[object]] [[object]]
name = "Gst.Object" name = "Gst.Object"
# For renaming the trait... # For renaming the trait...
@ -603,7 +623,12 @@ status = "generate"
[[object.function]] [[object.function]]
name = "link_maybe_ghosting" name = "link_maybe_ghosting"
[object.function.return] [object.function.return]
bool_return_is_error = "Failed to link pad, possibly ghosting" bool_return_is_error = "Failed to link pads, possibly ghosting"
[[object.function]]
name = "link_maybe_ghosting_full"
[object.function.return]
bool_return_is_error = "Failed to link pads, possibly ghosting"
[[object.function]] [[object.function]]
name = "unlink" name = "unlink"
@ -1187,6 +1212,11 @@ status = "generate"
# wrong mutable for context parameter # wrong mutable for context parameter
ignore = true ignore = true
[[object.function]]
name = "update_registry"
[object.function.return]
bool_return_is_error = "Failed to update the registry"
[[object.function]] [[object.function]]
name = "util_group_id_next" name = "util_group_id_next"
# newtype wrapper # newtype wrapper

View file

@ -130,7 +130,7 @@ fn example_main() {
// Remove the watch function from the bus. // Remove the watch function from the bus.
// Again: There can always only be one watch function. // Again: There can always only be one watch function.
// Thus we don't have to tell him which function to remove. // Thus we don't have to tell him which function to remove.
bus.remove_watch(); bus.remove_watch().unwrap();
} }
fn main() { fn main() {

View file

@ -146,7 +146,7 @@ fn create_ui(app: &gtk::Application) {
.set_state(gst::State::Null) .set_state(gst::State::Null)
.expect("Unable to set the pipeline to the `Null` state"); .expect("Unable to set the pipeline to the `Null` state");
bus.remove_watch(); bus.remove_watch().unwrap();
if let Some(timeout_id) = timeout_id.borrow_mut().take() { if let Some(timeout_id) = timeout_id.borrow_mut().take() {
glib::source_remove(timeout_id); glib::source_remove(timeout_id);
} }

View file

@ -249,7 +249,7 @@ fn create_ui(app: &gtk::Application) {
.set_state(gst::State::Null) .set_state(gst::State::Null)
.expect("Unable to set the pipeline to the `Null` state"); .expect("Unable to set the pipeline to the `Null` state");
bus.remove_watch(); bus.remove_watch().unwrap();
if let Some(timeout_id) = timeout_id.borrow_mut().take() { if let Some(timeout_id) = timeout_id.borrow_mut().take() {
glib::source_remove(timeout_id); glib::source_remove(timeout_id);
} }

View file

@ -68,7 +68,7 @@ fn example_main() {
// Here we remove the bus watch we added above. This avoids a memory leak, that might // Here we remove the bus watch we added above. This avoids a memory leak, that might
// otherwise happen because we moved a strong reference (clone of main_loop) into the // otherwise happen because we moved a strong reference (clone of main_loop) into the
// callback closure above. // callback closure above.
bus.remove_watch(); bus.remove_watch().unwrap();
} }
fn main() { fn main() {

View file

@ -124,7 +124,7 @@ fn example_main() {
.set_state(gst::State::Null) .set_state(gst::State::Null)
.expect("Unable to set the pipeline to the `Null` state"); .expect("Unable to set the pipeline to the `Null` state");
bus.remove_watch(); bus.remove_watch().unwrap();
glib::source_remove(timeout_id); glib::source_remove(timeout_id);
} }

View file

@ -99,8 +99,6 @@ pub trait GstBinExt: 'static {
#[cfg(any(feature = "v1_10", feature = "dox"))] #[cfg(any(feature = "v1_10", feature = "dox"))]
fn connect_deep_element_removed<F: Fn(&Self, &Bin, &Element) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId; fn connect_deep_element_removed<F: Fn(&Self, &Bin, &Element) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId;
fn connect_do_latency<F: Fn(&Self) -> bool + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId;
fn connect_element_added<F: Fn(&Self, &Element) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId; fn connect_element_added<F: Fn(&Self, &Element) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId;
fn connect_element_removed<F: Fn(&Self, &Element) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId; fn connect_element_removed<F: Fn(&Self, &Element) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId;
@ -251,14 +249,6 @@ impl<O: IsA<Bin>> GstBinExt for O {
} }
} }
fn connect_do_latency<F: Fn(&Self) -> bool + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
unsafe {
let f: Box_<Box_<Fn(&Self) -> bool + Send + Sync + 'static>> = Box_::new(Box_::new(f));
connect_raw(self.as_ptr() as *mut _, b"do-latency\0".as_ptr() as *const _,
transmute(do_latency_trampoline::<Self> as usize), Box_::into_raw(f) as *mut _)
}
}
fn connect_element_added<F: Fn(&Self, &Element) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId { fn connect_element_added<F: Fn(&Self, &Element) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
unsafe { unsafe {
let f: Box_<Box_<Fn(&Self, &Element) + Send + Sync + 'static>> = Box_::new(Box_::new(f)); let f: Box_<Box_<Fn(&Self, &Element) + Send + Sync + 'static>> = Box_::new(Box_::new(f));
@ -306,12 +296,6 @@ where P: IsA<Bin> {
f(&Bin::from_glib_borrow(this).unsafe_cast(), &from_glib_borrow(sub_bin), &from_glib_borrow(element)) f(&Bin::from_glib_borrow(this).unsafe_cast(), &from_glib_borrow(sub_bin), &from_glib_borrow(element))
} }
unsafe extern "C" fn do_latency_trampoline<P>(this: *mut ffi::GstBin, f: glib_ffi::gpointer) -> glib_ffi::gboolean
where P: IsA<Bin> {
let f: &&(Fn(&P) -> bool + Send + Sync + 'static) = transmute(f);
f(&Bin::from_glib_borrow(this).unsafe_cast()).to_glib()
}
unsafe extern "C" fn element_added_trampoline<P>(this: *mut ffi::GstBin, element: *mut ffi::GstElement, f: glib_ffi::gpointer) unsafe extern "C" fn element_added_trampoline<P>(this: *mut ffi::GstBin, element: *mut ffi::GstElement, f: glib_ffi::gpointer)
where P: IsA<Bin> { where P: IsA<Bin> {
let f: &&(Fn(&P, &Element) + Send + Sync + 'static) = transmute(f); let f: &&(Fn(&P, &Element) + Send + Sync + 'static) = transmute(f);

View file

@ -96,9 +96,9 @@ impl Bus {
} }
} }
pub fn remove_watch(&self) -> bool { pub fn remove_watch(&self) -> Result<(), glib::error::BoolError> {
unsafe { unsafe {
from_glib(ffi::gst_bus_remove_watch(self.to_glib_none().0)) glib_result_from_gboolean!(ffi::gst_bus_remove_watch(self.to_glib_none().0), "Bus has no event source")
} }
} }

View file

@ -7,6 +7,7 @@ use Element;
use Object; use Object;
use Structure; use Structure;
use ffi; use ffi;
use glib;
use glib::GString; use glib::GString;
use glib::object::Cast; use glib::object::Cast;
use glib::object::IsA; use glib::object::IsA;
@ -45,7 +46,7 @@ pub trait DeviceExt: 'static {
fn has_classesv(&self, classes: &[&str]) -> bool; fn has_classesv(&self, classes: &[&str]) -> bool;
fn reconfigure_element<P: IsA<Element>>(&self, element: &P) -> bool; fn reconfigure_element<P: IsA<Element>>(&self, element: &P) -> Result<(), glib::error::BoolError>;
fn connect_removed<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId; fn connect_removed<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId;
} }
@ -94,9 +95,9 @@ impl<O: IsA<Device>> DeviceExt for O {
} }
} }
fn reconfigure_element<P: IsA<Element>>(&self, element: &P) -> bool { fn reconfigure_element<P: IsA<Element>>(&self, element: &P) -> Result<(), glib::error::BoolError> {
unsafe { unsafe {
from_glib(ffi::gst_device_reconfigure_element(self.as_ref().to_glib_none().0, element.as_ref().to_glib_none().0)) glib_result_from_gboolean!(ffi::gst_device_reconfigure_element(self.as_ref().to_glib_none().0, element.as_ref().to_glib_none().0), "Failed to reconfigure the element to use this device")
} }
} }

View file

@ -45,7 +45,7 @@ pub trait DeviceMonitorExt: 'static {
fn get_show_all_devices(&self) -> bool; fn get_show_all_devices(&self) -> bool;
fn remove_filter(&self, filter_id: u32) -> bool; fn remove_filter(&self, filter_id: u32) -> Result<(), glib::error::BoolError>;
fn set_show_all_devices(&self, show_all: bool); fn set_show_all_devices(&self, show_all: bool);
@ -93,9 +93,9 @@ impl<O: IsA<DeviceMonitor>> DeviceMonitorExt for O {
} }
} }
fn remove_filter(&self, filter_id: u32) -> bool { fn remove_filter(&self, filter_id: u32) -> Result<(), glib::error::BoolError> {
unsafe { unsafe {
from_glib(ffi::gst_device_monitor_remove_filter(self.as_ref().to_glib_none().0, filter_id)) glib_result_from_gboolean!(ffi::gst_device_monitor_remove_filter(self.as_ref().to_glib_none().0, filter_id), "Failed to remove the filter")
} }
} }

View file

@ -11,6 +11,7 @@ use Error;
#[cfg(any(feature = "v1_12", feature = "dox"))] #[cfg(any(feature = "v1_12", feature = "dox"))]
use StackTraceFlags; use StackTraceFlags;
use ffi; use ffi;
use glib;
use glib::GString; use glib::GString;
use glib::object::IsA; use glib::object::IsA;
use glib::translate::*; use glib::translate::*;
@ -177,10 +178,10 @@ pub fn parse_launchv(argv: &[&str]) -> Result<Element, Error> {
} }
} }
pub fn update_registry() -> bool { pub fn update_registry() -> Result<(), glib::error::BoolError> {
assert_initialized_main_thread!(); assert_initialized_main_thread!();
unsafe { unsafe {
from_glib(ffi::gst_update_registry()) glib_result_from_gboolean!(ffi::gst_update_registry(), "Failed to update the registry")
} }
} }

View file

@ -125,7 +125,7 @@ pub trait PadExt: 'static {
fn link_maybe_ghosting<P: IsA<Pad>>(&self, sink: &P) -> Result<(), glib::error::BoolError>; fn link_maybe_ghosting<P: IsA<Pad>>(&self, sink: &P) -> Result<(), glib::error::BoolError>;
#[cfg(any(feature = "v1_10", feature = "dox"))] #[cfg(any(feature = "v1_10", feature = "dox"))]
fn link_maybe_ghosting_full<P: IsA<Pad>>(&self, sink: &P, flags: PadLinkCheck) -> bool; fn link_maybe_ghosting_full<P: IsA<Pad>>(&self, sink: &P, flags: PadLinkCheck) -> Result<(), glib::error::BoolError>;
fn mark_reconfigure(&self); fn mark_reconfigure(&self);
@ -357,14 +357,14 @@ impl<O: IsA<Pad>> PadExt for O {
#[cfg(any(feature = "v1_10", feature = "dox"))] #[cfg(any(feature = "v1_10", feature = "dox"))]
fn link_maybe_ghosting<P: IsA<Pad>>(&self, sink: &P) -> Result<(), glib::error::BoolError> { fn link_maybe_ghosting<P: IsA<Pad>>(&self, sink: &P) -> Result<(), glib::error::BoolError> {
unsafe { unsafe {
glib_result_from_gboolean!(ffi::gst_pad_link_maybe_ghosting(self.as_ref().to_glib_none().0, sink.as_ref().to_glib_none().0), "Failed to link pad, possibly ghosting") glib_result_from_gboolean!(ffi::gst_pad_link_maybe_ghosting(self.as_ref().to_glib_none().0, sink.as_ref().to_glib_none().0), "Failed to link pads, possibly ghosting")
} }
} }
#[cfg(any(feature = "v1_10", feature = "dox"))] #[cfg(any(feature = "v1_10", feature = "dox"))]
fn link_maybe_ghosting_full<P: IsA<Pad>>(&self, sink: &P, flags: PadLinkCheck) -> bool { fn link_maybe_ghosting_full<P: IsA<Pad>>(&self, sink: &P, flags: PadLinkCheck) -> Result<(), glib::error::BoolError> {
unsafe { unsafe {
from_glib(ffi::gst_pad_link_maybe_ghosting_full(self.as_ref().to_glib_none().0, sink.as_ref().to_glib_none().0, flags.to_glib())) glib_result_from_gboolean!(ffi::gst_pad_link_maybe_ghosting_full(self.as_ref().to_glib_none().0, sink.as_ref().to_glib_none().0, flags.to_glib()), "Failed to link pads, possibly ghosting")
} }
} }

View file

@ -10,18 +10,28 @@ use Bin;
use Element; use Element;
use glib; use glib;
use glib::object::Cast;
use glib::object::IsA; use glib::object::IsA;
use glib::translate::{from_glib, from_glib_full, FromGlibPtrContainer, ToGlib, ToGlibPtr}; use glib::signal::connect_raw;
use glib::signal::SignalHandlerId;
use glib::translate::*;
use glib::GString; use glib::GString;
use ffi; use ffi;
use std::boxed::Box as Box_;
use std::mem::transmute;
use std::path; use std::path;
pub trait GstBinExtManual: 'static { pub trait GstBinExtManual: 'static {
fn add_many<E: IsA<Element>>(&self, elements: &[&E]) -> Result<(), glib::BoolError>; fn add_many<E: IsA<Element>>(&self, elements: &[&E]) -> Result<(), glib::BoolError>;
fn remove_many<E: IsA<Element>>(&self, elements: &[&E]) -> Result<(), glib::BoolError>; fn remove_many<E: IsA<Element>>(&self, elements: &[&E]) -> Result<(), glib::BoolError>;
fn connect_do_latency<F: Fn(&Self) -> Result<(), glib::BoolError> + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId;
fn iterate_all_by_interface(&self, iface: glib::types::Type) -> ::Iterator<Element>; fn iterate_all_by_interface(&self, iface: glib::types::Type) -> ::Iterator<Element>;
fn iterate_elements(&self) -> ::Iterator<Element>; fn iterate_elements(&self) -> ::Iterator<Element>;
fn iterate_recurse(&self) -> ::Iterator<Element>; fn iterate_recurse(&self) -> ::Iterator<Element>;
@ -64,7 +74,7 @@ impl<O: IsA<Bin>> GstBinExtManual for O {
e.as_ref().to_glib_none().0, e.as_ref().to_glib_none().0,
)); ));
if !ret { if !ret {
return Err(glib_bool_error!("Failed to add elements")); return Err(glib_bool_error!("Failed to remove elements"));
} }
} }
} }
@ -72,6 +82,22 @@ impl<O: IsA<Bin>> GstBinExtManual for O {
Ok(()) Ok(())
} }
fn connect_do_latency<F: Fn(&Self) -> Result<(), glib::BoolError> + Send + Sync + 'static>(
&self,
f: F,
) -> SignalHandlerId {
unsafe {
let f: Box_<Box_<Fn(&Self) -> Result<(), glib::BoolError> + Send + Sync + 'static>> =
Box_::new(Box_::new(f));
connect_raw(
self.as_ptr() as *mut _,
b"do-latency\0".as_ptr() as *const _,
transmute(do_latency_trampoline::<Self> as usize),
Box_::into_raw(f) as *mut _,
)
}
}
fn iterate_all_by_interface(&self, iface: glib::types::Type) -> ::Iterator<Element> { fn iterate_all_by_interface(&self, iface: glib::types::Type) -> ::Iterator<Element> {
unsafe { unsafe {
from_glib_full(ffi::gst_bin_iterate_all_by_interface( from_glib_full(ffi::gst_bin_iterate_all_by_interface(
@ -130,6 +156,24 @@ impl<O: IsA<Bin>> GstBinExtManual for O {
} }
} }
unsafe extern "C" fn do_latency_trampoline<P>(
this: *mut ffi::GstBin,
f: glib_ffi::gpointer,
) -> glib_ffi::gboolean
where
P: IsA<Bin>,
{
let f: &&(Fn(&P) -> Result<(), glib::BoolError> + Send + Sync + 'static) = transmute(f);
match f(&Bin::from_glib_borrow(this).unsafe_cast()) {
Ok(()) => true,
Err(err) => {
gst_error!(::CAT_RUST, obj: &Bin::from_glib_borrow(this), "{}", err);
false
}
}
.to_glib()
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -131,17 +131,20 @@ impl BufferPoolConfig {
size: u32, size: u32,
min_buffers: u32, min_buffers: u32,
max_buffers: u32, max_buffers: u32,
) -> bool { ) -> Result<(), glib::BoolError> {
let caps = caps.into(); let caps = caps.into();
unsafe { unsafe {
from_glib(ffi::gst_buffer_pool_config_validate_params( glib_result_from_gboolean!(
self.0.to_glib_none().0, ffi::gst_buffer_pool_config_validate_params(
caps.to_glib_none().0, self.0.to_glib_none().0,
size, caps.to_glib_none().0,
min_buffers, size,
max_buffers, min_buffers,
)) max_buffers,
),
"Parameters are not valid in this context"
)
} }
} }

View file

@ -58,16 +58,19 @@ impl GhostPad {
parent: R, parent: R,
mode: PadMode, mode: PadMode,
active: bool, active: bool,
) -> bool { ) -> Result<(), glib::BoolError> {
skip_assert_initialized!(); skip_assert_initialized!();
let parent = parent.into(); let parent = parent.into();
unsafe { unsafe {
from_glib(ffi::gst_ghost_pad_activate_mode_default( glib_result_from_gboolean!(
pad.to_glib_none().0 as *mut ffi::GstPad, ffi::gst_ghost_pad_activate_mode_default(
parent.map(|p| p.as_ref()).to_glib_none().0, pad.to_glib_none().0 as *mut ffi::GstPad,
mode.to_glib(), parent.map(|p| p.as_ref()).to_glib_none().0,
active.to_glib(), mode.to_glib(),
)) active.to_glib(),
),
"Failed to invoke the default activate mode function of the ghost pad"
)
} }
} }
@ -81,16 +84,22 @@ impl GhostPad {
parent: R, parent: R,
mode: PadMode, mode: PadMode,
active: bool, active: bool,
) -> bool { ) -> Result<(), glib::BoolError> {
skip_assert_initialized!(); skip_assert_initialized!();
let parent = parent.into(); let parent = parent.into();
unsafe { unsafe {
from_glib(ffi::gst_ghost_pad_internal_activate_mode_default( glib_result_from_gboolean!(
pad.to_glib_none().0 as *mut ffi::GstPad, ffi::gst_ghost_pad_internal_activate_mode_default(
parent.map(|p| p.as_ref()).to_glib_none().0, pad.to_glib_none().0 as *mut ffi::GstPad,
mode.to_glib(), parent.map(|p| p.as_ref()).to_glib_none().0,
active.to_glib(), mode.to_glib(),
)) active.to_glib(),
),
concat!(
"Failed to invoke the default activate mode function of a proxy pad ",
"that is owned by the ghost pad"
)
)
} }
} }
} }

View file

@ -161,11 +161,14 @@ pub trait PadExtManual: 'static {
fn set_activate_function<F>(&self, func: F) fn set_activate_function<F>(&self, func: F)
where where
F: Fn(&Pad, &Option<::Object>) -> bool + Send + Sync + 'static; F: Fn(&Pad, &Option<::Object>) -> Result<(), glib::BoolError> + Send + Sync + 'static;
fn set_activatemode_function<F>(&self, func: F) fn set_activatemode_function<F>(&self, func: F)
where where
F: Fn(&Pad, &Option<::Object>, ::PadMode, bool) -> bool + Send + Sync + 'static; F: Fn(&Pad, &Option<::Object>, ::PadMode, bool) -> Result<(), glib::BoolError>
+ Send
+ Sync
+ 'static;
fn set_chain_function<F>(&self, func: F) fn set_chain_function<F>(&self, func: F)
where where
@ -510,12 +513,13 @@ impl<O: IsA<Pad>> PadExtManual for O {
fn set_activate_function<F>(&self, func: F) fn set_activate_function<F>(&self, func: F)
where where
F: Fn(&Pad, &Option<::Object>) -> bool + Send + Sync + 'static, F: Fn(&Pad, &Option<::Object>) -> Result<(), glib::BoolError> + Send + Sync + 'static,
{ {
#[cfg_attr(feature = "cargo-clippy", allow(type_complexity))] #[cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
unsafe { unsafe {
let func_box: Box<Fn(&Pad, &Option<::Object>) -> bool + Send + Sync + 'static> = let func_box: Box<
Box::new(func); Fn(&Pad, &Option<::Object>) -> Result<(), glib::BoolError> + Send + Sync + 'static,
> = Box::new(func);
ffi::gst_pad_set_activate_function_full( ffi::gst_pad_set_activate_function_full(
self.as_ref().to_glib_none().0, self.as_ref().to_glib_none().0,
Some(trampoline_activate_function), Some(trampoline_activate_function),
@ -527,12 +531,18 @@ impl<O: IsA<Pad>> PadExtManual for O {
fn set_activatemode_function<F>(&self, func: F) fn set_activatemode_function<F>(&self, func: F)
where where
F: Fn(&Pad, &Option<::Object>, ::PadMode, bool) -> bool + Send + Sync + 'static, F: Fn(&Pad, &Option<::Object>, ::PadMode, bool) -> Result<(), glib::BoolError>
+ Send
+ Sync
+ 'static,
{ {
#[cfg_attr(feature = "cargo-clippy", allow(type_complexity))] #[cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
unsafe { unsafe {
let func_box: Box< let func_box: Box<
Fn(&Pad, &Option<::Object>, ::PadMode, bool) -> bool + Send + Sync + 'static, Fn(&Pad, &Option<::Object>, ::PadMode, bool) -> Result<(), glib::BoolError>
+ Send
+ Sync
+ 'static,
> = Box::new(func); > = Box::new(func);
ffi::gst_pad_set_activatemode_function_full( ffi::gst_pad_set_activatemode_function_full(
self.as_ref().to_glib_none().0, self.as_ref().to_glib_none().0,
@ -1106,10 +1116,20 @@ unsafe extern "C" fn trampoline_activate_function(
parent: *mut ffi::GstObject, parent: *mut ffi::GstObject,
) -> glib_ffi::gboolean { ) -> glib_ffi::gboolean {
#[cfg_attr(feature = "cargo-clippy", allow(transmute_ptr_to_ref))] #[cfg_attr(feature = "cargo-clippy", allow(transmute_ptr_to_ref))]
let func: &&(Fn(&Pad, &Option<::Object>) -> bool + Send + Sync + 'static) = let func: &&(Fn(&Pad, &Option<::Object>) -> Result<(), glib::BoolError>
transmute((*pad).activatedata); + Send
+ Sync
+ 'static) = transmute((*pad).activatedata);
func(&from_glib_borrow(pad), &from_glib_borrow(parent)).to_glib() let pad: Pad = from_glib_borrow(pad);
match func(&pad, &from_glib_borrow(parent)) {
Ok(()) => true,
Err(err) => {
gst_error!(::CAT_RUST, obj: &pad, "{}", err);
false
}
}
.to_glib()
} }
unsafe extern "C" fn trampoline_activatemode_function( unsafe extern "C" fn trampoline_activatemode_function(

View file

@ -171,13 +171,16 @@ impl<T: FormattedValue> FormattedSegment<T> {
} }
} }
pub fn offset_running_time(&mut self, offset: i64) -> bool { pub fn offset_running_time(&mut self, offset: i64) -> Result<(), glib::BoolError> {
unsafe { unsafe {
from_glib(ffi::gst_segment_offset_running_time( glib_result_from_gboolean!(
&mut self.0, ffi::gst_segment_offset_running_time(
self.get_format().to_glib(), &mut self.0,
offset, self.get_format().to_glib(),
)) offset,
),
"Offset is not in the segment"
)
} }
} }
@ -257,7 +260,7 @@ impl<T: FormattedValue> FormattedSegment<T> {
} }
} }
pub fn set_running_time<V: Into<T>>(&mut self, running_time: V) -> bool { pub fn set_running_time<V: Into<T>>(&mut self, running_time: V) -> Result<(), glib::BoolError> {
let running_time = running_time.into(); let running_time = running_time.into();
if T::get_default_format() == Format::Undefined { if T::get_default_format() == Format::Undefined {
@ -265,11 +268,14 @@ impl<T: FormattedValue> FormattedSegment<T> {
} }
unsafe { unsafe {
from_glib(ffi::gst_segment_set_running_time( glib_result_from_gboolean!(
&mut self.0, ffi::gst_segment_set_running_time(
self.get_format().to_glib(), &mut self.0,
running_time.to_raw_value() as u64, self.get_format().to_glib(),
)) running_time.to_raw_value() as u64,
),
"Running time is not in the segment"
)
} }
} }

View file

@ -20,11 +20,11 @@ use Element;
use Message; use Message;
pub trait BinImpl: ElementImpl + Send + Sync + 'static { pub trait BinImpl: ElementImpl + Send + Sync + 'static {
fn add_element(&self, bin: &Bin, element: &Element) -> bool { fn add_element(&self, bin: &Bin, element: &Element) -> Result<(), glib::BoolError> {
self.parent_add_element(bin, element) self.parent_add_element(bin, element)
} }
fn remove_element(&self, bin: &Bin, element: &Element) -> bool { fn remove_element(&self, bin: &Bin, element: &Element) -> Result<(), glib::BoolError> {
self.parent_remove_element(bin, element) self.parent_remove_element(bin, element)
} }
@ -32,25 +32,31 @@ pub trait BinImpl: ElementImpl + Send + Sync + 'static {
self.parent_handle_message(bin, message) self.parent_handle_message(bin, message)
} }
fn parent_add_element(&self, bin: &Bin, element: &Element) -> bool { fn parent_add_element(&self, bin: &Bin, element: &Element) -> Result<(), glib::BoolError> {
unsafe { unsafe {
let data = self.get_type_data(); let data = self.get_type_data();
let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBinClass; let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBinClass;
(*parent_class) let f = (*parent_class)
.add_element .add_element
.map(|f| from_glib(f(bin.to_glib_none().0, element.to_glib_none().0))) .ok_or_else(|| glib_bool_error!("Parent function `add_element` is not defined"))?;
.unwrap_or(false) glib_result_from_gboolean!(
f(bin.to_glib_none().0, element.to_glib_none().0),
"Failed to add the element using the parent function"
)
} }
} }
fn parent_remove_element(&self, bin: &Bin, element: &Element) -> bool { fn parent_remove_element(&self, bin: &Bin, element: &Element) -> Result<(), glib::BoolError> {
unsafe { unsafe {
let data = self.get_type_data(); let data = self.get_type_data();
let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBinClass; let parent_class = data.as_ref().get_parent_class() as *mut ffi::GstBinClass;
(*parent_class) let f = (*parent_class).remove_element.ok_or_else(|| {
.remove_element glib_bool_error!("Parent function `remove_element` is not defined")
.map(|f| from_glib(f(bin.to_glib_none().0, element.to_glib_none().0))) })?;
.unwrap_or(false) glib_result_from_gboolean!(
f(bin.to_glib_none().0, element.to_glib_none().0),
"Failed to remove the element using the parent function"
)
} }
} }
@ -94,7 +100,13 @@ where
let wrap: Bin = from_glib_borrow(ptr); let wrap: Bin = from_glib_borrow(ptr);
gst_panic_to_error!(&wrap, &instance.panicked(), false, { gst_panic_to_error!(&wrap, &instance.panicked(), false, {
imp.add_element(&wrap, &from_glib_borrow(element)) match imp.add_element(&wrap, &from_glib_borrow(element)) {
Ok(()) => true,
Err(err) => {
gst_error!(::CAT_RUST, obj: &wrap, "{}", err);
false
}
}
}) })
.to_glib() .to_glib()
} }
@ -113,7 +125,13 @@ where
let wrap: Bin = from_glib_borrow(ptr); let wrap: Bin = from_glib_borrow(ptr);
gst_panic_to_error!(&wrap, &instance.panicked(), false, { gst_panic_to_error!(&wrap, &instance.panicked(), false, {
imp.remove_element(&wrap, &from_glib_borrow(element)) match imp.remove_element(&wrap, &from_glib_borrow(element)) {
Ok(()) => true,
Err(err) => {
gst_error!(::CAT_RUST, obj: &wrap, "{}", err);
false
}
}
}) })
.to_glib() .to_glib()
} }

View file

@ -48,20 +48,23 @@ macro_rules! gst_plugin_define(
_gst_reserved: [0 as $crate::glib_ffi::gpointer; 4], _gst_reserved: [0 as $crate::glib_ffi::gpointer; 4],
}); });
pub fn plugin_register_static() -> bool { pub fn plugin_register_static() -> Result<(), glib::BoolError> {
unsafe { unsafe {
from_glib($crate::ffi::gst_plugin_register_static( glib_result_from_gboolean!(
$crate::subclass::plugin::MAJOR_VERSION, $crate::ffi::gst_plugin_register_static(
$crate::subclass::plugin::MINOR_VERSION, $crate::subclass::plugin::MAJOR_VERSION,
concat!($name, "\0") as *const str as *const _, $crate::subclass::plugin::MINOR_VERSION,
concat!($description, "\0") as *const str as _, concat!($name, "\0") as *const str as *const _,
Some(plugin_init_trampoline), concat!($description, "\0") as *const str as _,
concat!($version, "\0") as *const str as *const _, Some(plugin_init_trampoline),
concat!($license, "\0") as *const str as *const _, concat!($version, "\0") as *const str as *const _,
concat!($source, "\0") as *const str as *const _, concat!($license, "\0") as *const str as *const _,
concat!($package, "\0") as *const str as *const _, concat!($source, "\0") as *const str as *const _,
concat!($origin, "\0") as *const str as *const _, concat!($package, "\0") as *const str as *const _,
)) concat!($origin, "\0") as *const str as *const _,
),
"Failed to register the plugin"
)
} }
} }

View file

@ -80,8 +80,8 @@ fn tutorial_main() -> Result<(), Error> {
main_loop.run(); main_loop.run();
bus.remove_watch(); bus.remove_watch()?;
let _ = pipeline.set_state(gst::State::Null); pipeline.set_state(gst::State::Null)?;
Ok(()) Ok(())
} }