BlocklyのカスタムブロックをJS-Interpreterで実行できるようにしてみます。
JS-Interpreterに関してはBlocklyでコードを実行してみように記載があります。
最初は
コンソールにhogeの文字列を出力する簡単なブロックを登録してみます。
※関数名もhogeにして話を進めます。
作成中のコードに今回のブロックに関するコードを組み込みます。
~/workspace/blockly/custom.js
に下記のコードを組み込みます。
Blockly.Blocks['hoge'] = { init: function() { this.appendDummyInput() .appendField("hoge"); this.setPreviousStatement(true, null); this.setNextStatement(true, null); this.setColour(230); this.setTooltip(""); this.setHelpUrl(""); } };
javascript.javascriptGenerator.forBlock['hoge'] = function(block, generator) { var code = 'hoge();\n'; return code; };
ここでコードの説明用として、hogeブロックにはJavaScriptの組み込み関数にはないhogeという関数を実行することにしています。
JS-Interpreterでhoge関数を実行できるようにします。
Blocklyでコードを実行してみようの記事で作成したコードを下記のように変更します。
~/workspace/blockly/index.html
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)); }
※説明用として、initApiに登録している関数はalertのみにしています。
を
function hoge(){ console.log("hoge"); } 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)); wrapper = function(){ return hoge(); }; interpreter.setProperty(globalObject, 'hoge', interpreter.createNativeFunction(wrapper)); }
に変更します。
ここで注意すべき点としまして、hoge関数を作っておき、initApi内で作成したhoge関数を指定していることです。
hoge関数は引数を持たないので、initApiへの登録で引数の指定を気にする必要はありません。
続いて、
引数を一つ持つ関数について考えてみます。
~/workspace/blockly/custom.js
から先ほど追加したhoge分を削除して、新たに下記のコードを追加します。
Blockly.Blocks['hoge'] = { init: function() { this.appendValueInput("VALUE") .setCheck("String") .appendField(new Blockly.FieldLabelSerializable(""), "VALUE"); this.setPreviousStatement(true, null); this.setNextStatement(true, null); this.setColour(230); this.setTooltip(""); this.setHelpUrl(""); } };
javascript.javascriptGenerator.forBlock['hoge'] = function(block, generator) { var value = generator.valueToCode(block, 'VALUE', javascript.Order.ATOMIC); var code = 'hoge('+value+');\n'; return code; };
~/workspace/blockly/index.html
を下記のように変更します。
function hoge(){ console.log("hoge"); } 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)); wrapper = function(){ return hoge(); }; interpreter.setProperty(globalObject, 'hoge', interpreter.createNativeFunction(wrapper)); }
を
function hoge(text){ console.log(text); } 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)); wrapper = function(text){ return hoge(text); }; interpreter.setProperty(globalObject, 'hoge', interpreter.createNativeFunction(wrapper)); }
のように修正します。
hoge関数に関する箇所に引数を一つ追加しています。
最後に
引数を二つ持つ関数について考えてみます。
~/workspace/blockly/custom.js
から先ほど追加したhoge分を削除して、新たに下記のコードを追加します。
Blockly.Blocks['hoge'] = { init: function() { this.appendValueInput("VALUE") .setCheck("String") .appendField(new Blockly.FieldLabelSerializable(""), "VALUE"); this.appendDummyInput(); this.appendValueInput("VALUE2") .setCheck("String") .setAlign(Blockly.ALIGN_RIGHT) .appendField(new Blockly.FieldLabelSerializable(""), "VALUE2"); this.setOutput(true, null); this.setColour(230); this.setTooltip(""); this.setHelpUrl(""); } };
javascript.javascriptGenerator.forBlock['hoge'] = function(block, generator) { var value = generator.valueToCode(block, 'VALUE', javascript.Order.ATOMIC); var value2 = generator.valueToCode(block, 'VALUE2', javascript.Order.ATOMIC); var code = 'hoge('+value+','+value2+');\n'; return code; };
~/workspace/blockly/index.html
を下記のように変更します。
function hoge(text, text2){ console.log(text+text2); } 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)); wrapper = function(text, text2){ return hoge(text, text2); }; interpreter.setProperty(globalObject, 'hoge', interpreter.createNativeFunction(wrapper)); }
これで引数が二つの関数もJS-Interpreterで実行できるようになりました。
引数が3個以上でも同様の要領で増やすことで対応できます。