Refactor: Replace calling JS settimeout with Rust

web-sys and js-sys provides ways to use "settimeout" in pure Rust which
is used instead of calling into Javascript to do "settimeout".
This commit is contained in:
Stephen Seo 2022-03-23 16:56:25 +09:00
parent 20a8b6ade0
commit 839e9021fa
4 changed files with 20 additions and 21 deletions

View File

@ -1,3 +0,0 @@
export function async_sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}

View File

@ -1,15 +0,0 @@
use js_sys::Promise;
use wasm_bindgen::prelude::*;
use wasm_bindgen_futures::JsFuture;
#[wasm_bindgen(module = "/src/async_js_helper.js")]
extern "C" {
fn async_sleep(ms: u32) -> Promise;
}
pub async fn rust_async_sleep(ms: u32) -> Result<(), JsValue> {
let promise = async_sleep(ms);
let js_fut = JsFuture::from(promise);
js_fut.await?;
Ok(())
}

View File

@ -1,5 +1,4 @@
mod ai;
mod async_js_helper;
mod constants;
mod game_logic;
mod html_helper;

View File

@ -1,5 +1,4 @@
use crate::ai::{get_ai_choice, AIDifficulty};
use crate::async_js_helper;
use crate::constants::{COLS, INFO_TEXT_MAX_ITEMS, ROWS};
use crate::game_logic::{check_win_draw, WinType};
use crate::html_helper::{
@ -11,6 +10,10 @@ use crate::state::{BoardState, GameState, SharedState, Turn};
use std::cell::Cell;
use std::rc::Rc;
use js_sys::Promise;
use wasm_bindgen_futures::JsFuture;
use yew::prelude::*;
pub struct MainMenu {}
@ -790,7 +793,22 @@ impl Component for Wrapper {
WrapperMsg::AIChoice => {
// defer by 1 second
ctx.link().send_future(async {
async_js_helper::rust_async_sleep(1000).await.unwrap();
let promise = Promise::new(&mut |resolve: js_sys::Function, _reject| {
let window = web_sys::window();
if window.is_none() {
resolve.call0(&resolve).ok();
return;
}
let window = window.unwrap();
if window
.set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, 1000)
.is_err()
{
resolve.call0(&resolve).ok();
}
});
let js_fut = JsFuture::from(promise);
js_fut.await.ok();
WrapperMsg::AIChoiceImpl
});
}