diff --git a/Gir_Gst.toml b/Gir_Gst.toml index c59a88a06..fa2f45e29 100644 --- a/Gir_Gst.toml +++ b/Gir_Gst.toml @@ -81,7 +81,6 @@ manual = [ "GLib.Source", "GLib.DateTime", "GObject.Object", - "Gst.Iterator", "Gst.Segment", ] diff --git a/examples/src/bin/iterator.rs b/examples/src/bin/iterator.rs index ff4db5ab8..37164f289 100644 --- a/examples/src/bin/iterator.rs +++ b/examples/src/bin/iterator.rs @@ -5,10 +5,10 @@ fn main() { gst::init().unwrap(); let identity = gst::ElementFactory::make("identity", None).unwrap(); - let mut iter = identity.iterate_pads().unwrap(); + let mut iter = identity.iterate_pads(); while let Some(res) = iter.next() { match res { - Ok(pad) => println!("Pad: {}", pad.get::().unwrap().get_name()), + Ok(pad) => println!("Pad: {}", pad.get_name()), Err(gst::IteratorError::Resync) => { println!("Iterator resync"); iter.resync(); diff --git a/gstreamer/src/auto/bin.rs b/gstreamer/src/auto/bin.rs index b62e80ce7..5cb7ef9e4 100644 --- a/gstreamer/src/auto/bin.rs +++ b/gstreamer/src/auto/bin.rs @@ -5,7 +5,6 @@ use ChildProxy; use Element; #[cfg(feature = "v1_10")] use ElementFlags; -use Iterator; use Object; use Pad; use PadDirection; @@ -62,17 +61,17 @@ pub trait BinExt { #[cfg(feature = "v1_10")] fn get_suppressed_flags(&self) -> ElementFlags; - fn iterate_all_by_interface(&self, iface: glib::types::Type) -> Option; + //fn iterate_all_by_interface(&self, iface: glib::types::Type) -> /*Ignored*/Option; - fn iterate_elements(&self) -> Option; + //fn iterate_elements(&self) -> /*Ignored*/Option; - fn iterate_recurse(&self) -> Option; + //fn iterate_recurse(&self) -> /*Ignored*/Option; - fn iterate_sinks(&self) -> Option; + //fn iterate_sinks(&self) -> /*Ignored*/Option; - fn iterate_sorted(&self) -> Option; + //fn iterate_sorted(&self) -> /*Ignored*/Option; - fn iterate_sources(&self) -> Option; + //fn iterate_sources(&self) -> /*Ignored*/Option; fn recalculate_latency(&self) -> Result<(), glib::error::BoolError>; @@ -152,41 +151,29 @@ impl + IsA> BinExt for O { } } - fn iterate_all_by_interface(&self, iface: glib::types::Type) -> Option { - unsafe { - from_glib_full(ffi::gst_bin_iterate_all_by_interface(self.to_glib_none().0, iface.to_glib())) - } - } + //fn iterate_all_by_interface(&self, iface: glib::types::Type) -> /*Ignored*/Option { + // unsafe { TODO: call ffi::gst_bin_iterate_all_by_interface() } + //} - fn iterate_elements(&self) -> Option { - unsafe { - from_glib_full(ffi::gst_bin_iterate_elements(self.to_glib_none().0)) - } - } + //fn iterate_elements(&self) -> /*Ignored*/Option { + // unsafe { TODO: call ffi::gst_bin_iterate_elements() } + //} - fn iterate_recurse(&self) -> Option { - unsafe { - from_glib_full(ffi::gst_bin_iterate_recurse(self.to_glib_none().0)) - } - } + //fn iterate_recurse(&self) -> /*Ignored*/Option { + // unsafe { TODO: call ffi::gst_bin_iterate_recurse() } + //} - fn iterate_sinks(&self) -> Option { - unsafe { - from_glib_full(ffi::gst_bin_iterate_sinks(self.to_glib_none().0)) - } - } + //fn iterate_sinks(&self) -> /*Ignored*/Option { + // unsafe { TODO: call ffi::gst_bin_iterate_sinks() } + //} - fn iterate_sorted(&self) -> Option { - unsafe { - from_glib_full(ffi::gst_bin_iterate_sorted(self.to_glib_none().0)) - } - } + //fn iterate_sorted(&self) -> /*Ignored*/Option { + // unsafe { TODO: call ffi::gst_bin_iterate_sorted() } + //} - fn iterate_sources(&self) -> Option { - unsafe { - from_glib_full(ffi::gst_bin_iterate_sources(self.to_glib_none().0)) - } - } + //fn iterate_sources(&self) -> /*Ignored*/Option { + // unsafe { TODO: call ffi::gst_bin_iterate_sources() } + //} fn recalculate_latency(&self) -> Result<(), glib::error::BoolError> { unsafe { diff --git a/gstreamer/src/auto/element.rs b/gstreamer/src/auto/element.rs index a0026c108..1861b7f0c 100644 --- a/gstreamer/src/auto/element.rs +++ b/gstreamer/src/auto/element.rs @@ -9,7 +9,6 @@ use Context; use ElementFactory; use Error; use Format; -use Iterator; use Message; use Object; use Pad; @@ -131,11 +130,11 @@ pub trait ElementExt { fn is_locked_state(&self) -> bool; - fn iterate_pads(&self) -> Option; + //fn iterate_pads(&self) -> /*Ignored*/Option; - fn iterate_sink_pads(&self) -> Option; + //fn iterate_sink_pads(&self) -> /*Ignored*/Option; - fn iterate_src_pads(&self) -> Option; + //fn iterate_src_pads(&self) -> /*Ignored*/Option; fn link>(&self, dest: &P) -> Result<(), glib::error::BoolError>; @@ -347,23 +346,17 @@ impl + IsA> ElementExt for O { } } - fn iterate_pads(&self) -> Option { - unsafe { - from_glib_full(ffi::gst_element_iterate_pads(self.to_glib_none().0)) - } - } + //fn iterate_pads(&self) -> /*Ignored*/Option { + // unsafe { TODO: call ffi::gst_element_iterate_pads() } + //} - fn iterate_sink_pads(&self) -> Option { - unsafe { - from_glib_full(ffi::gst_element_iterate_sink_pads(self.to_glib_none().0)) - } - } + //fn iterate_sink_pads(&self) -> /*Ignored*/Option { + // unsafe { TODO: call ffi::gst_element_iterate_sink_pads() } + //} - fn iterate_src_pads(&self) -> Option { - unsafe { - from_glib_full(ffi::gst_element_iterate_src_pads(self.to_glib_none().0)) - } - } + //fn iterate_src_pads(&self) -> /*Ignored*/Option { + // unsafe { TODO: call ffi::gst_element_iterate_src_pads() } + //} fn link>(&self, dest: &P) -> Result<(), glib::error::BoolError> { unsafe { diff --git a/gstreamer/src/auto/pad.rs b/gstreamer/src/auto/pad.rs index bfa183130..2e1e89abc 100644 --- a/gstreamer/src/auto/pad.rs +++ b/gstreamer/src/auto/pad.rs @@ -7,7 +7,6 @@ use Event; use EventType; use FlowReturn; use Format; -use Iterator; use Object; use PadDirection; use PadLinkCheck; @@ -130,9 +129,9 @@ pub trait PadExt { fn is_linked(&self) -> bool; - fn iterate_internal_links(&self) -> Option; + //fn iterate_internal_links(&self) -> /*Ignored*/Option; - fn iterate_internal_links_default<'a, P: IsA + 'a, Q: Into>>(&self, parent: Q) -> Option; + //fn iterate_internal_links_default<'a, P: IsA + 'a, Q: Into>>(&self, parent: Q) -> /*Ignored*/Option; fn link>(&self, sinkpad: &P) -> PadLinkReturn; @@ -384,19 +383,13 @@ impl + IsA> PadExt for O { } } - fn iterate_internal_links(&self) -> Option { - unsafe { - from_glib_full(ffi::gst_pad_iterate_internal_links(self.to_glib_none().0)) - } - } + //fn iterate_internal_links(&self) -> /*Ignored*/Option { + // unsafe { TODO: call ffi::gst_pad_iterate_internal_links() } + //} - fn iterate_internal_links_default<'a, P: IsA + 'a, Q: Into>>(&self, parent: Q) -> Option { - let parent = parent.into(); - let parent = parent.to_glib_none(); - unsafe { - from_glib_full(ffi::gst_pad_iterate_internal_links_default(self.to_glib_none().0, parent.0)) - } - } + //fn iterate_internal_links_default<'a, P: IsA + 'a, Q: Into>>(&self, parent: Q) -> /*Ignored*/Option { + // unsafe { TODO: call ffi::gst_pad_iterate_internal_links_default() } + //} fn link>(&self, sinkpad: &P) -> PadLinkReturn { unsafe { diff --git a/gstreamer/src/auto/proxy_pad.rs b/gstreamer/src/auto/proxy_pad.rs index 20b0b0015..51103fb62 100644 --- a/gstreamer/src/auto/proxy_pad.rs +++ b/gstreamer/src/auto/proxy_pad.rs @@ -1,7 +1,6 @@ // This file was generated by gir (6a48033) from gir-files (???) // DO NOT EDIT -use Iterator; use Object; use Pad; use ffi; @@ -21,14 +20,9 @@ glib_wrapper! { } impl ProxyPad { - pub fn iterate_internal_links_default<'a, P: IsA, Q: IsA + 'a, R: Into>>(pad: &P, parent: R) -> Option { - skip_assert_initialized!(); - let parent = parent.into(); - let parent = parent.to_glib_none(); - unsafe { - from_glib_full(ffi::gst_proxy_pad_iterate_internal_links_default(pad.to_glib_none().0, parent.0)) - } - } + //pub fn iterate_internal_links_default<'a, P: IsA, Q: IsA + 'a, R: Into>>(pad: &P, parent: R) -> /*Ignored*/Option { + // unsafe { TODO: call ffi::gst_proxy_pad_iterate_internal_links_default() } + //} } unsafe impl Send for ProxyPad {} diff --git a/gstreamer/src/bin.rs b/gstreamer/src/bin.rs index 742d7a0b6..7dc7a4622 100644 --- a/gstreamer/src/bin.rs +++ b/gstreamer/src/bin.rs @@ -11,13 +11,20 @@ use Element; use glib; use glib::IsA; -use glib::translate::{from_glib, ToGlibPtr}; +use glib::translate::{from_glib, from_glib_full, ToGlibPtr, ToGlib}; use ffi; pub trait BinExtManual { fn add_many>(&self, elements: &[&E]) -> Result<(), glib::BoolError>; fn remove_many>(&self, elements: &[&E]) -> Result<(), glib::BoolError>; + + fn iterate_all_by_interface(&self, iface: glib::types::Type) -> ::Iterator; + fn iterate_elements(&self) -> ::Iterator; + fn iterate_recurse(&self) -> ::Iterator; + fn iterate_sinks(&self) -> ::Iterator; + fn iterate_sorted(&self) -> ::Iterator; + fn iterate_sources(&self) -> ::Iterator; } impl> BinExtManual for O { @@ -50,4 +57,40 @@ impl> BinExtManual for O { Ok(()) } + + fn iterate_all_by_interface(&self, iface: glib::types::Type) -> ::Iterator { + unsafe { + from_glib_full(ffi::gst_bin_iterate_all_by_interface(self.to_glib_none().0, iface.to_glib())) + } + } + + fn iterate_elements(&self) -> ::Iterator { + unsafe { + from_glib_full(ffi::gst_bin_iterate_elements(self.to_glib_none().0)) + } + } + + fn iterate_recurse(&self) -> ::Iterator { + unsafe { + from_glib_full(ffi::gst_bin_iterate_recurse(self.to_glib_none().0)) + } + } + + fn iterate_sinks(&self) -> ::Iterator { + unsafe { + from_glib_full(ffi::gst_bin_iterate_sinks(self.to_glib_none().0)) + } + } + + fn iterate_sorted(&self) -> ::Iterator { + unsafe { + from_glib_full(ffi::gst_bin_iterate_sorted(self.to_glib_none().0)) + } + } + + fn iterate_sources(&self) -> ::Iterator { + unsafe { + from_glib_full(ffi::gst_bin_iterate_sources(self.to_glib_none().0)) + } + } } diff --git a/gstreamer/src/element.rs b/gstreamer/src/element.rs index c89d1b7d8..67c933f3f 100644 --- a/gstreamer/src/element.rs +++ b/gstreamer/src/element.rs @@ -10,9 +10,10 @@ use Element; use glib; use glib::IsA; -use glib::translate::{from_glib, from_glib_none, FromGlibPtrContainer, ToGlibPtr}; +use glib::translate::{from_glib, from_glib_none, from_glib_full, FromGlibPtrContainer, ToGlibPtr}; use QueryRef; use Event; +use Pad; use PadTemplate; use miniobject::MiniObject; @@ -87,6 +88,10 @@ pub trait ElementExtManual { line: i32, structure: ::Structure, ); + + fn iterate_pads(&self) -> ::Iterator; + fn iterate_sink_pads(&self) -> ::Iterator; + fn iterate_src_pads(&self) -> ::Iterator; } impl> ElementExtManual for O { @@ -210,6 +215,24 @@ impl> ElementExtManual for O { ); } } + + fn iterate_pads(&self) -> ::Iterator { + unsafe { + from_glib_full(ffi::gst_element_iterate_pads(self.to_glib_none().0)) + } + } + + fn iterate_sink_pads(&self) -> ::Iterator { + unsafe { + from_glib_full(ffi::gst_element_iterate_sink_pads(self.to_glib_none().0)) + } + } + + fn iterate_src_pads(&self) -> ::Iterator { + unsafe { + from_glib_full(ffi::gst_element_iterate_src_pads(self.to_glib_none().0)) + } + } } lazy_static!{ diff --git a/gstreamer/src/iterator.rs b/gstreamer/src/iterator.rs index 9f96ee020..96d0a0406 100644 --- a/gstreamer/src/iterator.rs +++ b/gstreamer/src/iterator.rs @@ -10,8 +10,11 @@ use std::mem; use std::ptr; use glib; use glib::Value; +use glib::StaticType; +use glib::value::{FromValueOptional, ToValue}; use std::sync::Arc; use std::ffi::CString; +use std::marker::PhantomData; use std::iter::Iterator as StdIterator; #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] @@ -20,17 +23,17 @@ pub enum IteratorError { Error, } -glib_wrapper! { - pub struct Iterator(Boxed); - - match fn { - copy => |ptr| ffi::gst_iterator_copy(mut_override(ptr)), - free => |ptr| ffi::gst_iterator_free(ptr), - get_type => || ffi::gst_iterator_get_type(), - } +// Implemented manually so that we can use generics for the item +pub struct Iterator { + iter: *mut ffi::GstIterator, + borrowed: bool, + phantom: PhantomData, } -impl Iterator { +impl Iterator +where + for<'a> T: FromValueOptional<'a> + 'static, +{ pub fn resync(&mut self) { unsafe { ffi::gst_iterator_resync(self.to_glib_none_mut().0); @@ -39,15 +42,15 @@ impl Iterator { pub fn filter(self, func: F) -> Self where - F: Fn(&glib::Value) -> bool + Send + Sync + 'static, + F: Fn(T) -> bool + Send + Sync + 'static, { unsafe { let it = self.to_glib_none().0; mem::forget(self); let mut closure_value: gobject_ffi::GValue = mem::zeroed(); - let func_box: Box bool + Send + Sync + 'static> = Box::new(func); - gobject_ffi::g_value_init(&mut closure_value, filter_boxed_get_type()); + let func_box: Box bool + Send + Sync + 'static> = Box::new(func); + gobject_ffi::g_value_init(&mut closure_value, filter_boxed_get_type::()); gobject_ffi::g_value_take_boxed( &mut closure_value, Arc::into_raw(Arc::new(func_box)) as gpointer, @@ -55,7 +58,7 @@ impl Iterator { let it = from_glib_full(ffi::gst_iterator_filter( it as *mut _, - Some(filter_trampoline), + Some(filter_trampoline::), &closure_value, )); gobject_ffi::g_value_unset(&mut closure_value); @@ -64,25 +67,25 @@ impl Iterator { } } - pub fn find_simple(&mut self, func: F) -> Option + pub fn find_simple(&mut self, func: F) -> Option where - F: FnMut(&glib::Value) -> bool, + F: FnMut(T) -> bool, { unsafe { let mut elem = glib::Value::uninitialized(); let mut func = func; - let func_obj: &mut (FnMut(&glib::Value) -> bool) = &mut func; - let func_ptr = &func_obj as *const &mut (FnMut(&glib::Value) -> bool) as gpointer; + let func_obj: &mut (FnMut(T) -> bool) = &mut func; + let func_ptr = &func_obj as *const &mut (FnMut(T) -> bool) as gpointer; let res = from_glib(ffi::gst_iterator_find_custom( self.to_glib_none_mut().0, - Some(find_trampoline), + Some(find_trampoline::), elem.to_glib_none_mut().0, func_ptr, )); if res { - Some(elem) + Some(elem.get::().unwrap()) } else { None } @@ -91,16 +94,16 @@ impl Iterator { pub fn foreach(&mut self, func: F) -> Result<(), IteratorError> where - F: FnMut(&glib::Value), + F: FnMut(T), { unsafe { let mut func = func; - let func_obj: &mut (FnMut(&glib::Value)) = &mut func; - let func_ptr = &func_obj as *const &mut (FnMut(&glib::Value)) as gpointer; + let func_obj: &mut (FnMut(T)) = &mut func; + let func_ptr = &func_obj as *const &mut (FnMut(T)) as gpointer; let res = ffi::gst_iterator_foreach( self.to_glib_none_mut().0, - Some(foreach_trampoline), + Some(foreach_trampoline::), func_ptr, ); @@ -112,15 +115,14 @@ impl Iterator { } } - pub fn fold_with_early_exit(&mut self, init: T, func: F) -> Result + pub fn fold_with_early_exit(&mut self, init: U, func: F) -> Result where - F: FnMut(T, &glib::Value) -> Result, + F: FnMut(U, T) -> Result, { unsafe { let mut func = func; - let func_obj: &mut (FnMut(T, &glib::Value) -> Result) = &mut func; - let func_ptr = - &func_obj as *const &mut (FnMut(T, &glib::Value) -> Result) as gpointer; + let func_obj: &mut (FnMut(U, T) -> Result) = &mut func; + let func_ptr = &func_obj as *const &mut (FnMut(U, T) -> Result) as gpointer; let mut ret = glib::Value::uninitialized(); let mut accum = Some(init); @@ -132,7 +134,7 @@ impl Iterator { let res = ffi::gst_iterator_fold( self.to_glib_none_mut().0, - Some(fold_trampoline::), + Some(fold_trampoline::), ret.to_glib_none_mut().0, func_ptr, ); @@ -146,48 +148,62 @@ impl Iterator { } } } +} - pub fn new(imp: I) -> Self { +impl Iterator +where + for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static, +{ + pub fn new>(imp: I) -> Self { static DUMMY_COOKIE: u32 = 0; unsafe { let it = ffi::gst_iterator_new( - mem::size_of::>() as u32, - I::item_type().to_glib(), + mem::size_of::>() as u32, + T::static_type().to_glib(), ptr::null_mut(), &DUMMY_COOKIE as *const _ as *mut _, - Some(rs_iterator_copy::), - Some(rs_iterator_next::), + Some(rs_iterator_copy::), + Some(rs_iterator_next::), None, - Some(rs_iterator_resync::), - Some(rs_iterator_free::), + Some(rs_iterator_resync::), + Some(rs_iterator_free::), ); { - let it = it as *mut RsIterator; + let it = it as *mut RsIterator; (*it).imp = Some(imp); } from_glib_full(it) } } +} - pub fn from_vec( - items: Vec, - ) -> Self { +impl Iterator +where + for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Clone + Send + 'static, +{ + pub fn from_vec(items: Vec) -> Self { Self::new(VecIteratorImpl::new(items)) } } -impl StdIterator for Iterator { - type Item = Result; +impl StdIterator for Iterator +where + for<'a> T: FromValueOptional<'a> + 'static, +{ + type Item = Result; - fn next(&mut self) -> Option> { + fn next(&mut self) -> Option> { unsafe { let mut value = Value::uninitialized(); let res = ffi::gst_iterator_next(self.to_glib_none_mut().0, value.to_glib_none_mut().0); match res { - ffi::GST_ITERATOR_OK => Some(Ok(value)), + ffi::GST_ITERATOR_OK => match value.get::() { + Some(value) => Some(Ok(value)), + None => Some(Err(IteratorError::Error)), + }, ffi::GST_ITERATOR_DONE => None, ffi::GST_ITERATOR_RESYNC => Some(Err(IteratorError::Resync)), ffi::GST_ITERATOR_ERROR => Some(Err(IteratorError::Error)), @@ -197,42 +213,57 @@ impl StdIterator for Iterator { } #[repr(C)] -struct RsIterator { +struct RsIterator> +where + for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static, +{ iter: ffi::GstIterator, imp: Option, + phantom: PhantomData, } -pub trait IteratorImpl: Clone + Send + 'static { - fn item_type() -> glib::Type; - fn next(&mut self) -> Option>; +pub trait IteratorImpl: Clone + Send + 'static +where + for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static, +{ + fn next(&mut self) -> Option>; fn resync(&mut self); } -unsafe extern "C" fn rs_iterator_copy( +unsafe extern "C" fn rs_iterator_copy>( it: *const ffi::GstIterator, copy: *mut ffi::GstIterator, -) { +) where + for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static, +{ callback_guard!(); - let it = it as *const RsIterator; - let copy = copy as *mut RsIterator; + let it = it as *const RsIterator; + let copy = copy as *mut RsIterator; ptr::write(&mut (*copy).imp, (*it).imp.clone()); } -unsafe extern "C" fn rs_iterator_free(it: *mut ffi::GstIterator) { +unsafe extern "C" fn rs_iterator_free>(it: *mut ffi::GstIterator) +where + for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static, +{ callback_guard!(); - let it = it as *mut RsIterator; + let it = it as *mut RsIterator; let _ = (*it).imp.take(); } -unsafe extern "C" fn rs_iterator_next( +unsafe extern "C" fn rs_iterator_next>( it: *mut ffi::GstIterator, result: *mut gobject_ffi::GValue, -) -> ffi::GstIteratorResult { +) -> ffi::GstIteratorResult +where + for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static, +{ callback_guard!(); - let it = it as *mut RsIterator; + let it = it as *mut RsIterator; match (*it).imp.as_mut().map(|imp| imp.next()).unwrap() { Some(Ok(value)) => { + let value = value.to_value(); ptr::write(result, ptr::read(value.to_glib_none().0)); mem::forget(value); ffi::GST_ITERATOR_OK @@ -245,19 +276,25 @@ unsafe extern "C" fn rs_iterator_next( } } -unsafe extern "C" fn rs_iterator_resync(it: *mut ffi::GstIterator) { +unsafe extern "C" fn rs_iterator_resync>(it: *mut ffi::GstIterator) +where + for<'a> T: FromValueOptional<'a> + StaticType + ToValue + Send + 'static, +{ callback_guard!(); - let it = it as *mut RsIterator; + let it = it as *mut RsIterator; (*it).imp.as_mut().map(|imp| imp.resync()).unwrap(); } #[derive(Clone)] -struct VecIteratorImpl { +struct VecIteratorImpl { pos: usize, items: Vec, } -impl VecIteratorImpl { +impl VecIteratorImpl +where + for<'a> T: StaticType + ToValue + FromValueOptional<'a> + Clone + Send + 'static, +{ fn new(items: Vec) -> Self { Self { pos: 0, @@ -266,15 +303,13 @@ impl VecIte } } -impl IteratorImpl - for VecIteratorImpl { - fn item_type() -> glib::Type { - T::static_type() - } - - fn next(&mut self) -> Option> { +impl IteratorImpl for VecIteratorImpl +where + for<'a> T: StaticType + ToValue + FromValueOptional<'a> + Clone + Send + 'static, +{ + fn next(&mut self) -> Option> { if self.pos < self.items.len() { - let res = Ok(self.items[self.pos].clone().to_value()); + let res = Ok(self.items[self.pos].clone()); self.pos += 1; return Some(res); } @@ -287,18 +322,22 @@ impl Iterat } } -unsafe impl Send for Iterator {} +unsafe impl Send for Iterator {} -unsafe extern "C" fn filter_trampoline(value: gconstpointer, func: gconstpointer) -> i32 { +unsafe extern "C" fn filter_trampoline(value: gconstpointer, func: gconstpointer) -> i32 +where + for<'a> T: FromValueOptional<'a> + 'static, +{ callback_guard!(); let value = value as *const gobject_ffi::GValue; let func = func as *const gobject_ffi::GValue; let func = gobject_ffi::g_value_get_boxed(func); #[cfg_attr(feature = "cargo-clippy", allow(transmute_ptr_to_ref))] - let func: &&(Fn(&glib::Value) -> bool + Send + Sync + 'static) = mem::transmute(func); + let func: &&(Fn(T) -> bool + Send + Sync + 'static) = mem::transmute(func); let value = &*(value as *const glib::Value); + let value = value.get::().unwrap(); if func(value) { 0 @@ -307,12 +346,10 @@ unsafe extern "C" fn filter_trampoline(value: gconstpointer, func: gconstpointer } } -unsafe extern "C" fn filter_boxed_ref(boxed: gpointer) -> gpointer { +unsafe extern "C" fn filter_boxed_ref(boxed: gpointer) -> gpointer { callback_guard!(); - let boxed = Arc::from_raw( - boxed as *const (Box bool + Send + Sync + 'static>), - ); + let boxed = Arc::from_raw(boxed as *const (Box bool + Send + Sync + 'static>)); let copy = boxed.clone(); // Forget it and keep it alive, we will still need it later @@ -321,15 +358,13 @@ unsafe extern "C" fn filter_boxed_ref(boxed: gpointer) -> gpointer { Arc::into_raw(copy) as gpointer } -unsafe extern "C" fn filter_boxed_unref(boxed: gpointer) { +unsafe extern "C" fn filter_boxed_unref(boxed: gpointer) { callback_guard!(); - let _ = Arc::from_raw( - boxed as *const (Box bool + Send + Sync + 'static>), - ); + let _ = Arc::from_raw(boxed as *const (Box bool + Send + Sync + 'static>)); } -unsafe extern "C" fn filter_boxed_get_type() -> glib_ffi::GType { +unsafe extern "C" fn filter_boxed_get_type() -> glib_ffi::GType { use std::sync::{Once, ONCE_INIT}; callback_guard!(); @@ -342,7 +377,11 @@ unsafe extern "C" fn filter_boxed_get_type() -> glib_ffi::GType { let mut idx = 0; loop { - let type_name = CString::new(format!("GstRsIteratorFilterBoxed-{}", idx)).unwrap(); + let type_name = CString::new(format!( + "GstRsIteratorFilterBoxed-{}-{}", + T::static_type().name(), + idx + )).unwrap(); if gobject_ffi::g_type_from_name(type_name.as_ptr()) == gobject_ffi::G_TYPE_INVALID { break type_name; @@ -353,20 +392,24 @@ unsafe extern "C" fn filter_boxed_get_type() -> glib_ffi::GType { TYPE = gobject_ffi::g_boxed_type_register_static( type_name.as_ptr(), - Some(filter_boxed_ref), - Some(filter_boxed_unref), + Some(filter_boxed_ref::), + Some(filter_boxed_unref::), ); }); TYPE } -unsafe extern "C" fn find_trampoline(value: gconstpointer, func: gconstpointer) -> i32 { +unsafe extern "C" fn find_trampoline(value: gconstpointer, func: gconstpointer) -> i32 +where + for<'a> T: FromValueOptional<'a> + 'static, +{ callback_guard!(); let value = value as *const gobject_ffi::GValue; - let func = func as *const &mut (FnMut(&glib::Value) -> bool); + let func = func as *const &mut (FnMut(T) -> bool); let value = &*(value as *const glib::Value); + let value = value.get::().unwrap(); if (*func)(value) { 0 @@ -375,24 +418,32 @@ unsafe extern "C" fn find_trampoline(value: gconstpointer, func: gconstpointer) } } -unsafe extern "C" fn foreach_trampoline(value: *const gobject_ffi::GValue, func: gpointer) { +unsafe extern "C" fn foreach_trampoline(value: *const gobject_ffi::GValue, func: gpointer) +where + for<'a> T: FromValueOptional<'a> + 'static, +{ callback_guard!(); - let func = func as *const &mut (FnMut(&glib::Value)); + let func = func as *const &mut (FnMut(T)); let value = &*(value as *const glib::Value); + let value = value.get::().unwrap(); (*func)(value); } -unsafe extern "C" fn fold_trampoline( +unsafe extern "C" fn fold_trampoline( value: *const gobject_ffi::GValue, ret: *mut gobject_ffi::GValue, func: gpointer, -) -> glib_ffi::gboolean { +) -> glib_ffi::gboolean +where + for<'a> T: FromValueOptional<'a> + 'static, +{ callback_guard!(); - let func = func as *const &mut (FnMut(T, &glib::Value) -> Result); + let func = func as *const &mut (FnMut(U, T) -> Result); let value = &*(value as *const glib::Value); + let value = value.get::().unwrap(); - let accum = &mut *(gobject_ffi::g_value_get_pointer(ret) as *mut Option); + let accum = &mut *(gobject_ffi::g_value_get_pointer(ret) as *mut Option); match (*func)(accum.take().unwrap(), value) { Ok(next_accum) => { @@ -406,6 +457,145 @@ unsafe extern "C" fn fold_trampoline( } } +impl Clone for Iterator { + fn clone(&self) -> Self { + unsafe { from_glib_full(ffi::gst_iterator_copy(self.to_glib_none().0)) } + } +} + +impl Drop for Iterator { + fn drop(&mut self) { + if !self.borrowed { + unsafe { + ffi::gst_iterator_free(self.iter); + } + } + } +} + +impl glib::types::StaticType for Iterator { + fn static_type() -> glib::types::Type { + unsafe { glib::translate::from_glib(ffi::gst_iterator_get_type()) } + } +} + +#[doc(hidden)] +impl<'a, T: StaticType> glib::value::FromValueOptional<'a> for Iterator { + unsafe fn from_value_optional(value: &glib::Value) -> Option { + Option::>::from_glib_none( + gobject_ffi::g_value_get_boxed(value.to_glib_none().0) as *mut ffi::GstIterator, + ) + } +} + +#[doc(hidden)] +impl glib::value::SetValue for Iterator { + unsafe fn set_value(value: &mut glib::Value, this: &Self) { + gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + glib::translate::ToGlibPtr::<*const ffi::GstIterator>::to_glib_none(this).0 as + glib_ffi::gpointer, + ) + } +} + +#[doc(hidden)] +impl glib::value::SetValueOptional for Iterator { + unsafe fn set_value_optional(value: &mut glib::Value, this: Option<&Self>) { + gobject_ffi::g_value_set_boxed( + value.to_glib_none_mut().0, + glib::translate::ToGlibPtr::<*const ffi::GstIterator>::to_glib_none(&this).0 as + glib_ffi::gpointer, + ) + } +} + +#[doc(hidden)] +impl glib::translate::GlibPtrDefault for Iterator { + type GlibType = *mut ffi::GstIterator; +} + +#[doc(hidden)] +impl<'a, T: 'static> glib::translate::ToGlibPtr<'a, *const ffi::GstIterator> for Iterator { + type Storage = &'a Iterator; + + fn to_glib_none(&'a self) -> glib::translate::Stash<'a, *const ffi::GstIterator, Self> { + glib::translate::Stash(self.iter, self) + } + + fn to_glib_full(&self) -> *const ffi::GstIterator { + unimplemented!() + } +} + +#[doc(hidden)] +impl<'a, T: 'static> glib::translate::ToGlibPtrMut<'a, *mut ffi::GstIterator> for Iterator { + type Storage = &'a mut Iterator; + + #[inline] + fn to_glib_none_mut( + &'a mut self, + ) -> glib::translate::StashMut<'a, *mut ffi::GstIterator, Self> { + glib::translate::StashMut(self.iter, self) + } +} + +#[doc(hidden)] +impl glib::translate::FromGlibPtrNone<*const ffi::GstIterator> for Iterator { + #[inline] + unsafe fn from_glib_none(ptr: *const ffi::GstIterator) -> Self { + assert_ne!( + gobject_ffi::g_type_is_a((*ptr).type_, T::static_type().to_glib()), + glib_ffi::GFALSE + ); + from_glib_full(ffi::gst_iterator_copy(ptr)) + } +} + +#[doc(hidden)] +impl glib::translate::FromGlibPtrNone<*mut ffi::GstIterator> for Iterator { + #[inline] + unsafe fn from_glib_none(ptr: *mut ffi::GstIterator) -> Self { + assert_ne!( + gobject_ffi::g_type_is_a((*ptr).type_, T::static_type().to_glib()), + glib_ffi::GFALSE + ); + from_glib_full(ffi::gst_iterator_copy(ptr)) + } +} + +#[doc(hidden)] +impl glib::translate::FromGlibPtrBorrow<*mut ffi::GstIterator> for Iterator { + #[inline] + unsafe fn from_glib_borrow(ptr: *mut ffi::GstIterator) -> Self { + assert_ne!( + gobject_ffi::g_type_is_a((*ptr).type_, T::static_type().to_glib()), + glib_ffi::GFALSE + ); + Self { + iter: ptr, + borrowed: true, + phantom: PhantomData, + } + } +} + +#[doc(hidden)] +impl glib::translate::FromGlibPtrFull<*mut ffi::GstIterator> for Iterator { + #[inline] + unsafe fn from_glib_full(ptr: *mut ffi::GstIterator) -> Self { + assert_ne!( + gobject_ffi::g_type_is_a((*ptr).type_, T::static_type().to_glib()), + glib_ffi::GFALSE + ); + Self { + iter: ptr, + borrowed: false, + phantom: PhantomData, + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -417,16 +607,16 @@ mod tests { let vec = vec![1i32, 2, 3]; let mut it = Iterator::from_vec(vec); let val = it.next().unwrap(); - assert_eq!(val.unwrap().get::().unwrap(), 1); + assert_eq!(val, Ok(1)); let val = it.next().unwrap(); - assert_eq!(val.unwrap().get::().unwrap(), 2); + assert_eq!(val, Ok(2)); let val = it.next().unwrap(); - assert_eq!(val.unwrap().get::().unwrap(), 3); + assert_eq!(val, Ok(3)); assert!(it.next().is_none()); let vec = vec![1i32, 2, 3]; let it = Iterator::from_vec(vec); - let vals: Vec<_> = it.map(|v| v.unwrap().get::().unwrap()).collect(); + let vals: Vec<_> = it.map(|v| v.unwrap()).collect(); assert_eq!(vals, [1, 2, 3]); let vec = vec![1i32, 2, 3]; @@ -434,7 +624,7 @@ mod tests { let mut vals = Vec::new(); while let Some(res) = it.next() { match res { - Ok(v) => vals.push(v.get::().unwrap()), + Ok(v) => vals.push(v), _ => unreachable!(), } } @@ -444,7 +634,7 @@ mod tests { let it = Iterator::from_vec(vec); let mut vals = Vec::new(); for v in it { - vals.push(v.unwrap().get::().unwrap()); + vals.push(v.unwrap()); } assert_eq!(vals, [1, 2, 3]); } @@ -454,8 +644,8 @@ mod tests { ::init().unwrap(); let vec = vec![1i32, 2, 3]; - let it = Iterator::from_vec(vec).filter(|val| val.get::().unwrap() % 2 == 1); - let vals: Vec<_> = it.map(|v| v.unwrap().get::().unwrap()).collect(); + let it = Iterator::from_vec(vec).filter(|val| val % 2 == 1); + let vals: Vec<_> = it.map(|v| v.unwrap()).collect(); assert_eq!(vals, [1, 3]); } @@ -465,14 +655,13 @@ mod tests { // Our find let vec = vec![1i32, 2, 3]; - let val = Iterator::from_vec(vec).find_simple(|val| val.get::().unwrap() == 2); - assert_eq!(val.unwrap().get::().unwrap(), 2); + let val = Iterator::from_vec(vec).find_simple(|val| val == 2); + assert_eq!(val.unwrap(), 2); // Find from std::iter::Iterator let vec = vec![1i32, 2, 3]; - let val = - Iterator::from_vec(vec).find(|val| val.as_ref().unwrap().get::().unwrap() == 2); - assert_eq!(val.unwrap().unwrap().get::().unwrap(), 2); + let val = Iterator::from_vec(vec).find(|val| val.unwrap() == 2); + assert_eq!(val.unwrap(), Ok(2)); } #[test] @@ -481,7 +670,7 @@ mod tests { let vec = vec![1i32, 2, 3]; let mut sum = 0; - let res = Iterator::from_vec(vec).foreach(|val| sum += val.get::().unwrap()); + let res = Iterator::from_vec(vec).foreach(|val| sum += val); assert_eq!(res, Ok(())); assert_eq!(sum, 6); } @@ -493,7 +682,7 @@ mod tests { // Our fold let vec = vec![1i32, 2, 3]; let res = Iterator::from_vec(vec).fold_with_early_exit(0, |mut sum, val| { - sum += val.get::().unwrap(); + sum += val; Ok(sum) }); assert_eq!(res.unwrap(), 6); @@ -501,7 +690,7 @@ mod tests { // Fold from std::iter::Iterator let vec = vec![1i32, 2, 3]; let res = Iterator::from_vec(vec).fold(0, |mut sum, val| { - sum += val.unwrap().get::().unwrap(); + sum += val.unwrap(); sum }); assert_eq!(res, 6); diff --git a/gstreamer/src/pad.rs b/gstreamer/src/pad.rs index c5b53c513..4557df457 100644 --- a/gstreamer/src/pad.rs +++ b/gstreamer/src/pad.rs @@ -147,7 +147,7 @@ pub trait PadExtManual { fn set_iterate_internal_links_function(&self, func: F) where - F: Fn(&Pad, &::Object) -> ::Iterator + Send + Sync + 'static; + F: Fn(&Pad, &::Object) -> ::Iterator + Send + Sync + 'static; fn set_link_function(&self, func: F) where @@ -473,11 +473,11 @@ impl> PadExtManual for O { fn set_iterate_internal_links_function(&self, func: F) where - F: Fn(&Pad, &::Object) -> ::Iterator + Send + Sync + 'static, + F: Fn(&Pad, &::Object) -> ::Iterator + Send + Sync + 'static, { unsafe { let func_box: Box< - Fn(&Pad, &::Object) -> ::Iterator + Send + Sync + 'static, + Fn(&Pad, &::Object) -> ::Iterator + Send + Sync + 'static, > = Box::new(func); ffi::gst_pad_set_iterate_internal_links_function_full( self.to_glib_none().0, @@ -755,7 +755,7 @@ unsafe extern "C" fn trampoline_iterate_internal_links_function( ) -> *mut ffi::GstIterator { let _guard = CallbackGuard::new(); #[cfg_attr(feature = "cargo-clippy", allow(transmute_ptr_to_ref))] - let func: &&(Fn(&Pad, &::Object) -> ::Iterator + Send + Sync + 'static) = + let func: &&(Fn(&Pad, &::Object) -> ::Iterator + Send + Sync + 'static) = transmute((*pad).iterintlinkdata); // Steal the iterator and return it diff --git a/gstreamer/src/proxy_pad.rs b/gstreamer/src/proxy_pad.rs index 04d3f8481..b7dbaa1ce 100644 --- a/gstreamer/src/proxy_pad.rs +++ b/gstreamer/src/proxy_pad.rs @@ -77,4 +77,13 @@ impl ProxyPad { } } } + + pub fn iterate_internal_links_default<'a, P: IsA, Q: IsA + 'a, R: Into>>(pad: &P, parent: R) -> Option<::Iterator> { + skip_assert_initialized!(); + let parent = parent.into(); + let parent = parent.to_glib_none(); + unsafe { + from_glib_full(ffi::gst_proxy_pad_iterate_internal_links_default(pad.to_glib_none().0, parent.0)) + } + } } diff --git a/gstreamer/src/segment.rs b/gstreamer/src/segment.rs index 385503df4..4b10ab7cb 100644 --- a/gstreamer/src/segment.rs +++ b/gstreamer/src/segment.rs @@ -392,6 +392,14 @@ impl<'a> glib::translate::ToGlibPtrMut<'a, *mut ffi::GstSegment> for Segment { } } +#[doc(hidden)] +impl glib::translate::FromGlibPtrNone<*const ffi::GstSegment> for Segment { + #[inline] + unsafe fn from_glib_none(ptr: *const ffi::GstSegment) -> Self { + Segment(ptr::read(ptr)) + } +} + #[doc(hidden)] impl glib::translate::FromGlibPtrNone<*mut ffi::GstSegment> for Segment { #[inline] @@ -400,6 +408,14 @@ impl glib::translate::FromGlibPtrNone<*mut ffi::GstSegment> for Segment { } } +#[doc(hidden)] +impl glib::translate::FromGlibPtrBorrow<*mut ffi::GstSegment> for Segment { + #[inline] + unsafe fn from_glib_borrow(ptr: *mut ffi::GstSegment) -> Self { + Segment(ptr::read(ptr)) + } +} + #[doc(hidden)] impl glib::translate::FromGlibPtrFull<*mut ffi::GstSegment> for Segment { #[inline]