From b97974e2ace25efa093fc976e409bebf7ecd319f Mon Sep 17 00:00:00 2001 From: Tim Mickel Date: Tue, 21 Jun 2016 15:30:27 -0400 Subject: [PATCH] Implement WebWorker interface --- src/index.js | 59 +++++++++++++++++++++++++++++++++++---- src/worker.js | 70 +++++++++++++++++++++++++++++++++++++++++++++++ webpack.config.js | 3 +- 3 files changed, 125 insertions(+), 7 deletions(-) create mode 100644 src/worker.js diff --git a/src/index.js b/src/index.js index afe6cc2f4..174f05b1c 100644 --- a/src/index.js +++ b/src/index.js @@ -34,10 +34,62 @@ function VirtualMachine () { instance.flyoutBlockListener = ( instance.blocks.generateBlockListener(true, instance.runtime) ); + + // Runtime emits are passed along as VM emits. + instance.runtime.on(Runtime.STACK_GLOW_ON, function (id) { + instance.emit(Runtime.STACK_GLOW_ON, {id: id}); + }); + instance.runtime.on(Runtime.STACK_GLOW_OFF, function (id) { + instance.emit(Runtime.STACK_GLOW_OFF, {id: id}); + }); + instance.runtime.on(Runtime.BLOCK_GLOW_ON, function (id) { + instance.emit(Runtime.BLOCK_GLOW_ON, {id: id}); + }); + instance.runtime.on(Runtime.BLOCK_GLOW_OFF, function (id) { + instance.emit(Runtime.BLOCK_GLOW_OFF, {id: id}); + }); } +/** + * Inherit from EventEmitter + */ +util.inherits(VirtualMachine, EventEmitter); + +/** + * Start running the VM - do this before anything else. + */ +VirtualMachine.prototype.start = function () { + this.runtime.start(); +}; + +/** + * "Green flag" handler - start all threads starting with a green flag. + */ +VirtualMachine.prototype.greenFlag = function () { + this.runtime.greenFlag(); +}; + +/** + * Stop all threads and running activities. + */ +VirtualMachine.prototype.stopAll = function () { + this.runtime.stopAll(); +}; + +/** + * Get data for playground. Data comes back in an emitted event. + */ +VirtualMachine.prototype.getPlaygroundData = function () { + this.emit('playgroundData', { + blocks: this.blocks, + threads: this.runtime.threads + }); +}; + /* - * Worker Handlers + * Worker handlers: for all public methods available above, + * we must also provide a message handler in case the VM is run + * from a worker environment. */ if (ENV_WORKER) { self.vmInstance = new VirtualMachine(); @@ -85,11 +137,6 @@ if (ENV_WORKER) { }); } -/** - * Inherit from EventEmitter - */ -util.inherits(VirtualMachine, EventEmitter); - /** * Export and bind to `window` */ diff --git a/src/worker.js b/src/worker.js new file mode 100644 index 000000000..e96c57bf3 --- /dev/null +++ b/src/worker.js @@ -0,0 +1,70 @@ +var EventEmitter = require('events'); +var util = require('util'); + +function VirtualMachine () { + if (!window.Worker) { + console.error('WebWorkers not supported in this environment.' + + ' Please use the non-worker version (vm.js or vm.min.js).'); + return; + } + var instance = this; + EventEmitter.call(instance); + instance.vmWorker = new Worker('../vm.js'); + + // onmessage calls are converted into emitted events. + instance.vmWorker.onmessage = function (e) { + instance.emit(e.data.method, e.data); + }; + + instance.blockListener = function (e) { + // Messages from Blockly are not serializable by default. + // Pull out the necessary, serializable components to pass across. + var serializableE = { + blockId: e.blockId, + element: e.element, + type: e.type, + name: e.name, + newValue: e.newValue, + oldParentId: e.oldParentId, + oldInputName: e.oldInputName, + newParentId: e.newParentId, + newInputName: e.newInputName, + xml: { + outerHTML: (e.xml) ? e.xml.outerHTML : null + } + }; + instance.vmWorker.postMessage({ + method: 'blockListener', + args: serializableE + }); + }; +} + +/** + * Inherit from EventEmitter + */ +util.inherits(VirtualMachine, EventEmitter); + +// For documentation, please see index.js. +// These mirror the functionality provided there, with the worker wrapper. +VirtualMachine.prototype.getPlaygroundData = function () { + this.vmWorker.postMessage({method: 'getPlaygroundData'}); +}; + +VirtualMachine.prototype.start = function () { + this.vmWorker.postMessage({method: 'start'}); +}; + +VirtualMachine.prototype.greenFlag = function () { + this.vmWorker.postMessage({method: 'greenFlag'}); +}; + +VirtualMachine.prototype.stopAll = function () { + this.vmWorker.postMessage({method: 'stopAll'}); +}; + +/** + * Export and bind to `window` + */ +module.exports = VirtualMachine; +if (typeof window !== 'undefined') window.VirtualMachine = module.exports; diff --git a/webpack.config.js b/webpack.config.js index 6badafd2f..46a89c67c 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -3,7 +3,8 @@ var webpack = require('webpack'); module.exports = { entry: { 'vm': './src/index.js', - 'vm.min': './src/index.js' + 'vm.min': './src/index.js', + 'vm.worker': './src/worker.js' }, output: { path: __dirname,