setTimeout setInterval implementation with JS Interpreter

210 views
Skip to first unread message

Mike Raptakis

unread,
Jun 30, 2023, 5:09:10 AM6/30/23
to Blockly
Good evening to all,

I'm working on a project that uses Blockly and JS Interpreter to provide an interactive programming environment.

I would like to provide blocks equivalent to the setTimeout, setInterval and clearTimeout, clearInterval functions and I have made the following blocks (clear is a block that calls clearTimeout or clearInterval respectively). I also followed the JS Interpreter issue #201 for code generation.

Screenshot from 2023-06-30 11-42-04.png

Running the program shown in the image, I get the error 'interpreter.queueFunction is not a function'.

The code from the issue is

const timeouts = {};
let timeoutcnt = 0;
const intervals = {};
let intervalcnt = 0;

function executeAfter(fn, timeout) {
const timeoutId = ++timeoutcnt;
const _this = this;
timeouts[timeoutId] = setTimeout(function () {
if (!timeouts[timeoutId]) {
return;
}

delete timeouts[timeoutId];
interpreter.queueFunction(fn, _this);
interpreter.run();
}, timeout);

return `timeout:${timeoutId}`;
}

javascriptGenerator.addReservedWords('executeAfter');
interpreter.setProperty(
globalObject,
'executeAfter',
interpreter.createNativeFunction(executeAfter)
);

function executeRepeatedly(fn, timeout) {
const intervalId = ++intervalcnt;
const _this = this;
intervals[intervalId] = setInterval(function () {
interpreter.queueFunction(fn, _this);
interpreter.run();
}, timeout);

return `interval:${intervalId}`;
}

javascriptGenerator.addReservedWords('executeRepeatedly');
interpreter.setProperty(
globalObject,
'executeRepeatedly',
interpreter.createNativeFunction(executeRepeatedly)
);

const clearTimeoutOrInterval = info => {
const [type, id] = info.split(':');

const _id = Number(id);
switch (type) {
case 'timeout':
clearTimeout(timeouts[_id]);
delete timeouts[_id];
break;
case 'interval':
clearInterval(intervals[_id]);
delete intervals[_id];
break;
default:
break;
}
};

javascriptGenerator.addReservedWords('clearTimeoutOrInterval');
interpreter.setProperty(
globalObject,
'clearTimeoutOrInterval',
interpreter.createNativeFunction(clearTimeoutOrInterval)
);

Any advice on what I'm doing wrong?

Thank you in advance.

Christopher Allen

unread,
Jun 30, 2023, 10:51:56 AM6/30/23
to blo...@googlegroups.com
Hi Mike,

I would like to provide blocks equivalent to the setTimeout, setInterval and clearTimeout, clearInterval functions and I have made the following blocks (clear is a block that calls clearTimeout or clearInterval respectively). I also followed the JS Interpreter issue #201 for code generation.

You will note that PR #201 has never been merged; the functionality it aims to provide does not currently exist in JS Interpreter.

Running the program shown in the image, I get the error 'interpreter.queueFunction is not a function'.

Alas queueFunction is one of the necessary features added by #201.

So, at the moment JS Interpreter does not support setTimeout etc.  There are a few ways forward:
  • You could try cleaning up that PR and applying the changes to your own fork of JS Interpreter.  It's not been reviewed, so we can really make no guarantees about its trustworthiness, but it does seem reasonably well thought-out, so there's a good chance it will do what you want it to and not do anything too undesirable.  You'll have to figure out how to resolve the merge conflicts but they shouldn't be too bad as JS Interpreter has not changed significantly in some years.
  • You could wait and see if Neil is interested in having us review and merge the PR; this would give a bit better assurance that it is trustworthy.  The fact that it has not been merged after several years already does seem like a bad sign, but I have just sent him a reminder and will try to chase him for a decision about this.
  • You could implement the features from scratch yourself.  In addition to the approach taken by Webifi in #201 you might be interested in looking at the implementation of a similar set of features I did for the Code City interpreter—which started out as a fork of JS Interpreter.  The most relevant pieces are the Interpreter.Thread classthe Interpreter.prototype.createThread method (roughly equivalent to queueFunction), the Thread native built-in, and the implementation of setTimeout itself, which is a polyfill that uses the Thread constructor.

Best wishes,

Christopher

Neil Fraser

unread,
Jul 29, 2023, 9:20:35 PM7/29/23
to blo...@googlegroups.com
As of a few minutes ago, JS-Interpreter supports setTimeout, clearTimeout, setInterval, and clearInterval.
Enjoy!

--
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+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/blockly/CAN0w5ebVKBEgnCWqzD8rpuZ7e%2B35AZAh1%2BV%3DKd-sdoYW88VDsQ%40mail.gmail.com.


--
Neil Fraser, Switzerland
https://neil.fraser.name

Mike Raptakis

unread,
Jul 30, 2023, 9:28:28 AM7/30/23
to Blockly
That it's excellent! Thank you for informing me
Reply all
Reply to author
Forward
0 new messages