Aggiungi un campo plug-in a Block Factory

Strumenti per sviluppatori Blockly ti consente di creare blocchi personalizzati utilizzando i blocchi. Supporta i campi pubblicati come plug-in, oltre a quelli forniti con Blockly di base. Se hai creato un campo personalizzato, puoi aggiungere il supporto per questo alla Fabbrica dei blocchi seguendo questa guida. Il campo personalizzato deve essere pubblicato su npm prima di poter aggiungere il supporto. Devi anche impegnarti ad aggiornare il campo per tenere il passo con le modifiche apportate a Blockly, altrimenti potremmo doverlo rimuovere da Block Factory in futuro.

Sviluppo su Block Factory

Il codice sorgente di Block Factory si trova nel repository blockly-samples nella directory examples/developer-tools.

Per inviare una modifica agli Strumenti per sviluppatori in blockly-samples, devi seguire i passaggi tipici per lo sviluppo in blockly-samples. A differenza di quanto avviene con i plug-in, dovrai eseguire npm install direttamente dalla directory examples/developer-tools anziché a livello di root di blockly-samples.

Installare il plug-in

Affinché la fabbrica di blocchi mostri il campo personalizzato nell'anteprima, è necessario installarlo. Aggiungi il tuo campo come dipendenza npm di developer-tools. Poi, registralo o esegui qualsiasi altra operazione di configurazione necessaria in developer-tools/src/blocks/index.ts.

Crea un blocco per il campo

Poiché Block Factory utilizza i blocchi per creare blocchi personalizzati, ti servirà un blocco che rappresenti il tuo campo personalizzato.

Crea la definizione del blocco

Devi progettare il blocco per il tuo campo. Se vuoi fare un passo in più, puoi progettarlo anche utilizzando Block Factory. Il blocco deve consentire all'utente di configurare l'impostazione richiesta dal campo, ad esempio i valori predefiniti e un nome. Aggiungi questa definizione di blocco a developer-tools/src/blocks/fields.ts e importala in developer-tools/src/blocks/index.ts.

Aggiungere un blocco alla casella degli strumenti

Successivamente, devi aggiungere questo blocco alla definizione della casella degli strumenti per renderlo accessibile agli utenti. La definizione del toolbox si trova in developer-tools/src/toolbox.ts. Il blocco dovrebbe essere aggiunto alla categoria "Campi".

Generatori di codici

La fabbrica di blocchi funziona utilizzando il sistema di generazione di codice che già conosci di Blockly. Ogni blocco ha un generatore di codice di blocco per ogni tipo di output generato da Block Factory e i blocchi padre assemblano il codice per i blocchi figlio nell'output corretto. Per aggiungere il supporto per un campo personalizzato, devi aggiungere funzioni di generazione di codice a blocchi per ciascuna delle classi di generazione di codice.

Crea un file per il blocco di campi nella directory output-generators/fields. Aggiungerai i generatori di codice a blocchi per ciascuno dei seguenti generatori a questo file. Importa questo file nel file blocks/index.ts in modo che le funzioni del generatore di codice a blocchi vengano caricate nell'applicazione.

Definizione di JavaScript

javascriptDefinitionGenerator crea il codice che verrà incluso nella definizione JavaScript per un blocco che include il campo personalizzato. In genere, ciò significa che il generatore di blocchi di codice deve restituire una riga di codice simile a .appendField(new YourFieldConstructor(arg1, arg2), 'userSpecifiedName'). Tieni presente che questa riga di codice non include un punto e virgola, perché un input che contiene più campi avrà diverse chiamate a appendField concatenate tra loro. Gli argomenti nel costruttore vengono estratti dai valori impostati dall'utente nel blocco di campi. Ecco un esempio di questo generatore di codice a blocchi per FieldAngle:

javascriptDefinitionGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: JavascriptDefinitionGenerator,
): string {
  const name = generator.quote_(block.getFieldValue('FIELDNAME'));
  const angle = block.getFieldValue('ANGLE');
  return `.appendField(new FieldAngle(${angle}), ${name})`;
};

Il blocco angolare che l'utente ha trascinato dalla categoria "Campi" della casella degli strumenti di Block Factory ha due campi:

  • FIELDNAME: l'utente può impostare il nome del campo nel blocco personalizzato
  • ANGLE: l'utente può impostare il valore dell'angolo predefinito

In questo generatore di codice a blocchi, otteniamo il valore dell'angolo predefinito e lo passiamo come unico argomento al costruttore FieldAngle. Il nome del campo viene sempre passato come secondo argomento a appendField.

Definizione JSON

jsonDefinitionGenerator è simile, ma restituisce la parte della definizione del blocco JSON che corrisponde al tuo campo. In genere, questo codice è un oggetto JSON che include:

  • type: corrisponde al nome del campo nel registro dei campi Blockly
  • name: l'utente può impostare il nome del campo nel blocco personalizzato
  • qualsiasi altra proprietà personalizzata necessaria per il metodo di inizializzazione JSON del campo.

Ecco un esempio tratto di nuovo da FieldAngle:

jsonDefinitionGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: JsonDefinitionGenerator,
): string {
  const code = {
    type: 'field_angle',
    name: block.getFieldValue('FIELDNAME'),
    angle: block.getFieldValue('ANGLE'),
  };
  return JSON.stringify(code);
};

Intestazioni del codice

Il generatore di intestazioni di codice crea l'output delle intestazioni di codice mostrato in Block Factory. Questo output può essere attivato/disattivato tra le importazioni di esmodule e i tag script, a seconda di come l'utente vuole caricare il codice, quindi esistono due istanze del generatore diverse: una per ogni caso. Devi aggiungere un generatore di codici a blocchi per ciascuno. Ecco un esempio per FieldAngle:

importHeaderGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: CodeHeaderGenerator,
): string {
  generator.addHeaderLine(
    `import {registerFieldAngle, FieldAngle} from '@blockly/field-angle';`,
  );
  generator.addHeaderLine(`registerFieldAngle();`);
  return '';
};

scriptHeaderGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: CodeHeaderGenerator,
): string {
  generator.addHeaderLine(
    `<script src="https://unpkg.com/@blockly/field-angle"></script>`,
  );
  generator.addHeaderLine(`registerFieldAngle();`);
  return '';
};

Questi generatori hanno un metodo chiamato addHeaderLine che ti consente di specificare una riga di codice da chiamare prima che il campo venga utilizzato nel codice. In genere, questo include operazioni come l'importazione del campo o il caricamento tramite un tag script e magari la chiamata a una funzione che registrerà il campo nel registro dei campi di Blockly.

Per questi due generatori di blocchi di codice, tutto il codice deve essere aggiunto tramite chiamate a addHeaderLine. Questa funzione garantisce che ogni riga di intestazione venga visualizzata una sola volta, anche se il blocco di campi personalizzati viene utilizzato più volte in un blocco personalizzato. Il generatore di codici di blocco deve restituire la stringa vuota.

Stub del generatore

Infine, abbiamo il generatore che crea lo stub del generatore per il campo. In questo generatore di codice a blocchi, scriverai codice che genera codice che aiuta l'utente a scrivere codice che genera codice. Ti ho confuso le idee? È più facile di quanto sembra.

Lo stub del generatore per un blocco personalizzato include una variabile predefinita che rappresenta ogni campo del blocco. Poi c'è un TODO che l'utente deve completare per assemblare tutte queste variabili nella stringa di codice finale che il suo blocco personalizzato restituirà. Ciò significa che in genere il generatore di codici a blocchi deve solo restituire la riga che crea questa variabile personalizzata. Supponiamo che l'utente stia creando un blocco personalizzato che aggiungerà raggi di sole al suo canvas. Aggiungono un campo angolare al blocco e lo chiamano "SUN_DIRECTION". Lo stub del generatore per questo blocco includerebbe la riga const angle_sun_direction = block.getFieldValue("SUN_DIRECTION");. Questa è la riga di codice che il nostro generatore di codice a blocchi per il campo dell'angolo deve restituire:

generatorStubGenerator.forBlock['field_angle'] = function (
  block: Blockly.Block,
  generator: GeneratorStubGenerator,
): string {
  const name = block.getFieldValue('FIELDNAME');
  const fieldVar = generator.createVariableName('angle', name);
  return `const ${fieldVar} = block.getFieldValue(${generator.quote_(
    name,
  )});\n`;
};

Per ottenere un nome standardizzato per la variabile, puoi chiamare generator.createVariableName e passare il tipo di campo (ad esempio angle, number e così via) insieme al nome che l'utente ha dato al campo.

Testalo

Dopo aver scritto tutti questi elementi, dovresti essere in grado di avviare Block Factory eseguendo npm start nella directory blockly-samples/examples/developer-tools. Dovresti essere in grado di trascinare il blocco dalla categoria del campo, aggiungerlo a un input di un blocco e osservare la modifica dell'output. Verifica che l'anteprima del blocco sia corretta e che il codice di ciascuna sezione di output sia corretto.