Improve block primitive lookup and execution

Slightly simplify export of block primitives from a block package.
Catch and report exceptions from block functions.
This commit is contained in:
Christopher Willis-Ford 2016-05-02 11:07:40 -07:00
parent 27c06ce476
commit 4a3276d026
4 changed files with 94 additions and 13 deletions

View file

@ -1,5 +1,10 @@
function Scratch3Blocks() {
function Scratch3Blocks(runtime) {
/**
* The runtime instantiating this block package.
* @type {Runtime}
*/
this.runtime = runtime;
}
/**
@ -8,7 +13,42 @@ function Scratch3Blocks() {
*/
Scratch3Blocks.prototype.getPrimitives = function() {
return {
'control_repeat': this.repeat,
'control_forever': this.forever,
'control_wait': this.wait,
'control_stop': this.stop,
'event_whenflagclicked': this.whenFlagClicked,
'event_whenbroadcastreceived': this.whenBroadcastReceived,
'event_broadcast': this.broadcast
};
};
Scratch3Blocks.prototype.repeat = function() {
console.log('Running: control_repeat');
};
Scratch3Blocks.prototype.forever = function() {
console.log('Running: control_forever');
};
Scratch3Blocks.prototype.wait = function() {
console.log('Running: control_wait');
};
Scratch3Blocks.prototype.stop = function() {
console.log('Running: control_stop');
};
Scratch3Blocks.prototype.whenFlagClicked = function() {
console.log('Running: event_whenflagclicked');
};
Scratch3Blocks.prototype.whenBroadcastReceived = function() {
console.log('Running: event_whenbroadcastreceived');
};
Scratch3Blocks.prototype.broadcast = function() {
console.log('Running: event_broadcast');
};
module.exports = Scratch3Blocks;

View file

@ -1,5 +1,10 @@
function WeDo2Blocks() {
function WeDo2Blocks(runtime) {
/**
* The runtime instantiating this block package.
* @type {Runtime}
*/
this.runtime = runtime;
}
/**
@ -8,7 +13,37 @@ function WeDo2Blocks() {
*/
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
};
};
WeDo2Blocks.prototype.motorClockwise = function() {
console.log('Running: wedo_motorclockwise');
};
WeDo2Blocks.prototype.motorCounterClockwise = function() {
console.log('Running: wedo_motorcounterclockwise');
};
WeDo2Blocks.prototype.motorSpeed = function() {
console.log('Running: wedo_motorspeed');
};
WeDo2Blocks.prototype.setColor = function() {
console.log('Running: wedo_setcolor');
};
WeDo2Blocks.prototype.whenDistanceClose = function() {
console.log('Running: wedo_whendistanceclose');
};
WeDo2Blocks.prototype.whenTilt = function() {
console.log('Running: wedo_whentilt');
};
module.exports = WeDo2Blocks;

View file

@ -205,11 +205,12 @@ Runtime.prototype.deleteBlock = function (e) {
Runtime.prototype._registerBlockPackages = function () {
for (var packageName in defaultBlockPackages) {
if (defaultBlockPackages.hasOwnProperty(packageName)) {
var packageObject = new (defaultBlockPackages[packageName])();
// @todo maybe we pass a different runtime depending on package privilege level?
var packageObject = new (defaultBlockPackages[packageName])(this);
var packageContents = packageObject.getPrimitives();
for (var op in packageContents) {
if (packageContents.hasOwnProperty(op)) {
this._primitives[op] = packageContents[op];
this._primitives[op] = packageContents[op].bind(packageObject);
}
}
}

View file

@ -60,18 +60,23 @@ Sequencer.prototype.stepThreads = function (threads) {
Sequencer.prototype.stepThread = function (thread) {
var opcode = this.runtime._getOpcode(thread.nextBlock);
if (!opcode) {
console.log('Could not get opcode for block: ' + thread.nextBlock);
}
else {
var blockFunction = this.runtime.getOpcodeFunction(opcode);
if (!blockFunction) {
console.log('Could not get implementation for opcode: ' + opcode);
if (!opcode) {
console.warn('Could not get opcode for block: ' + thread.nextBlock);
}
else {
blockFunction();
var blockFunction = this.runtime.getOpcodeFunction(opcode);
if (!blockFunction) {
console.warn('Could not get implementation for opcode: ' + opcode);
}
else {
try {
blockFunction();
}
catch(e) {
console.error('Exception calling block function', {opcode: opcode, exception: e});
}
}
}
}
thread.nextBlock = this.runtime._getNextBlock(thread.nextBlock);
};