Переменные — важная концепция программирования. Blockly поддерживает языки с динамической типизацией, такие как Python и JavaScript, и, приложив немного усилий, вы можете добавить информацию для поддержки языков со строгой типизацией (или языков со статической типизацией), таких как Java или C.
Дополнительную информацию о языках с динамической и статической типизацией см. в статье Введение в типы данных: статические, динамические, сильные и слабые .
Blockly предоставляет поля переменных, представляющие собой динамические раскрывающиеся списки, в которых отображаются имена переменных, предоставленных пользователем. Ниже приведён пример такого поля.
По умолчанию Blockly позволяет присваивать переменной любой тип, и все предоставляемые Blockly генераторы предназначены для языков с динамической типизацией. Если вы используете язык с динамической типизацией, вы можете настроить Blockly для его поддержки, выполнив следующие действия:
- Укажите тип переменной и ее блоки , включая геттеры и сеттеры.
- Настройте панель инструментов для использования вашего типа переменной и блоков.
- Определите генераторы для переменных и их блоков.
Нетипизированные переменные блоки
Базовыми блоками для доступа к переменным и управления ими являются блоки получения и установки. Давайте рассмотрим блоки получения и установки, предоставляемые Blockly.
JSON
// Block for variable getter.
{
"type": "variables_get",
"message0": "%1",
"args0": [
{ // Beginning of the field variable dropdown
"type": "field_variable",
"name": "VAR", // Static name of the field
"variable": "%{BKY_VARIABLES_DEFAULT_NAME}" // Given at runtime
} // End of the field variable dropdown
],
"output": null, // Null means the return value can be of any type
...
},
// Block for variable setter.
{
"type": "variables_set",
"message0": "%{BKY_VARIABLES_SET}",
"args0": [
{
"type": "field_variable",
"name": "VAR",
"variable": "%{BKY_VARIABLES_DEFAULT_NAME}"
},
{
"type": "input_value", // This expects an input of any type
"name": "VALUE"
}
],
...
}
JavaScript
// Block for variable getter.
Blockly.Blocks['variables_get'] = {
init: function() {
this.appendDummyInput()
.appendField(new Blockly.FieldVariable("VAR_NAME"), "FIELD_NAME");
this.setOutput(true, null);
...
}
};
// Block for variable setter.
Blockly.Blocks['variables_set'] = {
init: function() {
this.appendValueInput("NAME")
.setCheck(null)
.appendField("set")
.appendField(new Blockly.FieldVariable("VAR_NAME"), "FIELD_NAME")
.appendField("to");
this.setOutput(true, null);
...
}
};
Это создает следующие два блока:
Важно отметить, что, установив «выход» метода получения переменной равным null, возвращаемое значение может быть любого типа. Кроме того, обратите внимание, что входные данные метода установки переменной не требуют никаких проверок. В результате переменной может быть присвоено значение любого типа.
Типизированные переменные блоки
Вы можете добавить геттеры и сеттеры, обеспечивающие проверку типов. Например, если вы создали переменную типа "Panda"
, следующие определения создадут геттер и сеттер с соответствующими типами.
JSON
// Block for Panda variable getter.
{
"type": "variables_get_panda",
"message0": "%1",
"args0": [
{
"type": "field_variable",
"name": "VAR",
"variable": "%{BKY_VARIABLES_DEFAULT_NAME}",
"variableTypes": ["Panda"], // Specifies what types to put in the dropdown
"defaultType": "Panda"
}
],
"output": "Panda", // Returns a value of "Panda"
...
},
// Block for Panda variable setter.
{
"type": "variables_set_panda",
"message0": "%{BKY_VARIABLES_SET}",
"args0": [
{
"type": "field_variable",
"name": "VAR",
"variable": "%{BKY_VARIABLES_DEFAULT_NAME}",
"variableTypes": ["Panda"],
"defaultType": "Panda"
},
{
"type": "input_value",
"name": "VALUE",
"check": "Panda" // Checks that the input value is of type "Panda"
}
],
"previousStatement": null,
"nextStatement": null,
...
}
JavaScript
// Block for Panda variable getter.
Blockly.Blocks['variables_get_panda'] = {
init: function() {
this.appendDummyInput()
.appendField(new Blockly.FieldVariable(
"VAR_NAME", ['Panda'], 'Panda'), "FIELD_NAME");
this.setOutput(true, 'Panda');
...
}
};
// Block for Panda variable setter.
Blockly.Blocks['variables_set_panda'] = {
init: function() {
this.appendValueInput("NAME")
.setCheck('Panda')
.appendField("set")
.appendField(new Blockly.FieldVariable(
"VAR_NAME", null, ['Panda'], 'Panda'), "FIELD_NAME")
.appendField("to");
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
...
}
};
Это создаёт два типа блоков: геттер и сеттер. В их раскрывающихся списках отображаются только переменные типа "Panda"
. Их входные и выходные данные принимают только соединения типа "Panda"
. Значение defaultType
поля должно быть равно одному из значений массива variableTypes
. Если не задать defaultType
при указании массива variableTypes
, возникнет ошибка.
По умолчанию визуальный индикатор, указывающий пользователю используемый тип, отсутствует. Один из простых способов различать типы переменных — по цвету .
Добавить переменные в панель инструментов
Чтобы сделать этот новый тип переменных полезным для ваших пользователей, вам необходимо добавить способ создания и использования новых переменных.
Создайте новую динамическую категорию для переменных, если у вас ее еще нет.
Добавьте новые геттеры и сеттеры в категорию.
Кнопка «Создать переменную»
Далее пользователю необходимо предоставить возможность создавать переменные. Проще всего воспользоваться кнопкой «Создать переменную».
При создании кнопки сделайте обратный вызов
Blockly.Variables.createVariableButtonHandler(button.getTargetWorkspace(), null, 'panda');
и будет создана переменная типа "Panda"
!
Самый простой способ разрешить пользователям создавать переменные нескольких типов — это иметь одну кнопку «Создать» для каждого типа (например, «Создать строковую переменную», «Создать числовую переменную», «Создать переменную Panda»).
Если у вас больше двух-трёх типов переменных, кнопок может быстро стать слишком много. В этом случае рассмотрите возможность использования @blockly/plugin-typed-variable-modal для отображения всплывающего окна, в котором пользователи смогут выбрать нужный тип переменной.
Определить генераторы
Наконец, вам потребуется определить генераторы блочного кода для новых блоков переменных. Вы также можете получить доступ к списку переменных напрямую с помощью Workspace.getVariableMap().getAllVariables()
, чтобы получить все переменные всех типов, или Workspace.getVariableMap().getVariablesOfType()
чтобы получить все переменные определённого типа.