Blocchi personalizzati: paradigmi di blocco

Esistono diversi paradigmi tra cui scegliere quando si progetta un'applicazione che utilizza Blockly. Dovresti prendere in considerazione queste scelte il prima possibile, poiché influiscono sui blocchi di cui l'utente avrà bisogno.

Configurazione

Molte applicazioni Blockly vengono utilizzate per descrivere le configurazioni, anziché i programmi eseguibili. In genere, le applicazioni di configurazione iniziano inizializzando un blocco di livello principale nell'area di lavoro. Un buon esempio è la scheda Block Factory degli strumenti per sviluppatori Blockly:

Blockly.Blocks['factory_base'] = {
  init: function() {
    this.setDeletable(false);
    this.setMovable(false);
    this.setEditable(false);
    // etc...
  }
}

Blockly.serialization.blocks.append({'type': 'factory_base'}, workspace);

In questo modo viene creato un blocco non eliminabile e non spostabile che contiene tutta la configurazione dell'utente. L'area di lavoro può essere serializzata in qualsiasi momento per determinare la configurazione attuale.

Tali applicazioni potrebbero disattivare automaticamente qualsiasi blocco non collegato al blocco principale. Puoi farlo utilizzando una sola riga:

workspace.addChangeListener(Blockly.Events.disableOrphans);

Programma in serie

La maggior parte delle applicazioni Blockly è progettata per creare programmi seriali. Gli utenti raggruppano i blocchi che vengono eseguiti in ordine.

Ogni blocco (non disattivato) nell'area di lavoro farà parte del programma. Se sono presenti più stack di blocchi, quelli più alti vengono eseguiti per primi. Se due stack hanno all'incirca la stessa altezza, viene data la priorità agli stack a sinistra (a destra in modalità RTL).

L'area di lavoro può essere esportata in codice eseguibile in qualsiasi momento. Questo codice può essere eseguito sul lato client in JavaScript (utilizzando eval o l'interprete JS) oppure sul lato server in qualsiasi linguaggio.

import {javascriptGenerator} from 'blockly/javascript';

var code = javascriptGenerator.workspaceToCode(workspace);

Programma parallelo

Alcune applicazioni Blockly scelgono di eseguire tutti gli stack di blocchi in parallelo anziché in serie. Un esempio potrebbe essere un'applicazione musicale in cui un loop di batteria viene eseguito contemporaneamente a una melodia.

Un modo per implementare l'esecuzione parallela è generare il codice per ogni blocco singolarmente:

import {javascriptGenerator} from 'blockly/javascript';

var json = Blockly.serialization.workspaces.save(workspace);

// Store top blocks separately, and remove them from the JSON.
var blocks = json['blocks']['blocks'];
var topBlocks = blocks.slice();  // Create shallow copy.
blocks.length = 0;

// Load each block into the workspace individually and generate code.
var allCode = [];
var headless = new Blockly.Workspace();
for (var i = 0; block < topBlocks.length; i++) {
  var block = topBlocks[i];
  blocks.push(block);
  Blockly.serialization.workspaces.load(json, headless);
  allCode.push(javascriptGenerator.workspaceToCode(headless));
  blocks.length = 0;
}

Se la lingua di destinazione è JavaScript, è possibile utilizzare l'array allCode per creare più interpreti JS per l'esecuzione simultanea. Se il linguaggio di destinazione è simile a Python, l'array allCode può essere assemblato in un singolo programma che utilizza un modulo di threading.

Come con qualsiasi programma parallelo, è necessario prendere decisioni attente in merito a risorse condivise, come variabili e funzioni.

Programma basato su eventi

I gestori di eventi sono solo funzioni che vengono richiamate dal sistema, piuttosto che dal programma. Questi blocchi possono racchiudere lo stack di blocchi da eseguire oppure possono essere intestazioni posizionate sopra una pila di blocchi.

Alcuni sviluppatori aggiungono "cappello" nella parte superiore dei blocchi eventi per distinguerli dagli altri blocchi. Questo non è l'aspetto predefinito di Blockly, ma può essere aggiunto sostituendo la costante del renderer ADD_START_HATS su true (codelab per il renderer personalizzato - override delle costanti) o aggiungendo un tema e impostando l'opzione cappello sullo stile del blocco. Ulteriori informazioni su come impostare cappelli sui blocchi come parte dei temi sono disponibili qui.

All'interno di un modello basato su eventi, potrebbe avere senso creare anche un gestore per l'avvio del programma. In base a questo modello, qualsiasi blocco nell'area di lavoro non collegato a un gestore di eventi viene ignorato e non viene eseguito.

Quando progetti un sistema che utilizza gli eventi, valuta se è possibile o opportuno supportare più istanze dello stesso gestore di eventi.