From df56e615ec7b34f607890fb783afd43061ceb52b Mon Sep 17 00:00:00 2001 From: Ray Schamp Date: Mon, 5 Nov 2018 20:38:04 +0000 Subject: [PATCH] Add method for collecting all targets' assets Resolves #1601. Does not include the project JSON since that would require knowledge of a project ID, which the VM has not been responsible for so far. For now, it is the responsibility of the consumer to determine if these assets should be saved or not. Otherwise the VM would need to be responsible for saving, which has been out of its scope. --- src/serialization/serialize-assets.js | 14 +++++++++ src/virtual-machine.js | 9 +++++- test/unit/vm_collectAssets.js | 42 +++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 test/unit/vm_collectAssets.js diff --git a/src/serialization/serialize-assets.js b/src/serialization/serialize-assets.js index c1d063949..35c82adbd 100644 --- a/src/serialization/serialize-assets.js +++ b/src/serialization/serialize-assets.js @@ -50,7 +50,21 @@ const serializeCostumes = function (runtime, optTargetId) { return serializeAssets(runtime, 'costumes', optTargetId); }; +/* + * Return all costumes and sounds in the provided runtime + * @param {Runtime} runtime + * @returns {Array} An array of costumes and sounds + */ +const collectAssets = function (runtime) { + return runtime.targets.reduce((acc, target) => ( + acc + .concat(target.sprite.sounds.map(sound => sound.asset)) + .concat(target.sprite.costumes.map(costume => costume.asset)) + ), []); +}; + module.exports = { + collectAssets, serializeSounds, serializeCostumes }; diff --git a/src/virtual-machine.js b/src/virtual-machine.js index b7659dd31..798078f2a 100644 --- a/src/virtual-machine.js +++ b/src/virtual-machine.js @@ -18,7 +18,7 @@ const Variable = require('./engine/variable'); const {loadCostume} = require('./import/load-costume.js'); const {loadSound} = require('./import/load-sound.js'); -const {serializeSounds, serializeCostumes} = require('./serialization/serialize-assets'); +const {collectAssets, serializeSounds, serializeCostumes} = require('./serialization/serialize-assets'); require('canvas-toBlob'); const RESERVED_NAMES = ['_mouse_', '_stage_', '_edge_', '_myself_', '_random_']; @@ -336,6 +336,13 @@ class VirtualMachine extends EventEmitter { }); } + /* + * @type {Array} Array of all costumes and sounds currently in the runtime + */ + get assets () { + return collectAssets(this.runtime); + } + _addFileDescsToZip (fileDescs, zip) { for (let i = 0; i < fileDescs.length; i++) { const currFileDesc = fileDescs[i]; diff --git a/test/unit/vm_collectAssets.js b/test/unit/vm_collectAssets.js new file mode 100644 index 000000000..2fcab59be --- /dev/null +++ b/test/unit/vm_collectAssets.js @@ -0,0 +1,42 @@ +const test = require('tap').test; + +const {collectAssets} = require('../../src/serialization/serialize-assets'); + +const RenderedTarget = require('../../src/sprites/rendered-target'); +const Sprite = require('../../src/sprites/sprite'); +const VirtualMachine = require('../../src/virtual-machine'); + +test('spec', t => { + t.type(collectAssets, 'function'); + t.end(); +}); + +test('collectAssets', t => { + const vm = new VirtualMachine(); + const sprite = new Sprite(null, vm.runtime); + const target = new RenderedTarget(sprite, vm.runtime); + vm.runtime.targets = [target]; + const [ + soundAsset1, + soundAsset2, + costumeAsset1 + ] = [{assetId: 1}, {assetId: 2}, {assetId: 3}]; + sprite.sounds = [{id: 1, asset: soundAsset1}, {id: 2, asset: soundAsset2}]; + sprite.costumes = [{id: 1, asset: costumeAsset1}]; + const assets = collectAssets(vm.runtime); + t.deepEqual(assets, [soundAsset1, soundAsset2, costumeAsset1]); + t.end(); +}); + +test('getter', t => { + const vm = new VirtualMachine(); + const sprite = new Sprite(null, vm.runtime); + const target = new RenderedTarget(sprite, vm.runtime); + vm.runtime.targets = [target]; + sprite.sounds = [{id: 1, asset: {}}, {id: 2, asset: {}}]; + sprite.costumes = [{id: 1, asset: {}}]; + const assets = vm.assets; + t.type(assets.length, 'number'); + t.equal(assets.length, 3); + t.end(); +});