Vérification de la connexion

Les vérifications de connexion limitent les connexions (et donc les blocs) qui peuvent se connecter les unes aux autres.

Les vérifications de connexion sont utiles pour les types de modélisation. Par exemple, les trois blocs suivants n'ont aucune entreprise connectée, car ils représentent du code qui renvoie différents types:

Un bloc de liste vide, connecté à un bloc racine carré, connecté à un bloc en majuscules

Il est possible d'empêcher la connexion de ces blocs à l'aide de vérifications de connexion. Les utilisateurs bénéficient ainsi d'un retour instantané et cela évite de nombreuses erreurs simples.

Fonctionnement

Chaque connexion peut être associée à une "vérification de connexion", c'est-à-dire un tableau de chaînes pouvant avoir une valeur nulle.

Deux connexions peuvent se connecter si:

  1. Ils sont des types compatibles (par exemple, une sortie se connectant à une entrée).
  2. Ils ont au moins une chaîne en commun dans leur vérification de connexion.

Par exemple, les deux vérifications suivantes peuvent se connecter, car elles partagent la chaîne 'apple':

['apple', 'ball', 'cat']
['apple', 'bear', 'caterpillar']

Toutefois, ces deux vérifications n'ont pas pu se connecter, car elles ne partagent aucune chaîne:

['apple', 'ball', 'cat']
['ape', 'bear', 'caterpillar']

Il existe un autre cas particulier. Si l'un des tableaux est null, les deux connexions peuvent également se connecter. Cela vous permet de définir des connexions qui peuvent se connecter à n'importe quoi.

null
['ape', 'bear', 'caterpillar]

Effectuer des vérifications

Par défaut, toutes les connexions font l'objet d'une vérification de connexion null, ce qui signifie qu'elles peuvent se connecter à n'importe quoi. Les vérifications de connexion doivent être attribuées manuellement.

La manière dont vous attribuez des vérifications de connexion aux connexions diffère selon que vous utilisez des définitions de bloc JSON ou des définitions de bloc JavaScript.

JSON

Pour les connexions de niveau supérieur, vous attribuez la vérification directement à la propriété qui définit la connexion. La valeur que vous attribuez peut être null, une chaîne (qui devient la seule entrée lors de la vérification de la connexion) ou un tableau de chaînes.

{
  'type': 'custom_block',

  'output': null,
  'nextStatement': 'a connection check entry',
  'previousStatement': ['four', 'connection', 'check', 'entries']
}

Pour les entrées, vous pouvez attribuer la vérification à une propriété check de la définition de l'entrée. Si la propriété check n'existe pas, la vérification est considérée comme null. La valeur que vous attribuez peut être une chaîne ou un tableau de chaînes.

{
  'type': 'custom_block',
  'message0': '%1 %2',

  'args0': [
    {
      'type': 'input_value',
      'check': 'a connection check entry'
    },
    {
      'type': 'input_statement',
      'check': ['four', 'connection', 'check', 'entries']
    }
  ]
}

JavaScript

Pour les connexions de niveau supérieur, vous pouvez transmettre la vérification directement à la méthode qui définit la connexion. Si vous ne transmettez pas de valeur, le test est considéré comme null. La valeur que vous transmettez peut être une chaîne (qui devient la seule entrée lors de la vérification de la connexion) ou un tableau de chaînes.

Blockly.Blocks['custom_block'] = {
  init: function() {
    this.setOutput(true); // null check
    this.setNextStatement(true, 'a connection check entry');
    this.setPreviousStatement(true, ['four', 'connection', 'check', 'entries']);
  }
}

Pour les entrées, vous pouvez transmettre la vérification à la méthode setCheck après avoir défini l'entrée. Si la méthode setCheck n'est pas appelée, la vérification est considérée comme null. La valeur que vous transmettez peut être une chaîne ou un tableau de chaînes.

Blockly.Blocks['custom_block'] = {
  init: function() {
    this.appendValueInput('NAME')
        .setCheck('a connection check entry');
    this.appendStatementInput('NAME')
        .setCheck(['four', 'connection', 'check', 'entries']);
  }
}

Chaînes de vérification intégrées

Les blocs intégrés comportent des vérifications de connexion avec les valeurs 'Array', 'Boolean', 'Colour', 'Number' et 'String'. Si vous souhaitez que vos blocs interagissent avec les blocs intégrés, vous pouvez utiliser ces valeurs pour les rendre compatibles.

Exemples de valeurs

Lorsque vous définissez des vérifications de connexion pour les entrées et les sorties, vous devez généralement les considérer comme des vérifications de types.

Les vérifications des entrées doivent inclure tous les "types " qu'elles acceptent, et celles des sorties doivent inclure exactement ce qu'elles "renvoient".

Accepter un seul type

Dans les cas les plus basiques où vous souhaitez créer un bloc qui "accepte" ou "renvoie" un type, vous devez inclure ce type dans la vérification de la connexion de la connexion.

un bloc de valeur qui accepte un seul type

Accepter plusieurs types

Pour créer un bloc qui "accepte" plusieurs types, vous devez inclure tous les types acceptés dans la vérification de la connexion de l'entrée.

un bloc de valeur qui accepte plusieurs types

Par convention, si une sortie peut parfois être acceptée dans plusieurs situations (par exemple, si vous autorisez l'utilisation de nombres en tant que chaînes), elle doit être plus restrictive et les entrées doivent être plus permissives. Cette convention garantit que les sorties ne se connectent pas là où elles ne sont pas compatibles.

Accepter tous les types

Pour créer un bloc qui "accepte" n'importe quel type, vous devez définir la vérification de la connexion de l'entrée sur null.

un bloc "value" qui accepte n'importe quel type

Sous-types renvoyés

Pour créer un bloc qui "renvoie" un sous-type, vous devez inclure le type et le supertype dans la vérification de la connexion de la sortie.

un bloc de valeur qui renvoie son type et son supertype.

Dans le cas des sous-types, il est acceptable d'effectuer plusieurs vérifications dans une vérification de sortie, car le bloc "renvoie" toujours les deux types.

Renvoyer des types paramétrés

Pour créer un bloc qui "renvoie" un type paramétré, vous devez inclure à la fois la version paramétrée et la version non paramétrée dans la vérification de connexion de la sortie.

En fonction du degré de rigueur que vous souhaitez pour votre langage de blocage, vous pouvez également inclure la ou les variances du type.

Un bloc de valeur qui renvoie son type paramétré et son type non paramétré

Comme pour les sous-types, il est acceptable d'avoir plusieurs vérifications dans une vérification des résultats dans ce cas, car le bloc "renvoie" toujours les deux types.

Exemples de piles ou d'énoncés

Les développeurs utilisent plusieurs méthodes courantes pour définir les vérifications des connexions précédentes et suivantes. En général, vous les considérez comme limitant l’ordre des blocs.

Les connexions suivantes doivent inclure les blocs qui doivent suivre le bloc actuel, et les connexions précédentes incluent ce qu'est le bloc actuel.

Conserver les blocs dans l'ordre

Pour créer un ensemble de blocs qui se connectent dans un ordre défini, vous devez inclure les blocs qui doivent suivre le bloc actuel dans la vérification de la connexion suivante, et ce qu'est le bloc actuel lors de la vérification de connexion précédente.

d'instructions avec un ordre forcé

Beaucoup de blocs intermédiaires

Pour créer un ensemble de blocs ordonnés autorisant de nombreux blocs intermédiaires, vous devez inclure au moins une entrée de la vérification de connexion précédente du bloc du milieu lors de la vérification suivante des connexions du bloc du milieu. Cela permet de suivre le bloc en plus de lui-même.

qui autorisent de nombreux
blocs centraux

Ne pas autoriser les blocs du milieu

Pour créer un ensemble de blocs ordonnés dans lesquels les blocs du milieu sont facultatifs, vous devez inclure au moins une entrée provenant de la vérification de connexion précédente du bloc du milieu et de la vérification de connexion précédente du dernier bloc dans la vérification de connexion suivante du premier bloc. Le premier bloc peut ainsi être suivi soit d'un bloc du milieu, soit d'un dernier bloc.

qui n'autorisent aucun bloc intermédiaire

Piles ou l'un ou l'autre

Pour créer un bloc qui ne peut être suivi que de blocs d'un groupe ou de blocs d'un autre (et non les deux), vous devez effectuer les deux opérations suivantes:

  1. Vous devez inclure au moins une entrée provenant des vérifications de connexion précédentes des deux groupes dans la prochaine vérification de connexion du premier bloc.

  2. Vous devez définir les vérifications de connexion suivantes des groupes pour n'inclure que les valeurs figurant dans les vérifications de connexion précédentes (afin qu'elles ne puissent être suivies que par les blocs du même groupe).

qui peuvent être suivis par plusieurs blocs
d'un type ou d'un autre, mais pas les deux

Limites

Ce système est assez robuste et peut résoudre de nombreux cas d'utilisation, mais il présente quelques limites.

Restreindre l'ensemble du contexte

Ce système, seul, ne permet pas de restreindre le "contexte plus étendu" dans lequel une connexion est autorisée à se connecter. Par exemple, vous ne pouvez pas dire qu'un bloc break n'est autorisé à exister qu'à l'intérieur d'un bloc loop. Le système de vérification des connexions ne tient compte que des deux connexions immédiates connectées.

Pour ce faire, vous pouvez utiliser le système d'événements pour écouter les événements de déplacement de bloc et vérifier si le bloc est mal positionné.

Blockly.Blocks['custom_block'] = {
  init: function() { }

  onchange: function(e) {
    if (this.workspace.isDragging()) return;
    if (e.type !== Blockly.Events.BlockMove) return;
    if (!this.getSurroundLoop()) this.outputConnection.disconnect();
  }

  loopTypes: new Set(); // Your valid *block types* (not connection checks).

  getSurroundLoop: function () {
    let block = this.getSurroundParent();
    do {
      if (loopTypes.has(block.type)) return block;
      block = block.getSurroundParent();
    } while (block);
    return null;
  },
}

Types génériques

En soi, ce système ne permet pas de définir des types génériques. Par exemple, vous ne pouvez pas créer un bloc "Identité" qui "renvoie" quelle que soit son entrée.

Vous pouvez plutôt prendre en charge ce changement en modifiant activement la vérification de la connexion sur la sortie du bloc pour qu'elle corresponde à son entrée. Vous pouvez utiliser le système d'événements pour écouter afin de bloquer les événements de déplacement.

Blockly.Blocks['custom_block'] = {
  init: function() { }

  onchange: function(e) {
    if (e.type !== Blockly.Events.BlockMove) return;
    this.setOutput(
        true, this.getInputTargetBlock()?.outputConnection.getCheck());
  }
}

Toutefois, si le bloc connecté est également générique, cela ne fonctionne pas correctement. Il n'y a pas de solution de contournement appropriée pour ce cas.

Vérificateurs de connexion

Si ce système ne fonctionne pas pour votre cas d'utilisation, vous pouvez également modifier la comparaison des vérifications de connexion en créant un vérificateur de connexion personnalisé.

Par exemple, si vous souhaitez créer un système plus avancé qui gère certaines des limites de celui-ci, vous pouvez créer un vérificateur de connexion personnalisé.