Blockly腳本執(zhí)行

積木代碼編寫

Blockly應(yīng)用程序需要將積木轉(zhuǎn)換為代碼來執(zhí)行。添加積木JSON定義后墨缘,需轉(zhuǎn)到generators/目錄并選擇與您要生成的語言( JavaScript, Python, PHP颈娜, Lua, Dart等)相對(duì)應(yīng)的子目錄浙宜,編寫積木執(zhí)行代碼揭鳞。

Blockly.JavaScript['text_indexOf'] = function(block) {
  // Search the text for a substring.
  var operator = block.getFieldValue('END') == 'FIRST' ? 'indexOf' : 'lastIndexOf';
  var subString = Blockly.JavaScript.valueToCode(block, 'FIND',
      Blockly.JavaScript.ORDER_NONE) || '\'\'';
  var text = Blockly.JavaScript.valueToCode(block, 'VALUE',
      Blockly.JavaScript.ORDER_MEMBER) || '\'\'';
  var code = text + '.' + operator + '(' + subString + ')';
  return [code, Blockly.JavaScript.ORDER_MEMBER];
};

任何積木的代碼生成器需要生成參數(shù)和元素?cái)?shù)據(jù)。通常使用幾種函數(shù)輔助獲劝鹉巍:
getFieldValue野崇、valueToCode、statementToCode

getFieldValue

block.getFieldValue('END')
此函數(shù)從指定名稱的元素中返回值亩钟。

  • 對(duì)于文本元素乓梨,此函數(shù)返回輸入的文本。例如“ Hello World”清酥。
  • 如果是下拉菜單扶镀,此函數(shù)將返回與所選選項(xiàng)關(guān)聯(lián)的語言無關(guān)的文本。
  • 對(duì)于變量下拉列表焰轻,此函數(shù)返回變量下拉列表的對(duì)應(yīng)的名稱臭觉。
    要獲取生成的代碼中使用的Blockly變量名稱,需使用以下調(diào)用方式:
    Blockly.JavaScript.variableDB_.getName(block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);

valueToCode

Blockly.JavaScript.valueToCode(block, 'FROM', Blockly.JavaScript.ORDER_ADDITION) || '0'
此函數(shù)查找block值輸入('FROM')的文本辱志,然后將文本作為字符串返回蝠筑。在未卡合輸入的情況下,此函數(shù)返回null揩懒,這就是為什么通常在函數(shù)后加上布爾值“或”和默認(rèn)值的原因什乙。因此,在上面的示例中已球,如果沒有積木附加到名為“ FROM”的輸入臣镣,則此輸入的默認(rèn)代碼將為字符串“ 0”。
第三個(gè)參數(shù)指定嵌入所需的操作信息的順序智亮。每種語言生成器都有一個(gè)優(yōu)先順序列表忆某。

statementToCode

Blockly.JavaScript.statementToCode(block, 'DO')
此函數(shù)查找卡合到指定語句輸入的嵌套積木堆棧,為該堆棧生成代碼阔蛉,縮進(jìn)代碼弃舒,然后將代碼作為字符串返回。如果未卡合輸入馍忽,此函數(shù)將返回一個(gè)空字符串棒坏。

并行化

Blockly并不提供腳本的執(zhí)行的方法燕差,而是提供將腳本轉(zhuǎn)為指定的高級(jí)語言,由用戶執(zhí)行高級(jí)語言坝冕,從而完成腳本的執(zhí)行徒探。

串行程序

大多數(shù)Blockly應(yīng)用程序都是串行程序。用戶將按積木堆疊順序執(zhí)行喂窟。


串行程序 -c

工作空間中的每個(gè)(非禁用)積木都將構(gòu)成程序的一部分测暗。如果有多個(gè)堆棧積木,則首先執(zhí)行較高的堆棧磨澡。

工作空間可以隨時(shí)導(dǎo)出為可執(zhí)行代碼碗啄。此代碼可以在JavaScript的客戶端(使用eval或JS Interpreter)執(zhí)行,也可以在服務(wù)器端以任何語言執(zhí)行稳摄。

下面是獲取JavaScript代碼稚字。

//獲取代碼
var code = Blockly.JavaScript.workspaceToCode(demoWorkspace);
//執(zhí)行代碼
eval(code);

并行程序

一些Blockly應(yīng)用程序選擇并行而非串行執(zhí)行所有積木堆棧。例如音樂應(yīng)用程序厦酬,其中鼓循環(huán)與旋律同時(shí)運(yùn)行胆描。
實(shí)現(xiàn)并行執(zhí)行的一種方法是使用Hat積木生成多個(gè)代碼段:

var xml = Blockly.Xml.workspaceToDom(workspace);
// Find and remove all top blocks.
var topBlocks = [];
for (var i = xml.childNodes.length - 1, node; block = xml.childNodes[i]; i--) {
  if (block.tagName == 'BLOCK') {
    xml.removeChild(block);
    topBlocks.unshift(block);
  }
}
// Add each top block one by one and generate code.
var allCode = [];
for (var i = 0, block; block = topBlocks[i]; i++) {
  var headless = new Blockly.Workspace();
  xml.appendChild(block);
  Blockly.Xml.domToWorkspace(xml, headless);
  allCode.push(Blockly.JavaScript.workspaceToCode(headless));
  headless.dispose();
  xml.removeChild(block);
}

如果目標(biāo)語言是JavaScript,則可以使用該數(shù)組創(chuàng)建多個(gè)JS解釋器以同時(shí)執(zhí)行仗阅。

事件驅(qū)動(dòng)程序

事件處理程序只是由系統(tǒng)而不是由程序調(diào)用的函數(shù)昌讲。一些開發(fā)人員喜歡在事件積木的頂部添加一個(gè)“帽子”,以使它們看起來與其他積木不同减噪。這不是Blockly的默認(rèn)外觀短绸,但可以通過設(shè)置Blockly.BlockSvg.START_HAT = true;或添加主題并在block style上設(shè)置hat選項(xiàng)來添加。


帽子積木 -c

JS Interpreter

JS-Interpreter 是用 JavaScript寫的具有沙箱環(huán)境的JavaScript 解析器筹裕。 它可以讓你任意的, 一行一行地執(zhí)行JavaScript 代碼醋闭。它的執(zhí)行過程與主要的 JavaScript 代碼環(huán)境是分離開的,JS-Interpreter 的多個(gè)實(shí)例可以允許多線程并發(fā)JavaScript, 而無需使用Web Workers饶碘。

在執(zhí)行積木堆棧時(shí)目尖,有時(shí)需要執(zhí)行的速度較慢,單步執(zhí)行扎运,每執(zhí)行一條js,積木高亮顯示饮戳,更容易發(fā)現(xiàn)積木執(zhí)行位置豪治,觀察整個(gè)執(zhí)行過程,可以使用JS Interpreter配合積木的執(zhí)行扯罐。

使用方法

引入這兩個(gè) JavaScript 源代碼

<script src="acorn.js"></script>
<script src="interpreter.js"></script>

然后, 實(shí)例化一個(gè) interpreter, 并且把你需要還原的 JavaScript 代碼放進(jìn)去负拟。

var myCode = 'var a=1; for(var i=0;i<4;i++){a*=i;} a;';
var myInterpreter = new Interpreter(myCode);

為了去一步一步地跑這些代碼, 需要重復(fù)地去調(diào)用 step 函數(shù), 直到它返回 false

function nextStep() {
  if (myInterpreter.step()) {
    window.setTimeout(nextStep, 0);
  }
}
nextStep();

或者, 如果已知代碼里面沒有死循環(huán), 則可以直接調(diào)用 run 函數(shù)執(zhí)行一次完成全部的 step
myInterpreter.run();
API createNativeFunction的調(diào)用可以在創(chuàng)建的時(shí)候被添加到 interpreter, 下面是添加了 函數(shù)alert() 和 變量 url。

var initFunc = function(interpreter, scope) {
  interpreter.setProperty(scope, 'url', String(location));

  var wrapper = function(text) {
    return alert(text);
  };
  interpreter.setProperty(scope, 'alert',
      interpreter.createNativeFunction(wrapper));
};
var myInterpreter = new Interpreter(myCode, initFunc);

JS Interpreter結(jié)合積木使用

積木堆棧執(zhí)行時(shí)歹河,先生成代碼掩浙,代碼執(zhí)行的過程中會(huì)通過JS Interpreter調(diào)用wrapper函數(shù)花吟,對(duì)應(yīng)的會(huì)設(shè)置highlightBlock函數(shù),從而設(shè)置積木行為厨姚。

//綁定積木code執(zhí)行highlightBlock時(shí)衅澈,調(diào)用wrapper函數(shù)
var wrapper = function(id) {
    id = id ? id.toString() : '';
return interpreter.createPrimitive(highlightBlock(id));
};
interpreter.setProperty(scope, 'highlightBlock',
interpreter.createNativeFunction(wrapper));
//設(shè)置積木高亮顯示
function highlightBlock(id) {
    demoWorkspace.highlightBlock(id);
    highlightPause = true;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市谬墙,隨后出現(xiàn)的幾起案子今布,更是在濱河造成了極大的恐慌,老刑警劉巖拭抬,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件部默,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡造虎,警方通過查閱死者的電腦和手機(jī)傅蹂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來算凿,“玉大人贬派,你說我怎么就攤上這事∨烀剑” “怎么了搞乏?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)戒努。 經(jīng)常有香客問我请敦,道長(zhǎng),這世上最難降的妖魔是什么储玫? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任侍筛,我火速辦了婚禮,結(jié)果婚禮上撒穷,老公的妹妹穿的比我還像新娘匣椰。我一直安慰自己,他們只是感情好端礼,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布禽笑。 她就那樣靜靜地躺著,像睡著了一般蛤奥。 火紅的嫁衣襯著肌膚如雪佳镜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天凡桥,我揣著相機(jī)與錄音蟀伸,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛啊掏,可吹牛的內(nèi)容都是我干的蠢络。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼迟蜜,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼刹孔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起小泉,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤芦疏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后微姊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酸茴,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年兢交,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了薪捍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡配喳,死狀恐怖酪穿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情晴裹,我是刑警寧澤被济,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站涧团,受9級(jí)特大地震影響只磷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泌绣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一钮追、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧阿迈,春花似錦元媚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至崎页,卻和暖如春鞠绰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背飒焦。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人牺荠。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓翁巍,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親休雌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子灶壶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容