我有一个从WASM-Bindgen "canvas" example派生出来的Rust程序。我尝试在Canvas
元素的每个JavaScript onmousemove
事件上调用一些Rust代码。我的代码目前成功地创建了DOM事件(看起来是这样)。但是,每次触发事件时,Firefox开发人员版开发人员工具的控制台都会显示一个错误:
Uncaught Error: closure invoked recursively or destroyed already
下面是我的部分代码:
use std::f64;
use std::sync;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
mod canvas_manager;
use canvas_manager::CanvasManager;
#[wasm_bindgen(start)]
pub fn start() {
let document = web_sys::window().unwrap().document().unwrap();
let canvas = document.get_element_by_id("canvas").unwrap();
let canvas: web_sys::HtmlCanvasElement = canvas
.dyn_into::<web_sys::HtmlCanvasElement>()
.map_err(|_| ())
.unwrap();
let manager = CanvasManager::new(canvas, 480, 480);
manager.fill_rect_with_color(210, 12, 60, 6, "#444");
manager.fill_rect_with_color(210, 462, 60, 6, "#444");
manager.fill_rect_with_color(236, 236, 8, 8, "#999");
manager.clear_canvas();
let xPos= sync::Arc::from(sync::Mutex::new(Box::new(0f64)));
let xPosCloned = xPos.clone();
let a = Closure::wrap(Box::new(move || {
let mut xPosBox = xPosCloned.lock().unwrap();
**xPosBox += 1f64;
//web_sys::console::log_1(&JsValue::from_f64(2.5f64));
}) as Box<dyn FnMut()>);
manager.canvas.set_onmousemove(Some(a.as_ref().unchecked_ref()));
}
发布于 2020-08-29 07:20:42
在提供的代码中,将在start()
的末尾删除a
。
你可以通过a.forget()
解决这个问题,但是你会引入内存泄漏。
let a = Closure::wrap(Box::new(move || {
let mut xPosBox = xPosCloned.lock().unwrap();
**xPosBox += 1f64;
//web_sys::console::log_1(&JsValue::from_f64(2.5f64));
}) as Box<dyn FnMut()>);
manager.canvas.set_onmousemove(Some(a.as_ref().unchecked_ref()));
a.forget();
请看一下如何避免内存泄漏的好answer。
https://stackoverflow.com/questions/63640557
复制相似问题