diff --git a/src/virtual-machine.js b/src/virtual-machine.js index 893f411fc..5e77adebf 100644 --- a/src/virtual-machine.js +++ b/src/virtual-machine.js @@ -6,6 +6,7 @@ const Buffer = require('buffer').Buffer; const centralDispatch = require('./dispatch/central-dispatch'); const ExtensionManager = require('./extension-support/extension-manager'); const log = require('./util/log'); +const MathUtil = require('./util/math-util'); const Runtime = require('./engine/runtime'); const sb2 = require('./serialization/sb2'); const sb3 = require('./serialization/sb3'); @@ -1033,6 +1034,25 @@ class VirtualMachine extends EventEmitter { return null; } + /** + * Reorder target by index. Return whether a change was made. + * @param {!string} targetIndex Index of the target. + * @param {!number} newIndex index that the target should be moved to. + * @returns {boolean} Whether a target was reordered. + */ + reorderTarget (targetIndex, newIndex) { + targetIndex = MathUtil.clamp(targetIndex, 0, this.runtime.targets.length - 1); + newIndex = MathUtil.clamp(newIndex, 0, this.runtime.targets.length - 1); + if (targetIndex === newIndex) return false; + const target = this.runtime.targets[targetIndex]; + let targets = this.runtime.targets; + targets = targets.slice(0, targetIndex).concat(targets.slice(targetIndex + 1)); + targets.splice(newIndex, 0, target); + this.runtime.targets = targets; + this.emitTargetsUpdate(); + return true; + } + /** * Reorder the costumes of a target if it exists. Return whether it succeeded. * @param {!string} targetId ID of the target which owns the costumes. diff --git a/test/unit/virtual-machine.js b/test/unit/virtual-machine.js index 22a69235f..1404f8df0 100644 --- a/test/unit/virtual-machine.js +++ b/test/unit/virtual-machine.js @@ -368,6 +368,30 @@ test('reorderSound', t => { t.end(); }); +test('reorderTarget', t => { + const vm = new VirtualMachine(); + vm.emitTargetsUpdate = () => {}; + + vm.runtime.targets = ['a', 'b', 'c', 'd']; + + t.equal(vm.reorderTarget(2, 2), false); + t.deepEqual(vm.runtime.targets, ['a', 'b', 'c', 'd']); + + // Make sure clamping works + t.equal(vm.reorderTarget(-100, -5), false); + t.deepEqual(vm.runtime.targets, ['a', 'b', 'c', 'd']); + + // Reorder upwards + t.equal(vm.reorderTarget(0, 2), true); + t.deepEqual(vm.runtime.targets, ['b', 'c', 'a', 'd']); + + // Reorder downwards + t.equal(vm.reorderTarget(3, 1), true); + t.deepEqual(vm.runtime.targets, ['b', 'd', 'c', 'a']); + + t.end(); +}); + test('emitWorkspaceUpdate', t => { const vm = new VirtualMachine(); const blocksToXML = comments => {