调试
在我们编写更多代码之前,我们需要一些在出现问题时使用的调试工具。
为Panic启用日志记录
我们的 wasm-pack-template 附带了 console_error_panic_hook crate 是一个可选的默认开启的依赖项,可以在 wasm-game-of-life/src/utils.rs 中看到已配置了。
我们需要做的就是在初始化函数或常用代码路径中安装 hooks。
我们可以在 wasm-game-of-life/src/lib.rs 中的,Universe::new 构造函数里面调用它:
pub fn new() -> Universe {utils::set_panic_hook();// ...}
加入日志到游戏中
运用 console.log 函数,是由 web-sys 添加一些记录日志,记录 Universe::tick 函数的每个 Cell。
首先,在 wasm-game-of-life/Cargo.toml 添加 web-sys 依赖项,并启用它的 “console” 功能:
[dependencies.web-sys]version = "0.3"features = ["console",]
为了代码更优雅,我们将把 console.log 函数包装成 println! 形式的宏:
extern crate web_sys;// 一个 macro(宏) 提供 `println!(..)`-形式 语法,给到 `console.log` 日志功能.macro_rules! log {( $( $t:tt )* ) => {web_sys::console::log_1(&format!( $( $t )* ).into());}}
现在,我们可以在 Rust 代码中,调用 log,开始 console.log 的信息记录。
例如,要记录每个单元(cell)的状态,实时邻居计数,以及下一个状态,我们可以修改 wasm-game-of-life/src/lib.rs 像这样:
diff --git a/src/lib.rs b/src/lib.rsindex f757641..a30e107 100755--- a/src/lib.rs+++ b/src/lib.rs@@ -123,6 +122,14 @@ impl Universe {let cell = self.cells[idx];let live_neighbors = self.live_neighbor_count(row, col);+ log!(+ "cell[{}, {}] is initially {:?} and has {} live neighbors",+ row,+ col,+ cell,+ live_neighbors+ );+let next_cell = match (cell, live_neighbors) {// Rule 1: Any live cell with fewer than two live neighbours// dies, as if caused by underpopulation.@@ -140,6 +147,8 @@ impl Universe {(otherwise, _) => otherwise,};+ log!(" it becomes {:?}", next_cell);+next[idx] = next_cell;}}
在每个 Tick 之间用调试器暂停
例如,我们可用调试器,在我们的 renderLoop 函数每次迭代时,暂停。
只需要在 universe.tick() 之上放置一个 JavaScript 的 debugger;声明 。
const renderLoop = () => {debugger;universe.tick();drawGrid();drawCells();requestAnimationFrame(renderLoop);};
这为我们提供了一个方便的检查点,用于检查记录的消息,并将当前呈现的帧与前一帧进行比较。

练习
- 将日志记录添加到
tick函数中,该函数记录每个单元格的行和列,这些单元格将状态从 live 转换为 dead,反之亦然。
- 声明一个
panic!()到Universe::new方法里面。在 Web 浏览器的 JavaScript 调试器中,检查恐慌的回溯。要做到禁用调试符号,只用不带console_error_panic_hook可选依赖项,重新构建就好了,并再次检查堆栈跟踪。可以吗?
