Variables

Les variables sont un concept de programmation important. Blockly est compatible avec les langages à typage dynamique tels que Python et JavaScript. Avec un peu de travail supplémentaire, vous pouvez ajouter des informations pour prendre en charge les langages à typage fort (ou les langages à typage statique) tels que Java ou C.

Pour en savoir plus sur les langages à typage dynamique et statique, consultez Introduction aux types de données : statique, dynamique, fort & faible.

Blockly fournit des champs de variables qui sont des listes déroulantes dynamiques affichant les noms des variables fournies par l'utilisateur. Voici un exemple :

Un champ de variable avec un menu déroulant permettant de sélectionner une variable, de modifier le nom de la variable actuelle ou de la supprimer.

Par défaut, Blockly autorise l'attribution de n'importe quel type à une variable, et tous les générateurs fournis par Blockly sont destinés aux langages à typage dynamique. Si vous utilisez un langage typé, vous pouvez configurer Blockly pour qu'il le prenne en charge en procédant comme suit :

Blocs de variables non typées

Les blocs les plus élémentaires pour accéder à une variable et la manipuler sont les blocs d'accesseur et de mutateur. Examinons les blocs d'accesseur et de mutateur fournis par 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);
    ...
  }
};

Cela crée les deux blocs suivants :

Blocs Getter et Setter pour la variable `foo`.

Il est important de noter qu'en définissant la "sortie" du getter de variable sur "null", la valeur renvoyée peut être de n'importe quel type. Notez également que l'entrée du mutateur de variable ne spécifie aucune vérification. Par conséquent, la variable peut être définie sur n'importe quel type de valeur.

Blocs de variables typées

Vous pouvez ajouter des accesseurs et des mutateurs qui appliquent la vérification des types. Par exemple, si vous avez créé une variable de type "Panda", les définitions suivantes créent un accesseur et un mutateur avec les types appropriés.

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

Cela crée deux types de blocs, un accesseur et un mutateur. Leurs listes déroulantes n'affichent que les variables de type "Panda". Leurs entrées et sorties n'acceptent que les connexions de type "Panda". Le defaultType du champ doit être défini sur l'une des valeurs du tableau variableTypes. Si vous ne définissez pas le defaultType tout en fournissant un tableau variableTypes, une erreur sera générée.

Par défaut, aucun indicateur visuel n'indique à l'utilisateur le type utilisé. Un moyen simple de différencier les types de variables consiste à utiliser des couleurs.

Ajouter des variables à la boîte à outils

Pour que ce nouveau type de variable soit utile à vos utilisateurs, vous devez ajouter un moyen de créer et d'utiliser les nouvelles variables.

Créez une nouvelle catégorie dynamique pour les variables si vous n'en avez pas déjà une.

Une catégorie ouverte nommée "Variables" contenant un bouton "Créer une variable".

Ajoutez vos nouveaux accesseurs et mutateurs à la catégorie.

Même catégorie après la création des variables "foo" et "bar". Il contient un bouton "Créer une variable", des blocs "Définir la variable sur" et "Modifier la variable de", ainsi que des blocs getter.

Bouton "Créer une variable"

Ensuite, votre utilisateur a besoin d'un moyen de créer des variables. Le moyen le plus simple consiste à utiliser un "Créer une variable" bouton.

Lorsque vous créez le bouton, faites en sorte que le rappel appelle

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

et une variable typée "Panda" sera créée.

Le moyen le plus simple de permettre aux utilisateurs de créer des variables de plusieurs types consiste à disposer d'un bouton "Créer" par type (par exemple, "Créer une variable de chaîne", "Créer une variable numérique", "Créer une variable Panda").

Si vous avez plus de deux ou trois types de variables, vous risquez rapidement d'avoir trop de boutons. Dans ce cas, envisagez d'utiliser @blockly/plugin-typed-variable-modal pour afficher une fenêtre pop-up à partir de laquelle les utilisateurs peuvent sélectionner le type de variable souhaité.

Définir des générateurs

Enfin, vous devrez définir des générateurs de code de bloc pour vos nouveaux blocs de variables. Vous pouvez également accéder directement à la liste des variables avec Workspace.getVariableMap().getAllVariables() pour obtenir toutes les variables de tous les types ou Workspace.getVariableMap().getVariablesOfType() pour obtenir toutes les variables d'un type spécifique.