Переменные

Переменные — важная концепция программирования. 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);
    ...
  }
};

В результате создаются следующие два блока:

Блоки геттеров и сеттеров для переменной `foo`.

Важно отметить, что, установив значение параметра «output» для геттера переменной в null, возвращаемое значение может быть любого типа. Также обратите внимание, что параметр «input» для сеттера переменной не содержит никаких проверок. В результате переменной можно присвоить значение любого типа.

Блоки типизированных переменных

Вы можете добавлять геттеры и сеттеры, которые обеспечивают проверку типов. Например, если вы создали переменную типа "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 будет выдана ошибка.

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

Добавить переменные в панель инструментов

Чтобы сделать этот новый тип переменных полезным для ваших пользователей, вам необходимо добавить способ создания и использования новых переменных.

Если у вас его еще нет, создайте новую динамическую категорию для переменных.

Открытая категория под названием «Переменные», содержащая кнопку «Создать переменную».

Добавьте новые геттеры и сеттеры в эту категорию.

Та же категория после создания переменных `foo` и `bar`. Она содержит кнопку "Создать переменную", блоки set-variable-to и change-variable-by, а также блоки getter.

Создать кнопку «Переменная»

Далее пользователю потребуется способ создания переменных. Самый простой способ — использовать кнопку «Создать переменную».

При создании кнопки выполните вызов функции обратного вызова.

Blockly.Variables.createVariableButtonHandler(button.getTargetWorkspace(), null, 'panda');

и будет создана переменная типа "Panda" !

Самый простой способ позволить пользователям создавать переменные разных типов — это иметь отдельную кнопку «Создать» для каждого типа (например, «Создать строковую переменную», «Создать числовую переменную», «Создать переменную Panda»).

Если у вас более двух или трех типов переменных, вы быстро можете получить слишком много кнопок. В этом случае рассмотрите возможность использования @blockly/plugin-typed-variable-modal для отображения всплывающего окна, из которого пользователи смогут выбрать нужный тип переменной.

Определение генераторов

Наконец, вам потребуется определить генераторы кода блоков для ваших новых блоков переменных. Вы также можете получить доступ к списку переменных напрямую с помощью Workspace.getVariableMap().getAllVariables() , чтобы получить все переменные всех типов, или Workspace.getVariableMap().getVariablesOfType() , чтобы получить все переменные определенного типа.