Controlli di connessione

I controlli della connessione limitano le connessioni (e quindi i blocchi) che possono connettersi l'uno con l'altro.

I controlli della connessione sono utili per i tipi di modellazione. Ad esempio, tre blocchi non hanno alcuna attività collegata, perché rappresentano il codice restituisce tipi diversi:

Un blocco elenco vuoto, collegato a un blocco radice quadrato, collegato a un
blocco maiuscolo

È possibile utilizzare i controlli della connessione per impedire la connessione di questi blocchi. Questo fornisce agli utenti un feedback immediato e impedisce molti errori semplici.

Funzionamento

Ogni connessione può essere associata a un "controllo della connessione" che è un valore nullable un array di stringhe.

Possono connettersi due connessioni se:

  1. Sono tipi compatibili (ad esempio, un output che si collega un input).
  2. Hanno almeno una stringa in comune nel controllo della connessione.

Ad esempio, i due controlli seguenti potrebbero connettersi perché condividono Stringa 'apple':

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

Questi due controlli non sono stati in grado di connettersi perché non condividono nessuna stringa:

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

C'è un altro caso speciale. Se uno dei due array è null, i due anche le connessioni possono connettersi. In questo modo puoi definire connessioni che possono a qualsiasi cosa.

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

Imposta controlli

Per impostazione predefinita, tutte le connessioni hanno un controllo della connessione null, il che significa che possono connettersi a qualsiasi cosa. I controlli della connessione devono essere assegnati manualmente.

La modalità di assegnazione dei controlli della connessione alle connessioni varia a seconda della se utilizzi definizioni di blocco JSON o di blocco JavaScript.

JSON

Per i collegamenti di primo livello, assegni il controllo direttamente alla proprietà definisce la connessione. Il valore assegnato può essere null, una stringa (che diventa l'unica voce nel controllo della connessione) o un array di stringhe.

{
  'type': 'custom_block',

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

Per gli input, puoi assegnare il controllo a una proprietà check dell'input definizione di Kubernetes. Se la proprietà check non esiste, il controllo viene considerato null. Il valore assegnato può essere una stringa o un array di stringhe.

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

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

JavaScript

Per le connessioni di primo livello, puoi passare il controllo direttamente al metodo definisce la connessione. Se non passi un valore, il controllo viene considerato null. Il valore che passi può essere una stringa (che diventa l'unica voce nel controllo della connessione) o un array di stringhe.

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']);
  }
}

Per gli input, puoi passare il controllo al metodo setCheck, dopo aver definito l'input. Se il metodo setCheck non viene chiamato, il controllo è considerata null. Il valore che trasmetti può essere una stringa o un array di stringhe.

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

Stringhe di controllo integrate

I blocchi integrati hanno controlli della connessione con i valori 'Array', 'Boolean', 'Colour', 'Number' e 'String'. Se vuoi che i tuoi blocchi interagiscono con i blocchi integrati, puoi utilizzare questi valori per renderli compatibili.

Esempi di valori

Quando definisci i controlli della connessione per ingressi e output, di solito i controlli dovrebbero essere considerati come rappresentazioni di tipi.

Input i controlli devono includere ogni "tipo" accettano e genera controlli devono includere esattamente ciò che "restituisce".

Accetta un solo tipo

Nel caso più semplice in cui si desidera creare un blocco che "accetta" o "returns" uno, devi includere quel tipo nel controllo della connessione della connessione.

un blocco di valori che accetta un solo tipo

Accetta più tipi

Per creare un blocco che "accetta" di più tipi, devi includere ogni accettato nel controllo della connessione dell'input.

un blocco di valori che accetta più tipi

Per convenzione, se un output può a volte essere accettato in più situazioni (ad esempio, se consenti a volte di utilizzare i numeri come stringhe) l'output dovrebbe essere più restrittiva e gli input dovrebbero essere più permissivi. Questa convenzione assicura che gli output non si connettano dove non sono supportati.

Accetta qualsiasi tipo

Per creare un blocco che "accetta" qualsiasi tipo, devi impostare il valore controllo della connessione a null.

un blocco di valori che accetta qualsiasi tipo

Restituisci sottotipi

Per creare un blocco che "restituisce" un sottotipo, devi includere sia il tipo e il supertipo nel controllo della connessione dell'output.

un blocco di valori che restituisce il tipo e il supertipo

Nel caso di sottotipi, è accettabile avere più controlli in un controllo di output, perché il blocco restitui sempre "restituisce" entrambi i tipi.

Restituisci tipi con parametri

Per creare un blocco che "restituisce" con parametri, devi includere entrambi la versione con parametri e la versione senza parametri nel controllo della connessione.

A seconda di quanto vuoi che sia rigorosa la lingua di blocco, puoi anche includi le varianza del tipo.

un blocco di valore che restituisce il tipo con parametri
tipo

Come per i sottotipi, è possibile avere più controlli in un controllo di output In questo caso, perché il blocco "restituisce" sempre entrambi i tipi.

Esempi di stack o istruzioni

Gli sviluppatori definiscono alcuni modi comuni per definire i controlli per i controlli precedenti e successivi e connessioni a Internet. Di solito si pensa a questi elementi come a una limitazione dell'ordine dei blocchi.

Le connessioni successive devono includere i blocchi che seguono quello attuale e le connessioni precedenti includono il blocco "attuale".

Mantieni in ordine i blocchi

Per creare un insieme di blocchi che si collegano in un ordine definito, devi includere quali blocchi devono seguire quello attuale nel prossimo controllo della connessione e cos'è il blocco attuale nel controllo della connessione precedente.

blocchi di istruzioni con un ordine forzato

Consenti molti blocchi centrali

Per creare un insieme di blocchi ordinati che consenta molti blocchi centrali, devi includi almeno una voce dal controllo della connessione precedente del blocco centrale al prossimo controllo della connessione del blocco centrale. In questo modo si può seguire il blocco da sé.

blocchi di istruzioni che consentono molti blocchi centrali

Non consentire blocchi centrali

Per creare un insieme di blocchi ordinati in cui quelli centrali sono facoltativi, per includere almeno una voce della connessione precedente del blocco centrale e il controllo della connessione precedente dell'ultimo blocco nella connessione del primo blocco controllo della connessione. In questo modo il primo blocco può essere seguito da una o un ultimo blocco.

Blocchi di istruzioni che non consentono blocchi centrali

Uno o uno stack

Per creare un blocco che può essere seguito solo da blocchi di un gruppo o blocchi dall'altro (e non da entrambi), devi fare due cose:

  1. Devi includere almeno una voce di entrambi i gruppi precedenti controlli della connessione nel successivo controllo della connessione del primo blocco.

  2. Devi definire il ruolo dei gruppi la connessione successiva esegue controlli di connessione per includere solo i valori che si trovano nei precedenti controlli della connessione (quindi possono essere seguiti solo per blocchi dello stesso gruppo).

blocchi di istruzioni che possono essere seguiti da più blocchi di un tipo, oppure
multipli di un altro, ma non entrambi

Limitazioni

Si tratta di un sistema abbastanza robusto che può risolvere molti casi d'uso, ma presenta alcuni limitazioni.

Limita il contesto più ampio

Questo sistema da solo non supporta la limitazione del "contesto maggiore" nel a cui una connessione può connettersi. Ad esempio, non puoi affermare che Il blocco break può esistere solo all'interno di un blocco loop. La connessione il sistema di controllo considera solo le due connessioni immediate che sono connesse.

Puoi supportare questa operazione utilizzando il sistema di eventi per ascoltare Eventi di spostamento del blocco e controlla se il blocco è posizionato in modo errato.

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

Tipi generici

Questo sistema, da solo, non supporta la definizione di tipi generici. Ad esempio: non è possibile creare un'identità blocco, questo "restituisce" qualunque sia il suo input.

Puoi in qualche modo supportarlo modificando attivamente il controllo della connessione nella l'output del blocco in modo che corrisponda all'input. Cosa puoi fare usando il sistema di eventi rimanere in ascolto per bloccare gli eventi di movimento.

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

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

Tuttavia, se il blocco connesso è anche generico, questo non funziona correttamente. Non c'è alcuna soluzione valida per questo caso.

Controlli della connessione

Se questo sistema non funziona per il tuo caso d'uso, puoi anche modificare il modo in cui dei controlli di connessione vengono confrontati creando verifica connessione personalizzata.

Ad esempio, se volessi creare un sistema più avanzato che gestisca alcuni limitazioni di questo, puoi creare una richiesta il controllo della connessione.