本文仅分析 scratch-blocks 和 scratch-vm 两个库之间的通信,即:对积木block的操作(点击/拖拽/删除等)如何触发vm库相应逻辑。
一、初始化
源码位置
\scratch-gui\src\containers\blocks.jsx
源码说明
建立 block 库和 vm 库的绑定关系。attachVM 函数调用 Blockly.Workspace.prototype.addChangeListener 函数,向 Blockly.Workspace.prototype.listeners_ 队列传入 vm.blockListener 函数,用于 vm 监听 block 积木事件;
二、运行时
源码位置
\scratch-blocks\core\events.js
\scratch-blocks\core\workspace.js
\scratch-vm\src\virtual-machine.js
源码说明
-
block 积木事件触发 Blockly.Events.fire,传入 event 事件对象;
-
Blockly.Events.fire 向 Blockly.Events.FIRE_QUEUE_ 队列 push event 事件对象;
-
Blockly.Events.fire 创建 setTimeout,异步调用 Blockly.Events.fireNow_;
-
Blockly.Events.fireNow_ 遍历 Blockly.Events.FIRE_QUEUE_ 队列,调用 Blockly.Workspace.prototype.fireChangeListener,传入 event 事件对象;
-
Blockly.Workspace.prototype.fireChangeListener 遍历 Blockly.Workspace.prototype.listeners_ 队列,调用队列里的函数(即 vm.blockListener 函数),传入 event 事件对象
-
至此,vm 成功接收 block积木事件,可以在vm里扩展自己的需求了。