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.
This commit is contained in:
Ray Schamp 2018-11-05 20:38:04 +00:00
parent 5cf10b1af1
commit df56e615ec
3 changed files with 64 additions and 1 deletions

View file

@ -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<object>} 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
};

View file

@ -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<object>} 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];

View file

@ -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();
});