接続チェック

接続チェックでは、相互に接続できる接続(およびブロック)を制限します。

接続チェックは、型のモデリングに役立ちます。たとえば、次の 3 つのブロックは、異なる型を返すコードを表しているため、接続する必要はありません。

空のリストブロック、平方根ブロック、大文字ブロックに接続

接続チェックを使用すると、これらのブロックが接続しないようにできます。これにより、ユーザーに即時フィードバックが提供され、多くの単純なミスを防ぐことができます。

仕組み

すべての接続は、「接続チェック」に関連付けることができます。接続チェックは、文字列の null 許容配列です。

2 つの接続が接続できる場合:

  1. 互換性のあるタイプ(入力に接続する出力など)である。
  2. 接続チェックの文字列が 1 つ以上共通している。

たとえば、次の 2 つのチェックは 'apple' 文字列を共有しているため、接続できます。

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

ただし、これらの 2 つのチェックの接続は、文字列を共有していないため接続できません。

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

もう一つの特殊なケースがあります。いずれかの配列が null の場合、2 つの接続を接続することもできます。これにより、任意の場所への接続を定義できます。

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

接続チェックの使用方法の例については、接続チェックのプレイブックをご覧ください。

チェックを設定する

デフォルトでは、すべての接続に null 接続チェックが設定されているため、任意の接続先に接続できます。接続チェックは手動で割り当てる必要があります。

接続チェックを接続に割り当てる方法は、JSON ブロック定義を使用するか、JavaScript ブロック定義を使用するかによって異なります。

JSON

トップレベルの接続の場合は、接続を定義するプロパティにチェックを直接割り当てます。割り当てる値は、null、文字列(接続チェックの唯一のエントリになります)、または文字列の配列です。

{
  'type': 'custom_value_block',

  'output': 'a connection check entry',
},
{
  'type': 'custom_statement_block',

  'nextStatement': null, // null check
  'previousStatement': ['four', 'connection', 'check', 'entries']
}

入力の場合、チェックを入力定義の check プロパティに割り当てることができます。check プロパティが存在しない場合、チェックは null と見なされます。割り当てる値は、文字列または文字列の配列です。

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

  'args0': [
    {
      'type': 'input_value',
      'check': 'a connection check entry' // Accepts custom_value_block
    },
    {
      'type': 'input_statement',
      'check': ['two', 'entries'] // Accepts custom_statement_block
    }
  ]
}

JavaScript

最上位の接続の場合は、接続を定義するメソッドにチェックを直接渡すことができます。値を渡さない場合、チェックは null と見なされます。渡す値は、文字列(接続チェックの唯一のエントリになります)または文字列の配列です。

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

入力の場合は、入力を定義した後に、チェックを setCheck メソッドに渡すことができます。setCheck メソッドが呼び出されない場合、チェックは null と見なされます。渡す値は、文字列または文字列の配列にできます。

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

組み込みのチェック文字列

組み込みブロックには、'Array''Boolean''Colour''Number''String' の値を持つ接続チェックがあります。ブロックを組み込みブロックと相互運用する場合は、これらの値を使用して互換性を確保できます。

制限事項

このシステムは非常に堅牢で、多くのユースケースを解決できますが、いくつかの制限があります。

より大きなコンテキストを制限する

このシステム自体は、接続が許可される「より大きなコンテキスト」の制限をサポートしていません。たとえば、break ブロックは loop ブロック内にのみ存在できると指定することはできません。接続チェック システムは、接続されている直近の 2 つの接続のみを考慮します。

イベント システムを使用してブロック移動イベントをリッスンし、ブロックの位置が正しくないかを確認することで、これをサポートできます

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;
  },
}

一般的な種類

このシステム自体は、ジェネリック タイプの定義をサポートしていません。たとえば、入力が何であれ「返す」Identity ブロックを作成することはできません。

ブロックの出力で接続チェックをアクティブに変更して入力と一致させることで、これをある程度サポートできます。イベント システムを使用してブロック移動イベントをリッスンすることで実現できます。

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

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

ただし、接続されたブロックも汎用である場合、これは正しく機能しません。このケースに適した回避策はありません。

接続チェッカー

このシステムがユースケースに適していない場合は、カスタム接続チェッカーを作成して、接続チェックの比較方法を変更することもできます。

たとえば、このシステムの制限の一部を処理するより高度なシステムを作成したい場合は、カスタム接続チェッカーを作成できます。