I controlli di connessione limitano le connessioni (e quindi i blocchi) che possono essere collegate tra loro.
I controlli di connessione sono utili per i tipi di definizione del modello. Ad esempio, i seguenti tre blocchi non hanno alcun motivo di essere collegati, perché rappresentano codice che restituisce tipi diversi:
I controlli di connessione possono essere utilizzati per impedire la connessione di questi blocchi. In questo modo, gli utenti ricevono un feedback istantaneo e vengono evitati molti errori semplici.
Funzionamento
Ogni collegamento può essere associato a un "controllo connessione", che è un array di stringhe nullable.
Due connessioni possono essere collegate se:
- Si tratta di tipi compatibili (ad es. un output collegato a un input).
- Hanno almeno una stringa in comune nel controllo di connessione.
Ad esempio, le connessioni con i due controlli seguenti potrebbero essere collegate perché condividono la stringa 'apple'
:
['apple', 'ball', 'cat']
['apple', 'bear', 'caterpillar']
Tuttavia, i collegamenti con questi due controlli non sono stati possibili perché non condividono alcuna stringa:
['apple', 'ball', 'cat']
['ape', 'bear', 'caterpillar']
Esiste un altro caso speciale. Se uno degli array è null
, anche le due connessioni possono essere collegate. In questo modo puoi definire connessioni che possono collegarsi a qualsiasi cosa.
null
['ape', 'bear', 'caterpillar]
Esempi
Per un elenco di esempi su come utilizzare i controlli di connessione, consulta il playbook per i controlli di connessione.
Controlli impostati
Per impostazione predefinita, tutte le connessioni hanno un controllo di connessione null
, il che significa che possono collegarsi a qualsiasi cosa. I controlli di connessione devono essere assegnati manualmente.
Il modo in cui assegni i controlli di connessione alle connessioni è diverso a seconda che tu stia utilizzando definizioni di blocchi JSON o JavaScript.
JSON
Per le connessioni di primo livello, assegni il controllo direttamente alla proprietà che
definisce la connessione. Il valore assegnato può essere null
, una stringa (che diventa l'unica voce nel controllo di connessione) o un array di stringhe.
{
'type': 'custom_value_block',
'output': 'a connection check entry',
},
{
'type': 'custom_statement_block',
'nextStatement': null, // null check
'previousStatement': ['four', 'connection', 'check', 'entries']
}
Per gli input, puoi assegnare il controllo a una proprietà check
della definizione
dell'input. 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' // Accepts custom_value_block
},
{
'type': 'input_statement',
'check': ['two', 'entries'] // Accepts custom_statement_block
}
]
}
JavaScript
Per le connessioni di primo livello, puoi passare il controllo direttamente al metodo che
definisce la connessione. Se non specifichi 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_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']);
}
};
Per gli input, puoi passare il controllo al metodo setCheck
dopo averli
definiti. Se il metodo setCheck
non viene chiamato, il controllo viene considerato null
. Il valore che passi può essere una stringa o un array di stringhe.
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
}
};
Stringhe di controllo integrate
I blocchi integrati hanno controlli di connessione con i valori 'Array'
,
'Boolean'
, 'Colour'
, 'Number'
e 'String'
. Se vuoi che i tuoi blocchi interagiscano con i blocchi integrati, puoi utilizzare questi valori per renderli compatibili.
Limitazioni
Questo sistema è abbastanza solido e può risolvere molti casi d'uso, ma presenta alcune limitazioni.
Limitare il contesto più ampio
Questo sistema non supporta, da solo, la limitazione del "contesto più ampio" in cui è consentita una connessione. Ad esempio, non puoi dire che un blocco break
può esistere solo all'interno di un blocco loop
. Il sistema di controllo delle connessioni prende in considerazione solo le due connessioni immediate collegate.
Puoi supportare questa funzionalità utilizzando il sistema di eventi per ascoltare gli eventi di spostamento del blocco e verificare 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 non supporta, da solo, la definizione di tipi generici. Ad esempio, non puoi creare un blocco "Identità" che "restituisce" qualsiasi input.
Puoi in qualche modo supportare questa operazione modificando attivamente il controllo di connessione sull'output del blocco in modo che corrisponda all'input. Puoi farlo utilizzando il sistema di eventi per ascoltare gli eventi di spostamento dei blocchi.
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 collegato è anche generico, il blocco non funziona correttamente. Non esiste una buona soluzione alternativa per questo caso.
Strumenti di controllo della connessione
Se questo sistema non funziona per il tuo caso d'uso, puoi anche modificare il modo in cui vengono confrontati i controlli di connessione creando un controllo di connessione personalizzato.
Ad esempio, se vuoi creare un sistema più avanzato che gestisca alcune delle limitazioni di questo, puoi creare un controllo personalizzato delle connessioni.