From 706e112082f951196d4494abe97b31793c52f3d9 Mon Sep 17 00:00:00 2001 From: DD Liu Date: Mon, 8 May 2017 09:53:16 -0400 Subject: [PATCH] Add a block container for monitors that will run in the sequencer --- src/engine/blocks.js | 26 +++++++++++++++++++++++--- src/engine/runtime.js | 20 ++++++++++++++++++-- src/engine/target.js | 2 +- src/playground/playground.js | 1 + src/virtual-machine.js | 11 +++++++++++ 5 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/engine/blocks.js b/src/engine/blocks.js index 0c90d1a64..f27d63c52 100644 --- a/src/engine/blocks.js +++ b/src/engine/blocks.js @@ -273,16 +273,22 @@ class Blocks { */ changeBlock (args) { // Validate - if (args.element !== 'field' && args.element !== 'mutation') return; + if (['field', 'mutation', 'checkbox'].indexOf(args.element) === -1) return; const block = this._blocks[args.id]; if (typeof block === 'undefined') return; - if (args.element === 'field') { + switch (args.element) { + case 'field': // Update block value if (!block.fields[args.name]) return; block.fields[args.name].value = args.value; - } else if (args.element === 'mutation') { + break; + case 'mutation': block.mutation = mutationAdapter(args.value); + break; + case 'checkbox': + block.isMonitored = args.value; + break; } } @@ -342,6 +348,20 @@ class Blocks { } } + + /** + * Block management: run all blocks. + * @param {!object} runtime Runtime to run all blocks in. + */ + runAllMonitored (runtime) { + Object.keys(this._blocks).forEach(blockId => { + if (this.getBlock(blockId).isMonitored) { + // @todo handle specific targets (e.g. apple x position) + runtime.toggleScript(blockId); + } + }); + } + /** * Block management: delete blocks and their associated scripts. * @param {!object} e Blockly delete event to be processed. diff --git a/src/engine/runtime.js b/src/engine/runtime.js index f57a0e9f9..f2781a73e 100644 --- a/src/engine/runtime.js +++ b/src/engine/runtime.js @@ -52,6 +52,13 @@ class Runtime extends EventEmitter { */ this.flyoutBlocks = new Blocks(); + /** + * Storage container for monitor blocks. + * These will execute on a target maybe + * @type {!Blocks} + */ + this.monitorBlocks = new Blocks(); + /** * Currently known editing target for the VM. * @type {?Target} @@ -416,8 +423,9 @@ class Runtime extends EventEmitter { /** * Toggle a script. * @param {!string} topBlockId ID of block that starts the script. + * @param {?string} optTarget target ID for target to run script on. If not supplied, uses editing target. */ - toggleScript (topBlockId) { + toggleScript (topBlockId, optTarget) { // Remove any existing thread. for (let i = 0; i < this.threads.length; i++) { if (this.threads[i].topBlock === topBlockId) { @@ -426,7 +434,7 @@ class Runtime extends EventEmitter { } } // Otherwise add it. - this._pushThread(topBlockId, this._editingTarget); + this._pushThread(topBlockId, optTarget ? optTarget : this._editingTarget); } /** @@ -632,6 +640,7 @@ class Runtime extends EventEmitter { } } this.redrawRequested = false; + this._pushMonitors(); const doneThreads = this.sequencer.stepThreads(); this._updateGlows(doneThreads); this._setThreadCount(this.threads.length + doneThreads.length); @@ -641,6 +650,13 @@ class Runtime extends EventEmitter { } } + /** + * Queue monitor blocks to sequencer to be run. + */ + _pushMonitors () { + this.monitorBlocks.runAllMonitored(this); + } + /** * Set the current editing target known by the runtime. * @param {!Target} editingTarget New editing target. diff --git a/src/engine/target.js b/src/engine/target.js index d72937f65..c4f690aa9 100644 --- a/src/engine/target.js +++ b/src/engine/target.js @@ -20,7 +20,7 @@ class Target extends EventEmitter { super(); if (!blocks) { - blocks = new Blocks(this); + blocks = new Blocks(); } /** * A unique ID for this target. diff --git a/src/playground/playground.js b/src/playground/playground.js index fe06b4144..c1b655a58 100644 --- a/src/playground/playground.js +++ b/src/playground/playground.js @@ -92,6 +92,7 @@ window.onload = function () { workspace.addChangeListener(vm.blockListener); const flyoutWorkspace = workspace.getFlyout().getWorkspace(); flyoutWorkspace.addChangeListener(vm.flyoutBlockListener); + flyoutWorkspace.addChangeListener(vm.monitorBlockListener); // Create FPS counter. const stats = new window.Stats(); diff --git a/src/virtual-machine.js b/src/virtual-machine.js index c0b762bdd..c56e289c0 100644 --- a/src/virtual-machine.js +++ b/src/virtual-machine.js @@ -58,6 +58,7 @@ class VirtualMachine extends EventEmitter { this.blockListener = this.blockListener.bind(this); this.flyoutBlockListener = this.flyoutBlockListener.bind(this); + this.monitorBlockListener = this.monitorBlockListener.bind(this); } /** @@ -344,6 +345,16 @@ class VirtualMachine extends EventEmitter { this.runtime.flyoutBlocks.blocklyListen(e, this.runtime); } + /** + * Handle a Blockly event for the flyout to be passed to the monitor container. + * @param {!Blockly.Event} e Any Blockly event. + */ + monitorBlockListener (e) { + if (['create', 'change'].indexOf(e.type) !== -1) { + this.runtime.monitorBlocks.blocklyListen(e, this.runtime); + } + } + /** * Set an editing target. An editor UI can use this function to switch * between editing different targets, sprites, etc.