# How to Generate BlocklyDuino Block (如何生成Block)
# 進入BlocklyDuino (or BlockyDuino-for-LinkIt) \blockly 的資料夾當中
在BlocklyDuino(or BlockyDuino-for-LinkIt)\blockly中有兩個資料夾:
- blocks
<!-- - 當中的資料對應的是 Blocklyduino 中可被使用的Block-->
- Blocks 資料夾下的程式碼,對應各種 Blocks,若是要新增一個 Block,則需在此新增,其中 block 的板型可依需求自行設定。
- Block 的 code 的範例:
```
Blockly.Blocks['servo_read'] = {
init: function () {
this.setHelpUrl(Blockly.Msg.SERVO_READ_HELPURL);
this.setColour(Blockly.Blocks.servo.HUE);
this.appendDummyInput()
.appendField(new Blockly.FieldImage(Blockly.Blocks.servo.image, 64, 64))
.appendField(Blockly.Msg.SERVO_READ_TEXT1)
.appendField(new Blockly.FieldDropdown(profile.default.digital), "PIN")
.appendField(Blockly.Msg.SERVO_READ_TEXT2);
this.setInputsInline(true);
this.setOutput(true, "Number");
this.setTooltip(Blockly.Msg.SERVO_READ_TOOLTIP);
}
};
```
- generator\arduino
<!-- - 當中的資料對應的是對映 (Map) 在Blocklyduino所製造的程式碼至Arduino code-->
- Generator 裡面的程式碼,負責將 Blocks 資料夾下的 blocks 轉換為 Arduino code。
- Generatro 的 code 的樣板大致如下:
```
Blockly.Arduino.servo_read = function() {
var pin = this.getFieldValue('PIN');
Blockly.Arduino.definitions_['define_servo'] = '#include <Servo.h>';
Blockly.Arduino.definitions_['define_class_servo_'+ pin] = 'Servo myservo' + pin + ';';
var code = 'myservo' + pin + '.read()';
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
```
Generator 會生成對應 Blocks 的 Arduino code,因此在 BlocklyDuino\blockly\Blocks 資料夾下的檔案或 function,在 Generator 端都要有一個同樣函數名稱的對應。
- 比如:inout.js這個檔案在BlocklyDuino\blockly以及Generator/arduino都有一份同檔名但不同內文的檔案
- 在blocky的inout.js是負責處理各個Block的外觀及功能描述
- 在Generator的inout.js是負責把在BlocklyDuino描述的功能轉換至Arduino Code。
# 開始生成自己的Block
接下來,簡單講解 Block 的 code 所代表的意義。在Block中,以servo.js的讀取servo狀態為例:
```
Blockly.Blocks['servo_read'] = {
init: function () {
this.setHelpUrl(Blockly.Msg.SERVO_READ_HELPURL); //預設值
this.setColour(Blockly.Blocks.servo.HUE); //預設值
this.appendDummyInput() //input
.appendField(new Blockly.FieldImage(Blockly.Blocks.servo.image, 64, 64))
.appendField(Blockly.Msg.SERVO_READ_TEXT1)
.appendField(new Blockly.FieldDropdown(profile.default.digital), "PIN")
.appendField(Blockly.Msg.SERVO_READ_TEXT2);
this.setInputsInline(true);
this.setOutput(true, "Number");
this.setTooltip(Blockly.Msg.SERVO_READ_TOOLTIP);
}
};
```
其中的 `Blocky.Blocks['function name']` 務必要注意兩邊資料夾的名稱要相同,
而您將可以在 `init:function() { code.....}` 完成您要做的事情。
在 generator 的部分,仍以servo.js的讀取servo狀態為例:
```
Blockly.Arduino.servo_read = function() {
var pin = this.getFieldValue('PIN');
Blockly.Arduino.definitions_['define_servo'] = '#include <Servo.h>';
Blockly.Arduino.definitions_['define_class_servo_'+ pin] = 'Servo myservo' + pin + ';';
var code = 'myservo' + pin + '.read()';
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
```
主要Map至Arduino的Function用法: `Blockly.Arduino.definitions_['function name']= 'arduino function'`
其中要注意的是,
在同一個Block中,function name 的部分要避免相同的名字,否則在Map至Arduino Code中的時候將會產生後宣告的function覆蓋掉前面寫過的相同Function的情形。
關於`Blockly.Arduino.ORDER_ATOMIC`,則是會告訴 Blockyduino 現在即將要進到下一個 Block 而不是進到子Block運行。
Example:
![](https://i.imgur.com/6uiGAhb.png)
- 當item=1000 賦值完畢後,function將會return `Blockly.Arduino.ORDER_ATOMIC`,並開始執行下一個Block的指令。
## 常用的函數指令:
- this.setHelpUrl 用於塞入網址,可以在IDE中點HELP即可進入。
- this.setColour 塞的是Block的色調
- this.setPreviousStatement & this.setNextStatement 決定能不能被插 & 插入Block
- appendDummyInput() 告訴程式此處要塞字串
- appendField 則是引導程式到字串的地方
- 延伸用法:appendField(new Blockly.FieldDropdown(OPERATORS), 'OP');
- 可以插入圖片 如下: `.appendField(new Blockly.FieldImage(Blockly.Blocks.servo.image, 64, 64))`
- setCheck 確認型別
- setAlign 確認邊界
- setTooltip 是將blocky\msg資料夾中相關的Block說明訊息映射至Block中供使用者可以在IDE中參閱。
- FieldDropdown 下拉式選單
- 以appendField(new Blockly.FieldDropdown(OPERATORS), 'OP')為例,OPERATORS是變數名稱。在Logic裡面的範例中,OPERATOR會引導到**在同一個Block的Tooltip變數中,再轉換成字串**
- setOutput 變成Data拼圖,類似數據的情形
- Blockly.Arduino.statementToCode 對應到this.statementinput.
- this.appendValueInput 允許你讓Data Block從右邊插入
- .setcheck 則是要你決定輸入的狀態。
- **可以允許多個setcheck**
- this.appendDummyInput 則是沒有讓Data Block從右邊插入的功能,**但是可以讓你在下面繼續塞Block內部的字串,也不需要在appendDummyinput()裡面宣告特定的文字,更可以塞一些選項**
- Example:
```
this.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField(Blockly.Msg.LINKIT_SET_LBLE_ATTRIBUTE)
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.LINKIT_SET_LBLE_READ, "LBLE_READ"], [Blockly.Msg.LINKIT_SET_LBLE_WRITE, "LBLE_WRITE"], [Blockly.Msg.LINKIT_SET_LBLE_READ_WRITE, "LBLE_READ | LBLE_WRITE"]]), 'TYPE');
```
# 更改在BlockyDuino\Blocky\msg目錄下的js檔案:
- message.js
- 用途是將Block資料夾中的變數名稱對映至實際的Block上,使BlockyDuino的使用者可以知道每個Block的功能。
- ![](https://i.imgur.com/gODX9hB.png)
- message.js的功能便是將 "CommentOut" 這段字串印至Block上
- zn.js (位於BlockyDuino\Blocky\msg\js)
- 同message.js,但會將資料對映的語系換成中文。
# 最後一步:將所有新增的Block加入category中
- catagory.js(目錄)
- 還要改同目錄下的js\setCategoryCharacter
- 用途是為了生成目錄來存放Block
8.在Command line用`sh make.sh`去build,並將offline-editor 拖曳丟入 chrome : extension 完成。
- 注意:假如有換行字元的原因而無法成功build的時候,請改為使用: `sh make0.sh`