wait block for the blockly

971 views
Skip to first unread message

ken.lai...@gmail.com

unread,
May 18, 2017, 10:19:49 AM5/18/17
to Blockly
As far as I have tested, method 1 is stupid. Then, I moved on to method 2 by using JS interpreter. 

However, the code for "var ms = 2000;ms += new Date().getTime();while (new Date() < ms) { };" is ignored. this line of code don't be executed.

Method 1:

Blockly.Blocks['wait'] = {
  init: function() {
    this.appendDummyInput()
        .appendField("wait 2 second");
    this.setInputsInline(false);
    this.setPreviousStatement(true, null);
    this.setNextStatement(true, null);
    this.setColour(230);
    this.setTooltip('');
    this.setHelpUrl('');
  }
};

Blockly.JavaScript['wait'] = function(block) {
  // TODO: Assemble JavaScript into code variable.
  //var code = 'window.setTimeout(3000);';
  //var code = 'if (5==3) alert(3232);';
  //var code = 'prompt(321);';
    var code = 'var ms = 2000;ms += new Date().getTime();while (new Date() < ms) { };';

  return code;
};

   function runCode() {
      // Generate JavaScript code and run it.
      
      var code = Blockly.JavaScript.workspaceToCode(workspace);
 
window.LoopTrap = 1000;
      //Blockly.JavaScript.INFINITE_LOOP_TRAP =
          'if (--window.LoopTrap == 0) throw "Infinite loop.";\n';
      Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
      try {
        eval(code);
      } catch (e) {
        alert(e);
      }

        
    }

function initApi(interpreter, scope) {
// Add an API function for the alert() block.
var wrapper = function(text) {
text = text ? text.toString() : '';
return interpreter.createPrimitive(alert(text));
};
interpreter.setProperty(scope, 'alert',
interpreter.createNativeFunction(wrapper));
/*
wrapper = function(text) {
text = text ? text.toString() : '';
return interpreter.createPrimitive(wait(text));
};
interpreter.setProperty(scope, 'wait',
interpreter.createNativeFunction(wrapper));*/
// Add an API function for the prompt() block.
wrapper = function(text) {
text = text ? text.toString() : '';
return interpreter.createPrimitive(prompt(text));
};
interpreter.setProperty(scope, 'prompt',
interpreter.createNativeFunction(wrapper));
}

    function runCode() {
      // Generate JavaScript code and run it.
      
      var code = Blockly.JavaScript.workspaceToCode(workspace);
      alert(code);  
      myInterpreter = new Interpreter(code,initApi);
      myInterpreter.run();
 

        
    }

Anyone have idea? Please advise. Thank you so much!!!!!

PS. From the line below, I have already tested. They just using the step function only,


Rachel Fenichel

unread,
May 18, 2017, 4:40:26 PM5/18/17
to Blockly
Are you hitting the infinite loop trap?

Andrew n marshall

unread,
May 18, 2017, 6:34:09 PM5/18/17
to ken.lai...@gmail.com, blo...@googlegroups.com
Ken,

did you mean...
var code = 'var ms = 2000;ms += new Date().getTime();' +
    'while (new Date().getTime() < ms) { };';

That said, this will lock up the browser context, or any other JavaScript VM.

I highly recommend looking at the asynchronous execution interpreter demo:

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

ken.lai...@gmail.com

unread,
May 18, 2017, 11:12:25 PM5/18/17
to Blockly, ken.lai...@gmail.com

It works!! Thank you Andrew!!!

As I found that the link doesn't work in the google blockly document.







I think the branch of develop is not migrated to master branch. Thanks so much!!!

However, just one more question. It is necessary that the "setTimeout(runner, 10)" must be included in the code?

    function runCode() {
      if (!myInterpreter) {
        // First statement of this code.
        // Clear the program output.
        resetStepUi(true);
        runButton.disabled = 'disabled';

        // And then show generated code in an alert.
        // In a timeout to allow the outputArea.value to reset first.
        setTimeout(function() {
          alert('Ready to execute the following code\n' +
            '===================================\n' +
            latestCode);

          // Begin execution
          highlightPause = false;
          myInterpreter = new Interpreter(latestCode, initApi);
          runner = function() {
            if (myInterpreter) {
              var hasMore = myInterpreter.run();
              if (hasMore) {
                // Execution is currently blocked by some async call.
                // Try again later.
                setTimeout(runner, 10);
              } else {
                // Program is complete.
                outputArea.value += '\n\n<< Program complete >>';
                resetInterpreter();
                resetStepUi(false);
              }
            }
          };
          runner();
        }, 1);
        return;
      }








Andrew n marshall於 2017年5月19日星期五 UTC+8上午6時34分09秒寫道:
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.

Andrew n marshall

unread,
May 19, 2017, 3:40:24 PM5/19/17
to blo...@googlegroups.com
Yes, the timeout is necessary. When interpreter.run() returns, the interpreter has handed full control back to its calling context. When the waitForSeconds() returns and wrapper calls its callback , it just sets the internal interpreter state saying the interpreter can run again. This is why the runner repeatedly attempts to call .run(), attempting to pick up where waitForSeconds() left off.

That said, the 10 milliseconds can be adjusted to some reasonable value. At 10ms, it will continue the "thread" fast enough to pick up within the duration of a 100FPS animation frame.

To unsubscribe from this group and stop receiving emails from it, send an email to blockly+unsubscribe@googlegroups.com.

ken.lai...@gmail.com

unread,
May 21, 2017, 10:10:47 PM5/21/17
to Blockly
I see! Thanks!

If I do not have your example, I can't achieve this function.

Thanks again! Andrew :)

Andrew n marshall於 2017年5月20日星期六 UTC+8上午3時40分24秒寫道:
Reply all
Reply to author
Forward
0 new messages