Improving the cancelable_future API
This commit is contained in:
parent
4588ebf1f7
commit
b554c747c6
|
@ -5,3 +5,4 @@ authors = ["Pauan <pcxunlimited@gmail.com>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.1.18"
|
futures = "0.1.18"
|
||||||
|
discard = "1.0.3"
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
#![recursion_limit="128"]
|
#![recursion_limit="128"]
|
||||||
|
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
|
extern crate discard;
|
||||||
|
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use futures::{Async, Poll, task};
|
use futures::{Async, Poll, task};
|
||||||
use futures::future::{Future, IntoFuture};
|
use futures::future::{Future, IntoFuture};
|
||||||
use futures::stream::{Stream, ForEach};
|
use futures::stream::{Stream, ForEach};
|
||||||
|
use discard::{Discard, DiscardOnDrop};
|
||||||
|
|
||||||
|
|
||||||
// TODO add in Done to allow the Signal to end ?
|
// TODO add in Done to allow the Signal to end ?
|
||||||
|
@ -156,9 +158,8 @@ pub struct CancelableFutureHandle {
|
||||||
state: Weak<RefCell<CancelableFutureState>>,
|
state: Weak<RefCell<CancelableFutureState>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Cancel implementation
|
impl Discard for CancelableFutureHandle {
|
||||||
impl CancelableFutureHandle {
|
fn discard(self) {
|
||||||
pub fn cancel(&mut self) {
|
|
||||||
if let Some(state) = self.state.upgrade() {
|
if let Some(state) = self.state.upgrade() {
|
||||||
let mut borrow = state.borrow_mut();
|
let mut borrow = state.borrow_mut();
|
||||||
|
|
||||||
|
@ -175,13 +176,13 @@ impl CancelableFutureHandle {
|
||||||
|
|
||||||
pub struct CancelableFuture<A, B> {
|
pub struct CancelableFuture<A, B> {
|
||||||
state: Rc<RefCell<CancelableFutureState>>,
|
state: Rc<RefCell<CancelableFutureState>>,
|
||||||
future: A,
|
future: Option<A>,
|
||||||
when_cancelled: Option<B>,
|
when_cancelled: Option<B>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Future for CancelableFuture<A, B>
|
impl<A, B> Future for CancelableFuture<A, B>
|
||||||
where A: Future,
|
where A: Future,
|
||||||
B: FnOnce() -> A::Item {
|
B: FnOnce(A) -> A::Item {
|
||||||
|
|
||||||
type Item = A::Item;
|
type Item = A::Item;
|
||||||
type Error = A::Error;
|
type Error = A::Error;
|
||||||
|
@ -189,16 +190,20 @@ impl<A, B> Future for CancelableFuture<A, B>
|
||||||
// TODO should this inline ?
|
// TODO should this inline ?
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
let mut borrow = self.state.borrow_mut();
|
let borrow = self.state.borrow();
|
||||||
|
|
||||||
if borrow.is_cancelled {
|
if borrow.is_cancelled {
|
||||||
Ok(Async::Ready(self.when_cancelled.take().unwrap()()))
|
let future = self.future.take().unwrap();
|
||||||
|
let callback = self.when_cancelled.take().unwrap();
|
||||||
|
// TODO figure out how to call the callback immediately when discard is called
|
||||||
|
Ok(Async::Ready(callback(future)))
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// TODO does it need to drop borrow before calling poll ?
|
drop(borrow);
|
||||||
match self.future.poll() {
|
|
||||||
|
match self.future.as_mut().unwrap().poll() {
|
||||||
Ok(Async::NotReady) => {
|
Ok(Async::NotReady) => {
|
||||||
borrow.task = Some(task::current());
|
self.state.borrow_mut().task = Some(task::current());
|
||||||
Ok(Async::NotReady)
|
Ok(Async::NotReady)
|
||||||
},
|
},
|
||||||
a => a,
|
a => a,
|
||||||
|
@ -211,7 +216,7 @@ impl<A, B> Future for CancelableFuture<A, B>
|
||||||
// TODO figure out a more efficient way to implement this
|
// TODO figure out a more efficient way to implement this
|
||||||
// TODO this should be implemented in the futures crate
|
// TODO this should be implemented in the futures crate
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cancelable_future<A, B>(future: A, when_cancelled: B) -> (CancelableFutureHandle, CancelableFuture<A, B>)
|
pub fn cancelable_future<A, B>(future: A, when_cancelled: B) -> (DiscardOnDrop<CancelableFutureHandle>, CancelableFuture<A, B>)
|
||||||
where A: Future,
|
where A: Future,
|
||||||
B: FnOnce() -> A::Item {
|
B: FnOnce() -> A::Item {
|
||||||
|
|
||||||
|
@ -220,14 +225,13 @@ pub fn cancelable_future<A, B>(future: A, when_cancelled: B) -> (CancelableFutur
|
||||||
task: None,
|
task: None,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// TODO CancelOnDrop
|
let cancel_handle = DiscardOnDrop::new(CancelableFutureHandle {
|
||||||
let cancel_handle = CancelableFutureHandle {
|
|
||||||
state: Rc::downgrade(&state),
|
state: Rc::downgrade(&state),
|
||||||
};
|
});
|
||||||
|
|
||||||
let cancel_future = CancelableFuture {
|
let cancel_future = CancelableFuture {
|
||||||
state,
|
state,
|
||||||
future,
|
future: Some(future),
|
||||||
when_cancelled: Some(when_cancelled),
|
when_cancelled: Some(when_cancelled),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue