Add loadProject, setEditingTarget, and UI emits

This commit is contained in:
Tim Mickel 2016-08-31 12:28:09 -04:00
parent 23d9999a9f
commit 3e749fb9f1
2 changed files with 84 additions and 0 deletions

View file

@ -101,6 +101,65 @@ VirtualMachine.prototype.postIOData = function (device, data) {
} }
}; };
/**
* Load a project from a Scratch 2.0 JSON representation.
* @param {string} json JSON string representing the project.
*/
VirtualMachine.prototype.loadProject = function (json) {
// Select the first target for editing, e.g., the stage.
this.editingTarget = this.runtime.targets[0];
// Update the VM user's knowledge of targets and blocks on the workspace.
this.emitTargetsUpdate();
this.emitWorkspaceUpdate();
};
/**
* Set an editing target. An editor UI can use this function to switch
* between editing different targets, sprites, etc.
* After switching the editing target, the VM may emit updates
* to the list of targets and any attached workspace blocks
* (see `emitTargetsUpdate` and `emitWorkspaceUpdate`).
* @param {string} targetId Id of target to set as editing.
*/
VirtualMachine.prototype.setEditingTarget = function (targetId) {
if (targetId == this.editingTarget.id) { // No change.
return;
}
var target = this.runtime.getTargetById(targetId);
if (target) {
this.editingTarget = target;
// Emit appropriate UI updates.
this.emitTargetsUpdate();
this.emitWorkspaceUpdate();
}
};
/**
* Emit metadata about available targets.
* An editor UI could use this to display a list of targets and show
* the currently editing one.
*/
VirtualMachine.prototype.emitTargetsUpdate = function () {
this.emit('targetsUpdate', {
// [[target id, human readable target name], ...].
targetList: this.runtime.targets.map(function(target) {
return [target.id, target.getName()];
}),
// Currently editing target id.
editingTarget: this.editingTarget.id
});
};
/**
* Emit an Blockly/scratch-blocks compatible XML representation
* of the current editing target's blocks.
*/
VirtualMachine.prototype.emitWorkspaceUpdate = function () {
this.emit('workspaceUpdate', {
'xml': this.editingTarget.blocks.toXML()
});
};
/* /*
* Worker handlers: for all public methods available above, * Worker handlers: for all public methods available above,
* we must also provide a message handler in case the VM is run * we must also provide a message handler in case the VM is run
@ -155,6 +214,12 @@ if (ENV_WORKER) {
case 'postIOData': case 'postIOData':
self.vmInstance.postIOData(messageData.device, messageData.data); self.vmInstance.postIOData(messageData.device, messageData.data);
break; break;
case 'setEditingTarget':
self.vmInstance.setEditingTarget(messageData.targetId);
break;
case 'loadProject':
self.vmInstance.loadProject(messageData.json);
break;
default: default:
if (e.data.id == 'RendererConnected') { if (e.data.id == 'RendererConnected') {
//initRenderWorker(); //initRenderWorker();
@ -179,6 +244,17 @@ if (ENV_WORKER) {
self.vmInstance.runtime.on(Runtime.VISUAL_REPORT, function (id, value) { self.vmInstance.runtime.on(Runtime.VISUAL_REPORT, function (id, value) {
self.postMessage({method: Runtime.VISUAL_REPORT, id: id, value: value}); self.postMessage({method: Runtime.VISUAL_REPORT, id: id, value: value});
}); });
self.vmInstance.on('workspaceUpdate', function(data) {
self.postMessage({method: 'workspaceUpdate',
xml: data.xml
});
});
self.vmInstance.on('targetsUpdate', function(data) {
self.postMessage({method: 'targetsUpdate',
targetList: data.targetList,
editingTarget: data.editingTarget
});
});
} }
/** /**

View file

@ -76,6 +76,14 @@ VirtualMachine.prototype.animationFrame = function () {
this.vmWorker.postMessage({method: 'animationFrame'}); this.vmWorker.postMessage({method: 'animationFrame'});
}; };
VirtualMachine.prototype.loadProject = function (json) {
this.vmWorker.postMessage({method: 'loadProject', json: json});
};
VirtualMachine.prototype.setEditingTarget = function (targetId) {
this.vmWorker.postMessage({method: 'setEditingTarget', targetId: targetId});
};
/** /**
* Export and bind to `window` * Export and bind to `window`
*/ */