diff --git a/playground/index.html b/playground/index.html
index 0d4903d3d..82535807b 100644
--- a/playground/index.html
+++ b/playground/index.html
@@ -79,12 +79,6 @@
-
-
-
-
-
-
diff --git a/src/blocks/scratch3_control.js b/src/blocks/scratch3_control.js
index 1d05a8c7a..e13edefd9 100644
--- a/src/blocks/scratch3_control.js
+++ b/src/blocks/scratch3_control.js
@@ -1,3 +1,5 @@
+var Promise = require('promise');
+
function Scratch3ControlBlocks(runtime) {
/**
* The runtime instantiating this block package.
@@ -38,11 +40,12 @@ Scratch3ControlBlocks.prototype.forever = function(args, util) {
util.startSubstack();
};
-Scratch3ControlBlocks.prototype.wait = function(args, util) {
- util.yield();
- util.timeout(function() {
- util.done();
- }, 1000 * args.DURATION);
+Scratch3ControlBlocks.prototype.wait = function(args) {
+ return new Promise(function(resolve) {
+ setTimeout(function() {
+ resolve();
+ }, 1000 * args.DURATION);
+ });
};
Scratch3ControlBlocks.prototype.if = function(args, util) {
diff --git a/src/blocks/wedo2.js b/src/blocks/wedo2.js
deleted file mode 100644
index d7516bc18..000000000
--- a/src/blocks/wedo2.js
+++ /dev/null
@@ -1,152 +0,0 @@
-
-var YieldTimers = require('../util/yieldtimers.js');
-
-function WeDo2Blocks(runtime) {
- /**
- * The runtime instantiating this block package.
- * @type {Runtime}
- */
- this.runtime = runtime;
-
- /**
- * Current motor speed, as a percentage (100 = full speed).
- * @type {number}
- * @private
- */
- this._motorSpeed = 100;
-
- /**
- * The timeout ID for a pending motor action.
- * @type {?int}
- * @private
- */
- this._motorTimeout = null;
-}
-
-/**
- * Retrieve the block primitives implemented by this package.
- * @return {Object.} Mapping of opcode to Function.
- */
-WeDo2Blocks.prototype.getPrimitives = function() {
- return {
- 'wedo_motorclockwise': this.motorClockwise,
- 'wedo_motorcounterclockwise': this.motorCounterClockwise,
- 'wedo_motorspeed': this.motorSpeed,
- 'wedo_setcolor': this.setColor,
- 'wedo_whendistanceclose': this.whenDistanceClose,
- 'wedo_whentilt': this.whenTilt
- };
-};
-
-/**
- * Clamp a value between a minimum and maximum value.
- * @todo move this to a common utility class.
- * @param {number} val The value to clamp.
- * @param {number} min The minimum return value.
- * @param {number} max The maximum return value.
- * @returns {number} The clamped value.
- * @private
- */
-WeDo2Blocks.prototype._clamp = function(val, min, max) {
- return Math.max(min, Math.min(val, max));
-};
-
-/**
- * Common implementation for motor blocks.
- * @param {string} direction The direction to turn ('left' or 'right').
- * @param {number} durationSeconds The number of seconds to run.
- * @param {Object} util The util instance to use for yielding and finishing.
- * @private
- */
-WeDo2Blocks.prototype._motorOnFor = function(direction, durationSeconds, util) {
- if (this._motorTimeout > 0) {
- // @todo maybe this should go through util
- YieldTimers.resolve(this._motorTimeout);
- this._motorTimeout = null;
- }
- if (typeof window !== 'undefined' && window.native) {
- window.native.motorRun(direction, this._motorSpeed);
- }
-
- var instance = this;
- var myTimeout = this._motorTimeout = util.timeout(function() {
- if (instance._motorTimeout == myTimeout) {
- instance._motorTimeout = null;
- }
- if (typeof window !== 'undefined' && window.native) {
- window.native.motorStop();
- }
- util.done();
- }, 1000 * durationSeconds);
-
- util.yield();
-};
-
-WeDo2Blocks.prototype.motorClockwise = function(argValues, util) {
- this._motorOnFor('right', parseFloat(argValues[0]), util);
-};
-
-WeDo2Blocks.prototype.motorCounterClockwise = function(argValues, util) {
- this._motorOnFor('left', parseFloat(argValues[0]), util);
-};
-
-WeDo2Blocks.prototype.motorSpeed = function(argValues) {
- var speed = argValues[0];
- switch (speed) {
- case 'slow':
- this._motorSpeed = 20;
- break;
- case 'medium':
- this._motorSpeed = 50;
- break;
- case 'fast':
- this._motorSpeed = 100;
- break;
- }
-};
-
-/**
- * Convert a color name to a WeDo color index.
- * Supports 'mystery' for a random hue.
- * @param {string} colorName The color to retrieve.
- * @returns {number} The WeDo color index.
- * @private
- */
-WeDo2Blocks.prototype._getColor = function(colorName) {
- var colors = {
- 'yellow': 7,
- 'orange': 8,
- 'coral': 9,
- 'magenta': 1,
- 'purple': 2,
- 'blue': 3,
- 'green': 6,
- 'white': 10
- };
-
- if (colorName == 'mystery') {
- return Math.floor((Math.random() * 10) + 1);
- }
-
- return colors[colorName];
-};
-
-WeDo2Blocks.prototype.setColor = function(argValues, util) {
- if (typeof window !== 'undefined' && window.native) {
- var colorIndex = this._getColor(argValues[0]);
- window.native.setLedColor(colorIndex);
- }
- // Pause for quarter second
- util.yield();
- util.timeout(function() {
- util.done();
- }, 250);
-};
-
-WeDo2Blocks.prototype.whenDistanceClose = function() {
-};
-
-WeDo2Blocks.prototype.whenTilt = function() {
-};
-
-module.exports = WeDo2Blocks;
diff --git a/src/engine/execute.js b/src/engine/execute.js
index 8fbb73dfc..acff32585 100644
--- a/src/engine/execute.js
+++ b/src/engine/execute.js
@@ -77,7 +77,6 @@ var execute = function (sequencer, thread) {
done: function() {
sequencer.proceedThread(thread);
},
- timeout: thread.addTimeout.bind(thread),
stackFrame: currentStackFrame.executionContext,
startSubstack: function (substackNum) {
sequencer.stepToSubstack(thread, substackNum);
diff --git a/src/engine/runtime.js b/src/engine/runtime.js
index f6ad79f0b..8c4c862e1 100644
--- a/src/engine/runtime.js
+++ b/src/engine/runtime.js
@@ -6,8 +6,7 @@ var util = require('util');
var defaultBlockPackages = {
'scratch3_control': require('../blocks/scratch3_control'),
'scratch3_event': require('../blocks/scratch3_event'),
- 'scratch3_operators': require('../blocks/scratch3_operators'),
- 'wedo2': require('../blocks/wedo2')
+ 'scratch3_operators': require('../blocks/scratch3_operators')
};
/**
diff --git a/src/engine/sequencer.js b/src/engine/sequencer.js
index 81813a141..5eca9c202 100644
--- a/src/engine/sequencer.js
+++ b/src/engine/sequencer.js
@@ -52,16 +52,8 @@ Sequencer.prototype.stepThreads = function (threads) {
// Normal-mode thread: step.
this.startThread(activeThread);
} else if (activeThread.status === Thread.STATUS_YIELD) {
- // Yield-mode thread: resolve timers.
- activeThread.resolveTimeouts();
- if (activeThread.status === Thread.STATUS_YIELD) {
- // Still yielding.
- numYieldingThreads++;
- }
- } else if (activeThread.status === Thread.STATUS_DONE) {
- // Moved to a done state - finish up
- activeThread.status = Thread.STATUS_RUNNING;
- // @todo Deal with the return value
+ // Yielding thread: do nothing for this step.
+ continue;
}
if (activeThread.stack.length === 0 &&
activeThread.status === Thread.STATUS_DONE) {
diff --git a/src/engine/thread.js b/src/engine/thread.js
index 746d7dcc6..d14d83f90 100644
--- a/src/engine/thread.js
+++ b/src/engine/thread.js
@@ -1,5 +1,3 @@
-var YieldTimers = require('../util/yieldtimers.js');
-
/**
* A thread is a running stack context and all the metadata needed.
* @param {?string} firstBlock First block to execute in the thread.
@@ -30,12 +28,6 @@ function Thread (firstBlock) {
* @type {number}
*/
this.status = 0; /* Thread.STATUS_RUNNING */
-
- /**
- * Execution-synced timeouts.
- * @type {number}
- */
- this.timeoutIds = [];
}
/**
@@ -131,29 +123,4 @@ Thread.prototype.yield = function () {
this.status = Thread.STATUS_YIELD;
};
-/**
- * Add an execution-synced timeouts for this thread.
- * See also: util/yieldtimers.js:timeout
- * @param {!Function} callback To be called when the timer is done.
- * @param {number} timeDelta Time to wait, in ms.
- */
-Thread.prototype.addTimeout = function (callback, timeDelta) {
- var timeoutId = YieldTimers.timeout(callback, timeDelta);
- this.timeoutIds.push(timeoutId);
-};
-
-/**
- * Attempt to resolve all execution-synced timeouts on this thread.
- */
-Thread.prototype.resolveTimeouts = function () {
- var newTimeouts = [];
- for (var i = 0; i < this.timeoutIds.length; i++) {
- var resolved = YieldTimers.resolve(this.timeoutIds[i]);
- if (!resolved) {
- newTimeouts.push(this.timeoutIds[i]);
- }
- }
- this.timeoutIds = newTimeouts;
-};
-
module.exports = Thread;
diff --git a/src/util/yieldtimers.js b/src/util/yieldtimers.js
deleted file mode 100644
index 84c6d3259..000000000
--- a/src/util/yieldtimers.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * @fileoverview Timers that are synchronized with the Scratch sequencer.
- */
-var Timer = require('./timer');
-
-function YieldTimers () {}
-
-/**
- * Shared collection of timers.
- * Each timer is a [Function, number] with the callback
- * and absolute time for it to run.
- * @type {Object.}
- */
-YieldTimers.timers = {};
-
-/**
- * Monotonically increasing timer ID.
- * @type {number}
- */
-YieldTimers.timerId = 0;
-
-/**
- * Utility for measuring time.
- * @type {!Timer}
- */
-YieldTimers.globalTimer = new Timer();
-
-/**
- * The timeout function is passed to primitives and is intended
- * as a convenient replacement for window.setTimeout.
- * The sequencer will attempt to resolve the timer every time
- * the yielded thread would have been stepped.
- * @param {!Function} callback To be called when the timer is done.
- * @param {number} timeDelta Time to wait, in ms.
- * @return {number} Timer ID to be used with other methods.
- */
-YieldTimers.timeout = function (callback, timeDelta) {
- var id = ++YieldTimers.timerId;
- YieldTimers.timers[id] = [
- callback,
- YieldTimers.globalTimer.time() + timeDelta
- ];
- return id;
-};
-
-/**
- * Attempt to resolve a timeout.
- * If the time has passed, call the callback.
- * Otherwise, do nothing.
- * @param {number} id Timer ID to resolve.
- * @return {boolean} True if the timer has resolved.
- */
-YieldTimers.resolve = function (id) {
- var timer = YieldTimers.timers[id];
- if (!timer) {
- // No such timer.
- return false;
- }
- var callback = timer[0];
- var time = timer[1];
- if (YieldTimers.globalTimer.time() < time) {
- // Not done yet.
- return false;
- }
- // Execute the callback and remove the timer.
- callback();
- delete YieldTimers.timers[id];
- return true;
-};
-
-module.exports = YieldTimers;