Дизайн приложения

При разработке приложения, использующего Blockly, можно выбрать одну из нескольких парадигм. Следует заранее продумать эти варианты, поскольку они влияют на то, какие блоки понадобятся пользователю.

Конфигурация

Многие приложения Blockly используются для описания конфигураций, а не исполняемых программ. Приложения конфигурации обычно начинают работу с инициализации одного корневого блока в рабочей области. Хорошим примером является вкладка «Фабрика блоков» в инструментах разработчика Blockly:

Блок, используемый для проектирования других блоков. Пользователи могут указать имя блока, входы блока, являются ли входы внутренними или внешними и т. д.

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 может быть использован для создания нескольких интерпретаторов JavaScript для одновременного выполнения. Если целевой язык — что-то вроде Python, массив allCode может быть собран в одну программу, использующую модуль потоковой обработки.

Как и в любой параллельной программе, необходимо принимать осторожные решения относительно любых общих ресурсов, таких как переменные и функции.

Программа, ориентированная на события

Обработчики событий — это просто функции, вызываемые системой, а не программой. Эти блоки могут либо заключать в себе стек блоков, подлежащих выполнению, либо представлять собой заголовки, размещаемые поверх стека блоков.

Два блока «по щелчку мыши», один с оператором ввода и один со следующим соединением.

Некоторые разработчики любят добавлять «шапку» к верхней части блоков событий, чтобы они выделялись на фоне других блоков. Это не стандартный вид Blockly, но его можно добавить, переопределив константу рендерера ADD_START_HATS на true ( Custom renderers codelab - Override constants ) или добавив тему и установив параметр «шапка» в стиле блока. Подробнее о настройке шапок для блоков в рамках тем см. в разделе «Стиль блока» в документации по темам.

Те же блоки «по щелчку мыши» с шляпами, которые образуют горб наверху блока.

В рамках событийно-управляемой модели может иметь смысл также создать обработчик для запуска программы. В рамках этой модели любой блок в рабочей области, не подключенный к обработчику событий, будет игнорироваться и не будет выполняться.

При проектировании системы, использующей события, подумайте, возможно или желательно поддерживать несколько экземпляров одного и того же обработчика событий.

Планировка рабочего пространства

Существует два разумных способа компоновки экрана слева направо. Один из них предполагает расположение панели инструментов слева, рабочей области посередине и области визуализации вывода справа. Эта компоновка используется в первой версии Scratch, а также в Made with Code.

Приложение с панелью инструментов слева, рабочей областью посередине и лабиринтом (визуализацией выходных данных) справа.

Другой вариант начинается с визуализации вывода слева, панели инструментов посередине и рабочего пространства справа. Такая компоновка используется во второй версии Scratch, а также в большинстве приложений Blockly.

Приложение с лабиринтом (визуализацией выходных данных) слева, панелью инструментов посередине и рабочей областью справа.

В любом случае рабочее пространство должно растягиваться, чтобы занимать весь доступный размер экрана — пользователям нужно как можно больше места для программирования. Как видно на скриншотах выше, первый вариант плохо работает на широких экранах, поскольку пользовательский код и визуализация вывода разделены. Второй вариант позволяет выделить больше места для более крупных программ, при этом все три раздела располагаются близко друг к другу.

Также логично, что пользователи сначала обдумывают проблему, которую они пытаются решить, затем изучают предоставленные инструменты и только потом приступают к программированию.

Конечно, для перевода на арабский и иврит необходимо поменять весь порядок.

В некоторых случаях, например, при использовании небольшого количества простых блоков, может иметь смысл разместить панель инструментов над или под рабочей областью. В таких случаях Blockly поддерживает горизонтальную прокрутку панели инструментов, но использовать её следует с осторожностью.

Рекомендация: Разместите визуализацию программы рядом с панелью инструментов.