ブロック的なアプリケーションは、出力言語として JavaScript を生成することが多く、 通常はウェブページ内で実行します(同じまたは埋め込みの WebView)。 他の生成ツールと同様に、まず JavaScript 生成ツールを読み込みます。
import {javascriptGenerator} from 'blockly/javascript';
ワークスペースから JavaScript を生成するには、以下を呼び出します。
javascriptGenerator.addReservedWords('code');
var code = javascriptGenerator.workspaceToCode(workspace);
作成されたコードは、リンク先の Web ページで直接実行できます。
try {
eval(code);
} catch (e) {
alert(e);
}
基本的に、上記のスニペットはコードを生成して評価するだけです。ただし、
いくつかの改良点があります改良点の一つは、eval を
失敗するのではなくランタイム エラーを表示する try
/catch
抑えることができます。もう 1 つの絞り込みでは、予約済みのリストに code
が追加されることです。
変数を使用することで、ユーザーのコードにその名前の変数が含まれている場合に
自動的に名前が変更されます。ローカル変数はすべて、
できません。
ブロックを強調
コードの実行中に現在実行中のブロックをハイライト表示すると、
プログラムの動作を理解できますハイライト表示は、JavaScript コードを生成する前に STATEMENT_PREFIX
を設定することで、ステートメント単位で行うことができます。
javascriptGenerator.STATEMENT_PREFIX = 'highlightBlock(%1);\n';
javascriptGenerator.addReservedWords('highlightBlock');
highlightBlock
を定義して、ワークスペース上のブロックにマークを付けます。
function highlightBlock(id) {
workspace.highlightBlock(id);
}
これにより、ステートメント highlightBlock('123');
が前に追加されます。
すべてのステートメント(123
は、変換されるブロックのシリアル番号)
ハイライト表示されます。
無限ループ
生成されるコードは常に構文が正しいことが保証されますが、無限ループが含まれている可能性があります。2024 年に
問題の停止は
Blockly のスコープです
カウンタを維持し、反復処理が行われるたびに減らします。
これを行うには、javascriptGenerator.INFINITE_LOOP_TRAP
をコードに
すべてのループとすべての関数に挿入されます。以下に例を示します。
window.LoopTrap = 1000;
javascriptGenerator.INFINITE_LOOP_TRAP = 'if(--window.LoopTrap == 0) throw "Infinite loop.";\n';
var code = javascriptGenerator.workspaceToCode(workspace);
例
こちらの ライブデモ 基本的なスキルを習得できます。
JS インタープリタ
ユーザーのブロックを適切に実行することを真剣に考えている場合は、JS-Interpreter プロジェクトが適しています。このプロジェクトは Blockly とは別個ですが、Blockly 用に特別に作成されています。
- 任意の速度でコードを実行できます。
- 一時停止/再開/ステップスルーの実行。
- 実行時にブロックをハイライト表示します。
- ブラウザの JavaScript から完全に分離されています。
インタープリタを実行する
まず、GitHub から JS-Interpreter をダウンロードします。
次に、これをページに追加します。
<script src="acorn_interpreter.js"></script>
最も簡単な呼び出す方法は、JavaScript を生成し、 コードを実行します。
var code = javascriptGenerator.workspaceToCode(workspace);
var myInterpreter = new Interpreter(code);
myInterpreter.run();
通訳者をステップさせる
コードをより遅く、またはより制御された方法で実行するには、run
の呼び出しをステップするループに置き換えます(この場合は 10 ミリ秒ごとに 1 ステップ)。
function nextStep() {
if (myInterpreter.step()) {
setTimeout(nextStep, 10);
}
}
nextStep();
各ステップは行でもブロックでもなく、セマンティック単位です。 非常に詳細です。
API を追加する
JS インタープリタは、ブラウザから完全に隔離されたサンドボックスです。 外部とアクションを実行するブロックには、API を 説明します。詳細については、 JS Interpreter のドキュメント まず、アラート ブロックとプロンプト ブロックをサポートするために必要な API を紹介します。
function initApi(interpreter, globalObject) {
// Add an API function for the alert() block.
var wrapper = function(text) {
return alert(arguments.length ? text : '');
};
interpreter.setProperty(globalObject, 'alert',
interpreter.createNativeFunction(wrapper));
// Add an API function for the prompt() block.
wrapper = function(text) {
return prompt(text);
};
interpreter.setProperty(globalObject, 'prompt',
interpreter.createNativeFunction(wrapper));
}
次に、initApi 関数を渡すようにインタープリタの初期化を変更します。
var myInterpreter = new Interpreter(code, initApi);
デフォルトのブロックセットで、インタープリタのカスタム API が必要なブロックは、アラート ブロックとプロンプト ブロックの 2 つだけです。
highlightBlock()
を接続中
JS Interpreter で実行する場合、highlightBlock()
を実行する必要がある
ユーザーがプログラムをステップ実行すると、すぐにサンドボックスの外に現れます。タスク
関数を取得するラッパー関数 highlightBlock()
を作成します。
ネイティブ関数として登録します。
function initApi(interpreter, globalObject) {
// Add an API function for highlighting blocks.
var wrapper = function(id) {
return workspace.highlightBlock(id);
};
interpreter.setProperty(globalObject, 'highlightBlock',
interpreter.createNativeFunction(wrapper));
}
より高度なアプリケーションでは、コードを使わずにステップを繰り返し実行 ハイライト コマンドに到達するまで一時停止し、一時停止します。この戦略では、 行ごとに行われます。次の例ではこの方法を使用しています。
JS インタープリタの例
こちらの ライブデモ 一つひとつ解説しますそして こちらのデモ 他の非同期動作に使用するのに適した例として、wait ブロックが含まれている (音声や音声、ユーザー入力など)。