iced_futures/backend/native/
tokio.rs

1//! A `tokio` backend.
2use futures::Future;
3
4/// A `tokio` executor.
5pub type Executor = tokio::runtime::Runtime;
6
7impl crate::Executor for Executor {
8    fn new() -> Result<Self, futures::io::Error> {
9        tokio::runtime::Runtime::new()
10    }
11
12    #[allow(clippy::let_underscore_future)]
13    fn spawn(&self, future: impl Future<Output = ()> + Send + 'static) {
14        let _ = tokio::runtime::Runtime::spawn(self, future);
15    }
16
17    fn enter<R>(&self, f: impl FnOnce() -> R) -> R {
18        let _guard = tokio::runtime::Runtime::enter(self);
19        f()
20    }
21}
22
23pub mod time {
24    //! Listen and react to time.
25    use crate::subscription::{self, Hasher, Subscription};
26
27    /// Returns a [`Subscription`] that produces messages at a set interval.
28    ///
29    /// The first message is produced after a `duration`, and then continues to
30    /// produce more messages every `duration` after that.
31    pub fn every(
32        duration: std::time::Duration,
33    ) -> Subscription<std::time::Instant> {
34        subscription::from_recipe(Every(duration))
35    }
36
37    #[derive(Debug)]
38    struct Every(std::time::Duration);
39
40    impl subscription::Recipe for Every {
41        type Output = std::time::Instant;
42
43        fn hash(&self, state: &mut Hasher) {
44            use std::hash::Hash;
45
46            std::any::TypeId::of::<Self>().hash(state);
47            self.0.hash(state);
48        }
49
50        fn stream(
51            self: Box<Self>,
52            _input: subscription::EventStream,
53        ) -> futures::stream::BoxStream<'static, Self::Output> {
54            use futures::stream::StreamExt;
55
56            let start = tokio::time::Instant::now() + self.0;
57
58            let mut interval = tokio::time::interval_at(start, self.0);
59            interval.set_missed_tick_behavior(
60                tokio::time::MissedTickBehavior::Skip,
61            );
62
63            let stream = {
64                futures::stream::unfold(interval, |mut interval| async move {
65                    Some((interval.tick().await, interval))
66                })
67            };
68
69            stream.map(tokio::time::Instant::into_std).boxed()
70        }
71    }
72}