indicate show visual report or update monitor on the thread

This commit is contained in:
DD Liu 2017-05-09 17:34:13 -04:00
parent 35a208d1d3
commit 4ae1321252
4 changed files with 42 additions and 14 deletions

View file

@ -357,7 +357,7 @@ class Blocks {
Object.keys(this._blocks).forEach(blockId => { Object.keys(this._blocks).forEach(blockId => {
if (this.getBlock(blockId).isMonitored) { if (this.getBlock(blockId).isMonitored) {
// @todo handle specific targets (e.g. apple x position) // @todo handle specific targets (e.g. apple x position)
runtime.toggleScript(blockId); runtime.toggleScript(blockId, {updateMonitor: true});
} }
}); });
} }

View file

@ -60,6 +60,8 @@ const execute = function (sequencer, thread) {
* or after a promise resolves. * or after a promise resolves.
* @param {*} resolvedValue Value eventually returned from the primitive. * @param {*} resolvedValue Value eventually returned from the primitive.
*/ */
// @todo move this to callback attached to the thread when we have performance
// metrics (dd)
const handleReport = function (resolvedValue) { const handleReport = function (resolvedValue) {
thread.pushReportedValue(resolvedValue); thread.pushReportedValue(resolvedValue);
if (isHat) { if (isHat) {
@ -85,9 +87,23 @@ const execute = function (sequencer, thread) {
} else { } else {
// In a non-hat, report the value visually if necessary if // In a non-hat, report the value visually if necessary if
// at the top of the thread stack. // at the top of the thread stack.
if (typeof resolvedValue !== 'undefined' && thread.showVisualReport && thread.atStackTop()) {
if (typeof resolvedValue !== 'undefined' && thread.atStackTop()) {
if (thread.showVisualReport) {
runtime.visualReport(currentBlockId, resolvedValue); runtime.visualReport(currentBlockId, resolvedValue);
} }
if (thread.updateMonitor) {
runtime.updateMonitors([{
id: currentBlockId, // @todo(dd) this will collide if multiple sprites use same block
category: 'data',
label: blockContainer.getOpcode(blockContainer.getBlock(currentBlockId)), // @todo(dd) how to handle translation here?
value: String(resolvedValue),
x: 0, // @todo(dd) place below the last monitor instead
y: 0
}]);
}
}
// Finished any yields. // Finished any yields.
thread.status = Thread.STATUS_RUNNING; thread.status = Thread.STATUS_RUNNING;
} }

View file

@ -377,13 +377,22 @@ class Runtime extends EventEmitter {
* Create a thread and push it to the list of threads. * Create a thread and push it to the list of threads.
* @param {!string} id ID of block that starts the stack. * @param {!string} id ID of block that starts the stack.
* @param {!Target} target Target to run thread on. * @param {!Target} target Target to run thread on.
* @param {?boolean} optShowVisualReport true if the script should show speech bubble for its value * @param {?object} opts optional arguments
* @param {?boolean} opts.optShowVisualReport true if the script should show speech bubble for its value
* @param {?boolean} opts.optUpdateMonitor true if the script should show and update a monitor with its value
* @return {!Thread} The newly created thread. * @return {!Thread} The newly created thread.
*/ */
_pushThread (id, target, optShowVisualReport) { _pushThread (id, target, opts) {
opts = Object.assign({
showVisualReport: false,
updateMonitor: false
}, opts);
const thread = new Thread(id); const thread = new Thread(id);
thread.target = target; thread.target = target;
thread.showVisualReport = optShowVisualReport; thread.showVisualReport = opts.optShowVisualReport;
thread.updateMonitor = opts.updateMonitor;
thread.pushStack(id); thread.pushStack(id);
this.threads.push(thread); this.threads.push(thread);
return thread; return thread;
@ -436,8 +445,14 @@ class Runtime extends EventEmitter {
* @param {?object} opts optional arguments to toggle script * @param {?object} opts optional arguments to toggle script
* @param {?string} opts.target target ID for target to run script on. If not supplied, uses editing target. * @param {?string} opts.target target ID for target to run script on. If not supplied, uses editing target.
* @param {?boolean} opts.showVisualReport true if the speech bubble should pop up on the block, false if not. * @param {?boolean} opts.showVisualReport true if the speech bubble should pop up on the block, false if not.
* @param {?boolean} opts.updateMonitor true if the monitor for this block should show and get updated.
*/ */
toggleScript (topBlockId, opts) { toggleScript (topBlockId, opts) {
opts = Object.assign({
target: this._editingTarget,
showVisualReport: false,
updateMonitor: false
}, opts);
// Remove any existing thread. // Remove any existing thread.
for (let i = 0; i < this.threads.length; i++) { for (let i = 0; i < this.threads.length; i++) {
if (this.threads[i].topBlock === topBlockId) { if (this.threads[i].topBlock === topBlockId) {
@ -446,10 +461,7 @@ class Runtime extends EventEmitter {
} }
} }
// Otherwise add it. // Otherwise add it.
this._pushThread( this._pushThread(topBlockId, opts.target, opts);
topBlockId,
opts && opts.target ? opts.target : this._editingTarget,
opts ? opts.showVisualReport : false);
} }
/** /**
@ -828,10 +840,10 @@ class Runtime extends EventEmitter {
} }
/** /**
* Emit a monitor update. * Emit a monitor update which adds or updates if exists the given monitors.
* @param {!Array} monitors Array of all monitors * @param {!Array} monitors Array of all monitors
*/ */
monitorsUpdate (monitors) { updateMonitors (monitors) {
this.emit(Runtime.MONITORS_UPDATE, monitors); this.emit(Runtime.MONITORS_UPDATE, monitors);
} }

View file

@ -55,8 +55,8 @@ class VirtualMachine extends EventEmitter {
instance.runtime.on(Runtime.SPRITE_INFO_REPORT, spriteInfo => { instance.runtime.on(Runtime.SPRITE_INFO_REPORT, spriteInfo => {
instance.emit(Runtime.SPRITE_INFO_REPORT, spriteInfo); instance.emit(Runtime.SPRITE_INFO_REPORT, spriteInfo);
}); });
instance.runtime.on(Runtime.MONITORS_UPDATE, spriteInfo => { instance.runtime.on(Runtime.MONITORS_UPDATE, data => {
instance.emit(Runtime.MONITORS_UPDATE, spriteInfo); instance.emit(Runtime.MONITORS_UPDATE, data);
}); });
this.blockListener = this.blockListener.bind(this); this.blockListener = this.blockListener.bind(this);