Variáveis

Variáveis são um conceito de programação importante. O Blockly oferece suporte dinâmico linguagens tipadas, como Python e JavaScript, e com um pouco mais de trabalho, pode adicionar informações para oferecer suporte a linguagens fortemente tipadas (ou com tipagem estática linguagens, como Java ou C.

Veja mais aqui sobre linguagens dinâmicas e estáticas.

O Blockly fornece campos variáveis, que são caixas suspensas dinâmicas que mostram os nomes das variáveis fornecidas pelo usuário. Confira abaixo um exemplo.

Por padrão, o Blockly permite que qualquer tipo seja atribuído a uma variável e todos Os geradores do Blockly são para idiomas com verificação dinâmica. Se você for usando um idioma digitado, é possível configurar o Blockly para oferecer suporte a ele fazendo o seguinte:

Blocos de variáveis não digitadas

Os blocos mais básicos para acessar e manipular uma variável são o getter e setter. Vamos analisar os blocos getter e setter que o Blockly oferece.

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);
    ...
  }
};

Isso cria os dois blocos a seguir:

Um detalhe importante a notar é que definir o valor de "output" do getter para nulo, o valor de retorno pode ser de qualquer tipo. Além disso, observe que a variável setter não especifica nenhuma verificação. Como resultado, a variável pode ser definida a qualquer tipo de valor.

Blocos de variáveis com tipo

É possível adicionar getters e setters que aplicam a verificação de tipo. Por exemplo, se você tenham criado uma variável do tipo "Panda", as definições a seguir criam uma getter e setter com os tipos apropriados.

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 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 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);
    ...
  }
};

Isso cria dois tipos de blocos, um getter e um setter. Apenas os menus suspensos exiba variáveis do tipo Panda. As entradas e saídas aceitam apenas com o tipo Panda. O defaultType do campo precisa ser definido como um dos valores na matriz variableTypes. Não definir o defaultType enquanto fornecer uma matriz variableTypes causará um erro.

Por padrão, não há um indicador visual para informar ao usuário qual tipo está sendo usados. Uma maneira fácil de diferenciar os tipos de variáveis é por cor.

Adicionar variáveis à caixa de ferramentas

Para que esse novo tipo de variável seja útil para seus usuários, você precisa adicionar uma forma criar e usar as novas variáveis.

Criar uma nova categoria dinâmica para variáveis, caso ainda não tenha feito isso.

Adicione os novos getters e setters à categoria.

Botão "Criar variável"

Em seguida, o usuário precisa de uma maneira de criar variáveis. A maneira mais simples é com um "Criar variável" .

Ao criar o botão, fazer a chamada de retorno

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

e uma variável do tipo Panda será criada!

A maneira mais fácil de permitir que os usuários criem variáveis de vários tipos é ter uma "criação" botão por tipo (por exemplo, "Criar variável de string", "Criar número" variável, Criar variável de panda).

Se você tiver mais de dois ou três tipos de variáveis, poderá acabar rapidamente em excesso. Nesse caso, considere usar @blockly/plugin-typed-variable-modal para exibir um pop-up em que os usuários podem selecionar o tipo de variável desejado.

Definir geradores

Por fim, você vai precisar definir geradores de código de bloco. para seus novos blocos de variáveis. Você também pode acessar a lista de variáveis diretamente com Blockly.Workspace.getAllVariables() para receber todas as variáveis de todos os tipos ou Blockly.Workspace.getVariablesOfType() para receber todas as variáveis de um tipo específico.