美文网首页
Blockly脚本执行

Blockly脚本执行

作者: 知晨创客坊 | 来源:发表于2020-04-02 08:46 被阅读0次

    积木代码编写

    Blockly应用程序需要将积木转换为代码来执行。添加积木JSON定义后,需转到generators/目录并选择与您要生成的语言( JavaScript, Python, PHP, Lua, Dart等)相对应的子目录,编写积木执行代码。

    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];
    };
    

    任何积木的代码生成器需要生成参数和元素数据。通常使用几种函数辅助获取:
    getFieldValue、valueToCode、statementToCode

    getFieldValue

    block.getFieldValue('END')
    此函数从指定名称的元素中返回值。

    • 对于文本元素,此函数返回输入的文本。例如“ Hello World”。
    • 如果是下拉菜单,此函数将返回与所选选项关联的语言无关的文本。
    • 对于变量下拉列表,此函数返回变量下拉列表的对应的名称。
      要获取生成的代码中使用的Blockly变量名称,需使用以下调用方式:
      Blockly.JavaScript.variableDB_.getName(block.getFieldValue('VAR'), Blockly.Variables.NAME_TYPE);

    valueToCode

    Blockly.JavaScript.valueToCode(block, 'FROM', Blockly.JavaScript.ORDER_ADDITION) || '0'
    此函数查找block值输入('FROM')的文本,然后将文本作为字符串返回。在未卡合输入的情况下,此函数返回null,这就是为什么通常在函数后加上布尔值“或”和默认值的原因。因此,在上面的示例中,如果没有积木附加到名为“ FROM”的输入,则此输入的默认代码将为字符串“ 0”。
    第三个参数指定嵌入所需的操作信息的顺序。每种语言生成器都有一个优先顺序列表。

    statementToCode

    Blockly.JavaScript.statementToCode(block, 'DO')
    此函数查找卡合到指定语句输入的嵌套积木堆栈,为该堆栈生成代码,缩进代码,然后将代码作为字符串返回。如果未卡合输入,此函数将返回一个空字符串。

    并行化

    Blockly并不提供脚本的执行的方法,而是提供将脚本转为指定的高级语言,由用户执行高级语言,从而完成脚本的执行。

    串行程序

    大多数Blockly应用程序都是串行程序。用户将按积木堆叠顺序执行。


    串行程序 -c

    工作空间中的每个(非禁用)积木都将构成程序的一部分。如果有多个堆栈积木,则首先执行较高的堆栈。

    工作空间可以随时导出为可执行代码。此代码可以在JavaScript的客户端(使用eval或JS Interpreter)执行,也可以在服务器端以任何语言执行。

    下面是获取JavaScript代码。

    //获取代码
    var code = Blockly.JavaScript.workspaceToCode(demoWorkspace);
    //执行代码
    eval(code);
    

    并行程序

    一些Blockly应用程序选择并行而非串行执行所有积木堆栈。例如音乐应用程序,其中鼓循环与旋律同时运行。
    实现并行执行的一种方法是使用Hat积木生成多个代码段:

    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);
    }
    

    如果目标语言是JavaScript,则可以使用该数组创建多个JS解释器以同时执行。

    事件驱动程序

    事件处理程序只是由系统而不是由程序调用的函数。一些开发人员喜欢在事件积木的顶部添加一个“帽子”,以使它们看起来与其他积木不同。这不是Blockly的默认外观,但可以通过设置Blockly.BlockSvg.START_HAT = true;或添加主题并在block style上设置hat选项来添加。


    帽子积木 -c

    JS Interpreter

    JS-Interpreter 是用 JavaScript写的具有沙箱环境的JavaScript 解析器。 它可以让你任意的, 一行一行地执行JavaScript 代码。它的执行过程与主要的 JavaScript 代码环境是分离开的,JS-Interpreter 的多个实例可以允许多线程并发JavaScript, 而无需使用Web Workers。

    在执行积木堆栈时,有时需要执行的速度较慢,单步执行,每执行一条js,积木高亮显示,更容易发现积木执行位置,观察整个执行过程,可以使用JS Interpreter配合积木的执行。

    使用方法

    引入这两个 JavaScript 源代码

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

    然后, 实例化一个 interpreter, 并且把你需要还原的 JavaScript 代码放进去。

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

    为了去一步一步地跑这些代码, 需要重复地去调用 step 函数, 直到它返回 false

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

    或者, 如果已知代码里面没有死循环, 则可以直接调用 run 函数执行一次完成全部的 step
    myInterpreter.run();
    API createNativeFunction的调用可以在创建的时候被添加到 interpreter, 下面是添加了 函数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结合积木使用

    积木堆栈执行时,先生成代码,代码执行的过程中会通过JS Interpreter调用wrapper函数,对应的会设置highlightBlock函数,从而设置积木行为。

    //绑定积木code执行highlightBlock时,调用wrapper函数
    var wrapper = function(id) {
        id = id ? id.toString() : '';
    return interpreter.createPrimitive(highlightBlock(id));
    };
    interpreter.setProperty(scope, 'highlightBlock',
    interpreter.createNativeFunction(wrapper));
    //设置积木高亮显示
    function highlightBlock(id) {
        demoWorkspace.highlightBlock(id);
        highlightPause = true;
    }
    

    相关文章

      网友评论

          本文标题:Blockly脚本执行

          本文链接:https://www.haomeiwen.com/subject/pkzfyhtx.html