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