Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement sleep and interval for Yew Platform #2784

Merged
merged 13 commits into from Jul 31, 2022
2 changes: 1 addition & 1 deletion packages/yew-router/tests/basename.rs
@@ -1,9 +1,9 @@
use std::time::Duration;

use gloo::timers::future::sleep;
use serde::{Deserialize, Serialize};
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
use yew::functional::function_component;
use yew::platform::time::sleep;
use yew::prelude::*;
use yew_router::prelude::*;

Expand Down
2 changes: 1 addition & 1 deletion packages/yew-router/tests/browser_router.rs
@@ -1,9 +1,9 @@
use std::time::Duration;

use gloo::timers::future::sleep;
use serde::{Deserialize, Serialize};
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
use yew::functional::function_component;
use yew::platform::time::sleep;
use yew::prelude::*;
use yew_router::prelude::*;

Expand Down
2 changes: 1 addition & 1 deletion packages/yew-router/tests/hash_router.rs
@@ -1,9 +1,9 @@
use std::time::Duration;

use gloo::timers::future::sleep;
use serde::{Deserialize, Serialize};
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
use yew::functional::function_component;
use yew::platform::time::sleep;
use yew::prelude::*;
use yew_router::prelude::*;

Expand Down
2 changes: 1 addition & 1 deletion packages/yew-router/tests/link.rs
@@ -1,9 +1,9 @@
use std::time::Duration;

use gloo::timers::future::sleep;
use serde::{Deserialize, Serialize};
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
use yew::functional::function_component;
use yew::platform::time::sleep;
use yew::prelude::*;
use yew_router::prelude::*;

Expand Down
8 changes: 4 additions & 4 deletions packages/yew/Cargo.toml
Expand Up @@ -18,14 +18,14 @@ rust-version = "1.60.0"

[dependencies]
console_error_panic_hook = "0.1"
gloo = "0.8"
gloo = { version = "0.8", features = ["futures"] }
indexmap = { version = "1", features = ["std"] }
js-sys = "0.3"
slab = "0.4"
wasm-bindgen = "0.2"
yew-macro = { version = "^0.19.0", path = "../yew-macro" }
thiserror = "1.0"
futures = { version = "0.3", optional = true }
futures = { version = "0.3", default-features = false, features = ["std"] }
html-escape = { version = "0.2.9", optional = true }
implicit-clone = { version = "0.3", features = ["map"] }
base64ct = { version = "1.5.0", features = ["std"], optional = true }
Expand Down Expand Up @@ -93,8 +93,8 @@ features = [
]

[features]
tokio = ["tokio/rt", "dep:num_cpus", "dep:tokio-util"]
ssr = ["dep:futures", "dep:html-escape", "dep:base64ct", "dep:bincode"]
tokio = ["tokio/rt", "tokio/time", "dep:num_cpus", "dep:tokio-util"]
ssr = ["dep:html-escape", "dep:base64ct", "dep:bincode"]
csr = []
hydration = ["csr", "dep:bincode"]
nightly = ["yew-macro/nightly"]
Expand Down
7 changes: 4 additions & 3 deletions packages/yew/src/platform/mod.rs
Expand Up @@ -46,15 +46,16 @@ use std::future::Future;
pub(crate) mod io;

pub mod sync;
pub mod time;

#[cfg(target_arch = "wasm32")]
#[path = "rt_wasm_bindgen.rs"]
#[path = "rt_wasm_bindgen/mod.rs"]
mod imp;
#[cfg(all(not(target_arch = "wasm32"), feature = "tokio"))]
#[path = "rt_tokio.rs"]
#[path = "rt_tokio/mod.rs"]
mod imp;
#[cfg(all(not(target_arch = "wasm32"), not(feature = "tokio")))]
#[path = "rt_none.rs"]
#[path = "rt_none/mod.rs"]
mod imp;

/// Spawns a task on current thread.
Expand Down
26 changes: 0 additions & 26 deletions packages/yew/src/platform/rt_none.rs

This file was deleted.

30 changes: 30 additions & 0 deletions packages/yew/src/platform/rt_none/mod.rs
@@ -0,0 +1,30 @@
use std::future::Future;

pub(crate) mod time;

static NO_RUNTIME_NOTICE: &str = r#"No runtime configured for this platform, \
features that requires a runtime can't be used. \
Either compile with `target_arch = "wasm32", or enable the `tokio` feature."#;

fn panic_no_runtime() -> ! {
panic!("{}", NO_RUNTIME_NOTICE);
}

#[inline(always)]
pub(super) fn spawn_local<F>(_f: F)
where
F: Future<Output = ()> + 'static,
{
panic_no_runtime();
}

#[cfg(feature = "ssr")]
pub(crate) async fn run_pinned<F, Fut>(_create_task: F) -> Fut::Output
where
F: FnOnce() -> Fut,
F: Send + 'static,
Fut: Future + 'static,
Fut::Output: Send + 'static,
{
panic_no_runtime();
}
13 changes: 13 additions & 0 deletions packages/yew/src/platform/rt_none/time.rs
@@ -0,0 +1,13 @@
use std::time::Duration;

use futures::stream::LocalBoxStream;

use super::panic_no_runtime;

pub(crate) async fn sleep(_dur: Duration) {
panic_no_runtime();
}

pub(crate) fn interval(_dur: Duration) -> LocalBoxStream<'static, ()> {
panic_no_runtime();
}
@@ -1,5 +1,7 @@
use std::future::Future;

pub(crate) mod time;

#[cfg(feature = "ssr")]
pub(super) async fn run_pinned<F, Fut>(create_task: F) -> Fut::Output
where
Expand Down
14 changes: 14 additions & 0 deletions packages/yew/src/platform/rt_tokio/time.rs
@@ -0,0 +1,14 @@
use std::future::Future;
use std::time::Duration;

use futures::stream::{Stream, StreamExt};
use tokio_stream::wrappers::IntervalStream;

#[inline(always)]
pub(crate) fn sleep(dur: Duration) -> impl Future<Output = ()> {
tokio::time::sleep(dur)
}

pub(crate) fn interval(dur: Duration) -> impl Stream<Item = ()> {
IntervalStream::new(tokio::time::interval(dur)).then(|_| async {})
}
@@ -1,6 +1,8 @@
#[cfg(feature = "ssr")]
use std::future::Future;

pub(crate) mod time;

pub(super) use wasm_bindgen_futures::spawn_local;

#[cfg(feature = "ssr")]
Expand Down
17 changes: 17 additions & 0 deletions packages/yew/src/platform/rt_wasm_bindgen/time.rs
@@ -0,0 +1,17 @@
use std::future::Future;
use std::time::Duration;

use futures::stream::Stream;
use wasm_bindgen::UnwrapThrowExt;

#[inline(always)]
pub(crate) fn sleep(dur: Duration) -> impl Future<Output = ()> {
gloo::timers::future::sleep(dur)
}

pub(crate) fn interval(dur: Duration) -> impl Stream<Item = ()> {
let millis = u32::try_from(dur.as_millis())
.expect_throw("failed to cast the duration into a u32 with Duration::as_millis.");

gloo::timers::future::IntervalStream::new(millis)
}
30 changes: 30 additions & 0 deletions packages/yew/src/platform/time.rs
@@ -0,0 +1,30 @@
//! Utilities for bridging time and tasks.

use std::future::Future;
use std::time::Duration;

use futures::stream::Stream;

use crate::platform::imp::time as imp;

/// Waits until duration has elapsed.
///
/// # Panics
///
/// On some platforms, if the prodvided duration cannot be converted to u32 in milliseconds, this
/// function will panic.
#[inline(always)]
pub fn sleep(dur: Duration) -> impl Future<Output = ()> {
imp::sleep(dur)
}

/// Creates a Stream that yields an item after every period has elapsed.
///
/// # Panics
///
/// On some platforms, if the prodvided period cannot be converted to u32 in milliseconds, this
/// function will panic.
#[inline(always)]
pub fn interval(period: Duration) -> impl Stream<Item = ()> {
imp::interval(period)
}
2 changes: 1 addition & 1 deletion packages/yew/src/virtual_dom/vsuspense.rs
Expand Up @@ -65,8 +65,8 @@ mod ssr_tests {

use tokio::task::{spawn_local, LocalSet};
use tokio::test;
use tokio::time::sleep;

use crate::platform::time::sleep;
use crate::prelude::*;
use crate::suspense::{Suspension, SuspensionResult};
use crate::ServerRenderer;
Expand Down
2 changes: 1 addition & 1 deletion packages/yew/tests/common/mod.rs
Expand Up @@ -15,5 +15,5 @@ pub fn obtain_result_by_id(id: &str) -> String {
}

pub fn output_element() -> web_sys::Element {
gloo_utils::document().get_element_by_id("output").unwrap()
gloo::utils::document().get_element_by_id("output").unwrap()
}
4 changes: 2 additions & 2 deletions packages/yew/tests/hydration.rs
Expand Up @@ -8,11 +8,11 @@ use std::time::Duration;
mod common;

use common::{obtain_result, obtain_result_by_id};
use gloo::timers::future::sleep;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::spawn_local;
use wasm_bindgen_test::*;
use web_sys::{HtmlElement, HtmlTextAreaElement};
use yew::platform::time::sleep;
use yew::prelude::*;
use yew::suspense::{use_future, Suspension, SuspensionResult};
use yew::{Renderer, ServerRenderer};
Expand Down Expand Up @@ -769,7 +769,7 @@ async fn hydration_suspense_no_flickering() {
#[hook]
pub fn use_suspend() -> SuspensionResult<()> {
use_future(|| async {
gloo::timers::future::sleep(std::time::Duration::from_millis(200)).await;
yew::platform::time::sleep(std::time::Duration::from_millis(200)).await;
})?;
Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion packages/yew/tests/layout.rs
Expand Up @@ -7,9 +7,9 @@ wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
use std::time::Duration;

use common::obtain_result;
use gloo::timers::future::sleep;
use wasm_bindgen_futures::spawn_local;
use wasm_bindgen_test::*;
use yew::platform::time::sleep;
use yew::prelude::*;

#[wasm_bindgen_test]
Expand Down
2 changes: 1 addition & 1 deletion packages/yew/tests/mod.rs
Expand Up @@ -5,8 +5,8 @@ mod common;
use std::time::Duration;

use common::obtain_result;
use gloo::timers::future::sleep;
use wasm_bindgen_test::*;
use yew::platform::time::sleep;
use yew::prelude::*;

wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
Expand Down