在设计使用 Blockly 的应用时,有几种范例可供选择。您应尽早考虑这些选择,因为它们会影响用户需要的块。
配置
许多 Blockly 应用用于描述配置,而不是可执行程序。配置应用通常首先初始化工作区上的一个根级块。Blockly 开发者工具的“Block Factory”标签页就是一个很好的例子:
Blockly.Blocks['factory_base'] = {
init: function() {
this.setDeletable(false);
this.setMovable(false);
this.setEditable(false);
// etc...
}
}
Blockly.serialization.blocks.append({'type': 'factory_base'}, workspace);
这样会创建一个不可删除、不可移动的块,用于保存用户的所有配置。您可以随时对工作区进行序列化,以确定当前配置。
此类应用可能希望自动停用未连接到根块的任何块。这可以通过一行代码来实现:
workspace.addChangeListener(Blockly.Events.disableOrphans);
序列号
大多数 Blockly 应用都旨在创建串行节目。用户将按顺序执行的代码块堆叠在一起。
工作区中的每个(未停用)块都将构成该计划的一部分。如果有多个堆栈的块,则会先执行较高的块。(如果两个堆栈的高度大致相同,则优先考虑靠左的堆栈(在 RTL 模式下)。)
工作区可以随时导出为可执行代码。此代码可以在客户端使用 JavaScript(使用 eval 或 JS 解释器)执行,也可以在服务器端以任何语言执行。
import {javascriptGenerator} from 'blockly/javascript';
var code = javascriptGenerator.workspaceToCode(workspace);
并行计划
某些 Blockly 应用选择并行(而非串行)执行所有块堆栈。例如,鼓循环与旋律并发运行的音乐应用。
实现并行执行的一种方法是分别为每个代码块生成代码:
import {javascriptGenerator} from 'blockly/javascript';
var json = Blockly.serialization.workspaces.save(workspace);
// Store top blocks separately, and remove them from the JSON.
var blocks = json['blocks']['blocks'];
var topBlocks = blocks.slice(); // Create shallow copy.
blocks.length = 0;
// Load each block into the workspace individually and generate code.
var allCode = [];
var headless = new Blockly.Workspace();
for (var i = 0; block < topBlocks.length; i++) {
var block = topBlocks[i];
blocks.push(block);
Blockly.serialization.workspaces.load(json, headless);
allCode.push(javascriptGenerator.workspaceToCode(headless));
blocks.length = 0;
}
如果目标语言是 JavaScript,则 allCode
数组可用于创建多个 JS 解释器,以便同时执行。如果目标语言类似于 Python,则 allCode
数组可以组合成使用线程模块的单个程序。
与任何并行程序一样,您必须对任何共享资源(如变量和函数)做出谨慎的决策。
事件驱动型计划
事件处理脚本只是由系统(而不是程序)调用的函数。这些块可以封装要执行的块的堆栈,也可以是位于块堆栈顶部的标头。
有些开发者喜欢在事件块顶部添加“帽子”,使其看起来与其他块不同。这不是 Blockly 的默认外观,但可通过以下方法添加:将渲染程序常量 ADD_START_HATS
替换为 true
(自定义渲染程序 Codelab - 替换常量),或者添加主题并在块样式上设置 hat 选项。如需详细了解如何在主题中设置帽子,请点击此处。
在事件驱动型模型中,可能还有必要为程序启动创建一个处理程序。在该模型中,工作区上未连接到事件处理脚本的任何块都将被忽略,并且不会执行。
在设计使用事件的系统时,请考虑是否可以支持或是否需要支持同一事件处理脚本的多个实例。