问题描述
我有一个WASM-Bindgen "canvas" example分叉的Rust程序。我试图在onmousemove
元素的每个JavaScript Canvas
事件上调用一些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,"#444");
manager.fill_rect_with_color(236,236,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()));
}
解决方法
所提供的代码a
将在start()
的末尾删除。
您可以通过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如何避免内存泄漏。