我的 rust 程序正在管理 2d html canvas 上下文的内存,我试图达到 ~60fps。我可以很容易地计算出每帧之间的增量,结果大约是大约 5 毫秒。
我不清楚如何让我的 Rust webassembly 程序在剩余的 11 毫秒内进入睡眠状态。一种选择是让 JavaScript 在每个上调用 RustrequestAnimationFrame并将其用作驱动程序,但我很想尽可能将其全部保留在 Rust 中。
setTimeout(renderNext, 11)在编译到 wasm 目标时,我正在有效地寻找与 JavaScript 等效的 Rust 。
asynchronous settimeout rust requestanimationframe wasm-bindgen
假设我有一个用 Rust 编写的程序和另一个用 C++ 编写的程序。鉴于它们都被编译为 Wasm,我可以以某种方式从另一个程序中调用一个函数吗?
I'm using wasm_bindgen built with wasm-pack. I have a Rust function I expose to JS:
#[wasm_bindgen]
pub async fn validate_registration_token(backend_api_domain: String, token: String) -> Result<JsValue, JsValue> {
console::log_1(&"backend_api_domain=".clone().into());
console::log_1(&backend_api_domain.clone().into());
console::log_1(&"token=".clone().into());
console::log_1(&backend_api_domain.clone().into());
let api_endpoint_get_guest_info = format!(
"{backend_api_domain}/weddings/{token}/guests/registration/{registration_token}",
backend_api_domain = backend_api_domain.clone(),
token = token.clone(),
registration_token = registration_token.clone()
);
console::log_1(&api_endpoint_get_guest_info.clone().into());
let res = reqwest::Client::new()
.get(&api_endpoint_get_guest_info)
.send()
.await
.unwrap();
let text = res.text().await.unwrap();
let promise = js_sys::Promise::resolve(&true.into());
let result = wasm_bindgen_futures::JsFuture::from(promise).await.unwrap();
Ok(result)
}
Run Code Online (Sandbox Code Playgroud)
In HTML / JavaScript, I call the Rust function:
<button
type="button" …Run Code Online (Sandbox Code Playgroud) 我正在尝试调整生命游戏教程alert以从 Rust调用用户定义的 JS(而不是):
索引.js:
import * as wasm from "testing-wasm";
export const jsfunc = () => {
console.log("jsfunc called");
};
// Call Rust from JS. This function will call `jsfunc`, declared above.
wasm.rustfunc();
Run Code Online (Sandbox Code Playgroud)
库.rs:
mod utils;
use wasm_bindgen::prelude::*;
// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
// allocator.
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
#[wasm_bindgen(module = "/www/index.js")]
extern "C" {
fn jsfunc();
}
#[wasm_bindgen]
pub fn rustfunc() {
// call …Run Code Online (Sandbox Code Playgroud) javascript circular-dependency rust webassembly wasm-bindgen
尝试编译以下rust代码以wasm使其与现有js兼容运行。尝试从函数返回哈希映射值。
库文件
use wasm_bindgen::prelude::*;
use std::collections::HashMap;
#[wasm_bindgen]
pub fn get_transformed_filters()-> HashMap<i32, i32> {
let mut hm = HashMap::new();
for i in 1..9990000 {
hm.insert(i + i, i * i);
}
return hm
}
Run Code Online (Sandbox Code Playgroud)
运行命令后控制台错误wasm-pack build
[INFO]: Checking for the Wasm target...
[INFO]: Compiling to Wasm...
Compiling hello-wasm v0.1.0 (/Users/mfe/ui/rustService/test-wasm)
error[E0277]: the trait bound `HashMap<i32, i32>: IntoWasmAbi` is not satisfied
--> src/lib.rs:15:1
|
15 | #[wasm_bindgen]
| ^^^^^^^^^^^^^^^ the trait `IntoWasmAbi` is not implemented for `HashMap<i32, …Run Code Online (Sandbox Code Playgroud) 我正在尝试访问通过输入字段上传的文件内容的迭代器。
我可以通过 web-sys 将 JS 文件传递到 Wasm 中,但我一生都无法弄清楚如何访问 Rust 中传递的文件的长度和名称之外的任何内容。
我想我可以将整个文件作为 ByteArray 传递到 Wasm 中并对其进行迭代,但最好我想直接迭代文件内容而不进行复制,因为文件本身会很大(~1 GB)。
我在 Mozilla JS 文档中发现,我应该能够访问底层文件 blob,通过该.stream()方法从中获取 ReadableStream,并从中获取应该能够迭代的 Reader。但在 web-sys 中,.getReader()ReadableStream 的方法返回一个简单的 JSValue,我无法用它做任何有用的事情。
我是否在这里遗漏了一些东西,或者这个功能只是在网络系统中丢失了,还是有其他方法可以做到这一点?也许在 JS 中创建迭代器并将其传递给 Rust?
WASM我正在使用该框架编写前端seed。
我想用单元测试来测试我的模块之一,但我无法让它们来测试WASM代码。这是我的测试套件:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn check_non_wasm() {
assert_eq!("test", "test");
}
#[test]
fn check_home() {
assert_eq!(Urls::new().home().to_string(), "/");
}
}
Run Code Online (Sandbox Code Playgroud)
第一个测试通过了,因为没有使用任何与WASM. 另一个测试失败并出现以下错误:
thread 'urls::tests::check_home' panicked at 'cannot call wasm-bindgen imported functions on non-wasm targets'
Run Code Online (Sandbox Code Playgroud)
如果我运行cargo make test --chrome它甚至看不到这些测试。
我尝试运行cargo test --target wasm32-unknown-unknown,但失败并出现以下错误:
could not execute process `C:\Users\djenty\w\frontend\target\wasm32-unknown-unknown\debug\deps\w_frontend-2b6de747c6501f70.wasm` (never executed)
Run Code Online (Sandbox Code Playgroud)
rustup显示目标已安装:
installed targets for active toolchain
--------------------------------------
wasm32-unknown-unknown
x86_64-pc-windows-msvc
active toolchain
----------------
stable-x86_64-pc-windows-msvc (default)
rustc 1.54.0 …Run Code Online (Sandbox Code Playgroud) 让我们考虑一个示例导入对象,如下所示:
const importObject = {
exampleAsyncImportFunction: async () => fs.readFile("./someExampleFile.txt", "utf-8") // returns Promise<String>
};
Run Code Online (Sandbox Code Playgroud)
我想在我的 Rust 编写的 WASM 模块中使用它,类似于:
#[wasm_bindgen]
extern "C" {
pub async fn exampleAsyncImportFunction() -> JsValue; // Importing the JS-Function
}
#[wasm_bindgen]
pub async fn exampleExportFunction() -> Result<JsValue, JsValue> {
let theJSPromise = exampleAsyncImportFunction(); // Call the async import function
let promiseResult = theJSPromise.await; // Execute the async import function
// Do sth with the result
OK(JsValue::UNDEFINED)
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这会导致无法访问的错误。有趣的是,当 JavaScript 函数返回一个字符串时,它确实有效,如下所示:
const importObject = {
exampleAsyncImportFunction: …Run Code Online (Sandbox Code Playgroud) 因此,我使用带有 +atomic 标志的 wasm/rust 时内存不足,想检查实际可用的内存量。这是我的粗略的最小工作示例,它在向量发生恐慌之前记录其内存:
索引.js
import init from './pkg/test1.js';
import * as wasm_test1 from './pkg/test1.js';
async function run() {
await init();
let newDiv = document.createElement("div");
let btn = document.createElement("button");
btn.innerHTML = "Max out the memory now and panic!";
document.body.appendChild(btn);
btn.onclick = function () {
wasm_test1.fill_memory();
};
}
run();
Run Code Online (Sandbox Code Playgroud)
库文件
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
#[wasm_bindgen]
pub fn fill_memory() {
let mut v = Vec::new();
for i in 1..1000000000 {
v.push(0);
if …Run Code Online (Sandbox Code Playgroud) js_sysPromise通过函数公开 JavaScript pub fn new(cb: &mut dyn FnMut(Function, Function)) -> Promise;。根据我对MDN 文档的阅读,没有任何内容表明执行器函数将被多次调用,但js_sys将其公开FnMut为FnOnce.
因此,我无法专注于简单的任务,例如将来通过通道向自己发送消息。理想情况下,sender通道的一半将被移入封闭件中并Promise::new接受FnOnce.
async func send_to_future_self() {
use std::sync::mpsc::{Sender, Receiver, channel};
let (sender, receiver) = channel().split();
// Schedule sending a message in the future
// Option A: Move `sender` --> The closure becomes `FnOnce` because it consumes `sender`
// Option B: Reference `sender` --> Then the borrow outlives `sender`'s lifetime
let mut sleep_100 …Run Code Online (Sandbox Code Playgroud) rust ×10
wasm-bindgen ×10
webassembly ×7
rust-wasm ×2
async-await ×1
asynchronous ×1
c++ ×1
future ×1
javascript ×1
node.js ×1
promise ×1
rayon ×1
rust-cargo ×1
settimeout ×1
unit-testing ×1
wasm-pack ×1