我正在尝试编写一个在浏览器中运行的简单游戏,并且考虑到浏览器,rust和wasm-bindgen所施加的限制组合,我很难对游戏循环进行建模.
浏览器中的典型游戏循环遵循以下一般模式:
function mainLoop() {
update();
draw();
requestAnimationFrame(mainLoop);
}
Run Code Online (Sandbox Code Playgroud)
如果我要在rust/wasm-bindgen中建模这个确切的模式,它看起来像这样:
let main_loop = Closure::wrap(Box::new(move || {
update();
draw();
window.request_animation_frame(main_loop.as_ref().unchecked_ref()); // Not legal
}) as Box<FnMut()>);
Run Code Online (Sandbox Code Playgroud)
与javascript不同,我无法main_loop从内部引用,因此这不起作用.
有人建议的另一种方法是遵循生命游戏例子中说明的模式.在高级别,它涉及导出包含游戏状态的类型,并包括可以在javascript游戏循环中调用的公共tick()和render()函数.这对我不起作用,因为我的游戏状态需要生命周期参数,因为它实际上只包含规格 World和Dispatcher结构,后者具有生命周期参数.最终,这意味着我无法使用它导出它#[wasm_bindgen].
我很难找到解决这些限制的方法,并且正在寻找建议.
我正在构建一个 Chrome 扩展程序,并选择使用一些 WebAssembly 功能。我使用 wasm-pack 来构建源代码,因为它提供了--target web降低插入 Wasm 函数的复杂性的方法。在 Rust 和 JS 之间传递整数值可以无缝地工作,但我似乎无法将字符串传递给 Rust,反之亦然。
这是我正在处理的内容:
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
#[wasm_bindgen(js_namespace = console)]
fn log(x: &str);
}
#[wasm_bindgen]
pub extern "C" fn add_two(x: i32) -> i32 {
x + 2
}
#[wasm_bindgen]
pub fn hello(name: &str) {
log("Hello") // <-- passing a '&str' directly works. I can see it in the browser.
log(name) // <-- does not seem to work. There is no output
alert(&format!("Hello …Run Code Online (Sandbox Code Playgroud) 我编写了一些 Rust 代码并使用 wasm-pack 对其进行了编译。free()我在生成的 .d.ts 文件中注意到这些方法:
export class PdfDoc {
free(): void;
...
}
Run Code Online (Sandbox Code Playgroud)
PdfDoc拥有大量内存,高达 1GB,因此当 javascript 代码使用完这些内存时,正确释放所有内存以供重用非常重要。
问题:
free()方法?我搜索了“wasm-pack free method”,但这些搜索词组合没有找到任何有用的东西。
我的第一个Rust生产的WASM正在产生以下错误,我不知道如何进行调试。
wasm-000650c2-23:340 Uncaught RuntimeError: memory access out of bounds
at dlmalloc::dlmalloc::Dlmalloc::free::h36961b6fbcc40c05 (wasm-function[23]:670)
at __rdl_dealloc (wasm-function[367]:8)
at __rust_dealloc (wasm-function[360]:7)
at alloc::alloc::dealloc::h90df92e1f727e726 (wasm-function[146]:100)
at <alloc::alloc::Global as core::alloc::Alloc>::dealloc::h7f22ab187c7f5835 (wasm-function[194]:84)
at <alloc::raw_vec::RawVec<T, A>>::dealloc_buffer::hdce29184552be976 (wasm-function[82]:231)
at <alloc::raw_vec::RawVec<T, A> as core::ops::drop::Drop>::drop::h3910dccc175e44e6 (wasm-function[269]:38)
at core::ptr::real_drop_in_place::hd26be2408c00ce9d (wasm-function[267]:38)
at core::ptr::real_drop_in_place::h6acb013dbd13c114 (wasm-function[241]:50)
at core::ptr::real_drop_in_place::hb270ba635548ab74 (wasm-function[69]:192)
Run Code Online (Sandbox Code Playgroud)
上下文:从TypeScript自定义元素调用的最新Chrome,Rust wasm-bindgen代码,在影子DOM中的画布上运行。呈现到画布上的数据来自HTML5 AudioBuffer。所有rust变量都在本地范围内。
如果文档中仅出现一个实例,则Web组件可以正常工作,但是如果再出现其他实例,则如上所述将转储堆栈跟踪。该代码运行没有任何其他问题。
我知道Chrome中存在突出的内存错误-这是它们的外观吗,还是有经验的锈/毛病开发人员可以告诉我这是否异常?
js-sys = "0.3.19"
wasm-bindgen = "0.2.42"
wee_alloc = { version = "0.4.2", optional = true }
[dependencies.web-sys]
version = "0.3.4"
Run Code Online (Sandbox Code Playgroud)
rust代码很小,仅将AudioBuffer的两个通道呈现到提供的HTMLCanvasElement:
#[wasm_bindgen]
pub fn render(
canvas: web_sys::HtmlCanvasElement,
audio_buffer: &web_sys::AudioBuffer,
stroke_style: …Run Code Online (Sandbox Code Playgroud) 我正在使用 wasm bindgen 并且有以下功能:
#[wasm_bindgen]
pub fn obj(o: &JsValue){
console::log_1(o);
}
Run Code Online (Sandbox Code Playgroud)
在 js 中我调用这个函数obj({name: "john"});
并且它工作正常,但是当我尝试时它给出了指向的console::log_1(o.name);
错误unknown fieldname
我是网络组装新手。我想使用 canvas 和 来创建一个简单的贪吃蛇游戏wasm_bindgen。
我的生锈代码:
#[wasm_bindgen]
impl CanvasData {
pub fn index_to_coordinate(&self, index: usize) -> (usize, usize) {
(index % self.cell_count, index / self.cell_count)
}
}
Run Code Online (Sandbox Code Playgroud)
CanvasData是一个保存画布数据的结构体,cell_count属性为usizetype,代表方形画布上水平和垂直格子的数量。这里我把画布上所有的网格从左到右、从上到下看成一个一维数组。该方法的目的是将数组索引映射到x、y坐标。我想返回一个元组并在前端调用它,如下所示:
const [x, y] = canvasData.index_to_coordinate(100)
Run Code Online (Sandbox Code Playgroud)
然而,在构建过程中出现了错误。
构建脚本:
wasm-pack build -t web
Run Code Online (Sandbox Code Playgroud)
错误:
error[E0277]: the trait bound `(usize, usize): IntoWasmAbi` is not satisfied
[0] --> src\lib.rs:16:1
[0] |
[0] 16 | #[wasm_bindgen]
[0] | ^^^^^^^^^^^^^^^ the trait `IntoWasmAbi` is not implemented for `(usize, usize)`
[0] |
[0] …Run Code Online (Sandbox Code Playgroud) 嵌套的Vecs 似乎不适用于wasm-bindgen.那是对的吗?
我的目标是在Rust中使用生命游戏网格,我可以将其作为行返回,而不是Vec需要JavaScript处理索引的1D .我想到的两个解决方法是:
我不愿意使用其中任何一个,因为我希望这个库可以被JavaScript和本机Rust使用,而且我认为这两者在纯Rust的土地上都不会非常惯用.还有其他建议吗?
我正在使用 Rust 和 WebAssembly 操作像素数据,并且正在努力使用操作的像素创建新的 ImageData。
当我获取我的ImageData数据时,它返回一个Clamped<Vec<u8>>
fn get_buffer_image_data(&self) -> Clamped<Vec<u8>> {
let image_data = match self.buffer_ctx.get_image_data(0.0, 0.0, 640.0, 480.0) {
Ok(d) => d,
Err(_err) => panic!("failed to fetch buffer image data")
};
image_data.data()
}
Run Code Online (Sandbox Code Playgroud)
我在另一个函数中操作像素数据,然后尝试使用这些操作的像素创建新的 ImageData。问题是我只能用Clamped<&mut [u8]>创建新的 ImageData
fn create_image_data(&self, data: Clamped<Vec<u8>>) {
let imageData = ImageData::new_with_u8_clamped_array_and_sh(data, 640, 480);
}
Run Code Online (Sandbox Code Playgroud)
但是,我收到的错误是:
mismatched types
expected `&mut [u8]`, found struct `std::vec::Vec`
note: expected struct `wasm_bindgen::Clamped<&mut [u8]>`
found struct `wasm_bindgen::Clamped<std::vec::Vec<u8>>`
Run Code Online (Sandbox Code Playgroud)
我想我需要将一种类型转换为另一种类型。如何高效转换?我已经尝试这个有一段时间了,但我被困住了。我唯一的解决方案是将整个 Uint8ClampedArray 从我的 JS 发送到 wasm 。这是您可以使用的代码示例。请注意,如果您克隆此存储库,请查看分支problem …
如何在 WebAssembly 中使用 web-sys 创建带有 JSON 主体的 POST 请求?
下面这个例子展示了如何发出 GET 请求,我需要更改opts.method("GET"); 到opts.method("POST"); 但我如何将 JSON 主体传递给 reqeuest.
let mut opts = RequestInit::new();
opts.method("GET");
opts.credentials(web_sys::RequestCredentials::Include);
let request = Request::new_with_str_and_init(
"http://localhost:8080/api/v1/books",
&opts
).unwrap();
match web_sys::window() {
Some(window) => {
let _res = JsFuture::from(window.fetch_with_request(&request))
.await
.map(|err| web_sys::console::log_1(&format!("{:?}", err)
.into()));
},
None => web_sys::console::log_1(&format!("window is none").into()),
}
Run Code Online (Sandbox Code Playgroud) 关于closure.rs的注释非常好,但是我不能让它从WebAssembly库中返回一个闭包.
我有这样的功能:
#[wasm_bindgen]
pub fn start_game(
start_time: f64,
screen_width: f32,
screen_height: f32,
on_render: &js_sys::Function,
on_collision: &js_sys::Function,
) -> ClosureTypeHere {
// ...
}
Run Code Online (Sandbox Code Playgroud)
在该函数内部,我做了一个闭包,假设Closure::wrap是一个拼图,并从closure.rs复制):
let cb = Closure::wrap(Box::new(move |time| time * 4.2) as Box<FnMut(f64) -> f64>);
Run Code Online (Sandbox Code Playgroud)
如何从此回调start_game和应该返回什么ClosureTypeHere?
我们的想法是start_game创建本地可变对象 - 比如相机,并且JavaScript方应该能够调用Rust返回的函数来更新该相机.
rust ×10
wasm-bindgen ×10
webassembly ×8
wasm-pack ×3
frontend ×1
rust-cargo ×1
shadow-dom ×1
typescript ×1
web-sys ×1
yew ×1