gstreamer/promise: Add Future constructor for Promise

This returns a tuple that basically works like a oneshot channel: the
Promise acts as the "sender" and once the promise resolves the
"receiver" contains the result.
This commit is contained in:
Sebastian Dröge 2020-02-09 19:07:18 +02:00
parent 80c93dfddb
commit cddccf9502
2 changed files with 32 additions and 2 deletions

View file

@ -155,9 +155,9 @@ mod static_pad_template;
pub use static_pad_template::*; pub use static_pad_template::*;
#[cfg(any(feature = "v1_14", feature = "dox"))] #[cfg(any(feature = "v1_14", feature = "dox"))]
mod promise; pub mod promise;
#[cfg(any(feature = "v1_14", feature = "dox"))] #[cfg(any(feature = "v1_14", feature = "dox"))]
pub use promise::*; pub use promise::{Promise, PromiseError};
pub mod bus; pub mod bus;
mod element; mod element;

View file

@ -13,6 +13,9 @@ use PromiseResult;
use Structure; use Structure;
use StructureRef; use StructureRef;
use std::pin::Pin;
use std::task::{Context, Poll};
glib_wrapper! { glib_wrapper! {
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Promise(Shared<gst_sys::GstPromise>); pub struct Promise(Shared<gst_sys::GstPromise>);
@ -86,6 +89,18 @@ impl Promise {
} }
} }
pub fn new_future() -> (Self, PromiseFuture) {
use futures_channel::oneshot;
let (sender, receiver) = oneshot::channel();
let promise = Self::new_with_change_func(move |res| {
let _ = sender.send(res.map(|s| s.to_owned()));
});
(promise, PromiseFuture(receiver))
}
pub fn expire(&self) { pub fn expire(&self) {
unsafe { unsafe {
gst_sys::gst_promise_expire(self.to_glib_none().0); gst_sys::gst_promise_expire(self.to_glib_none().0);
@ -129,6 +144,21 @@ impl Default for Promise {
unsafe impl Send for Promise {} unsafe impl Send for Promise {}
unsafe impl Sync for Promise {} unsafe impl Sync for Promise {}
#[derive(Debug)]
pub struct PromiseFuture(futures_channel::oneshot::Receiver<Result<Structure, PromiseError>>);
impl std::future::Future for PromiseFuture {
type Output = Result<Structure, PromiseError>;
fn poll(mut self: Pin<&mut Self>, context: &mut Context) -> Poll<Self::Output> {
match Pin::new(&mut self.0).poll(context) {
Poll::Ready(Err(_)) => panic!("Sender dropped before callback was called"),
Poll::Ready(Ok(res)) => Poll::Ready(res),
Poll::Pending => Poll::Pending,
}
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;