From 75cf6407d4faf2754bf4c2384ab6a7a3f9baf7f2 Mon Sep 17 00:00:00 2001 From: DD Date: Fri, 23 Feb 2018 10:42:29 -0500 Subject: [PATCH 1/4] Duplicate costume --- src/sprites/rendered-target.js | 22 ++++++++++++++++++++++ src/virtual-machine.js | 30 +++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/sprites/rendered-target.js b/src/sprites/rendered-target.js index 2a6a0f7d3..aa1963480 100644 --- a/src/sprites/rendered-target.js +++ b/src/sprites/rendered-target.js @@ -408,6 +408,17 @@ class RenderedTarget extends Target { this.sprite.costumes.push(costumeObject); } + /** + * Add a costume at the given index, taking care to avoid duplicate names. + * @param {!object} costumeObject Object representing the costume. + * @param {!int} index Index at which to add costume + */ + addCostumeAt (costumeObject, index) { + const usedNames = this.sprite.costumes.map(costume => costume.name); + costumeObject.name = StringUtil.unusedName(costumeObject.name, usedNames); + this.sprite.costumes.splice(index, 0, costumeObject); + } + /** * Rename a costume, taking care to avoid duplicate names. * @param {int} costumeIndex - the index of the costume to be renamed. @@ -458,6 +469,17 @@ class RenderedTarget extends Target { this.runtime.requestTargetsUpdate(this); } + /** + * Add a sound, taking care to avoid duplicate names. + * @param {!object} soundObject Object representing the sound. + * @param {!int} index Index at which to add costume + */ + addSoundAt (soundObject, index) { + const usedNames = this.sprite.sounds.map(sound => sound.name); + soundObject.name = StringUtil.unusedName(soundObject.name, usedNames); + this.sprite.sounds.splice(index, 0, soundObject); + } + /** * Add a sound, taking care to avoid duplicate names. * @param {!object} soundObject Object representing the sound. diff --git a/src/virtual-machine.js b/src/virtual-machine.js index d930ad534..6fdb1d0ec 100644 --- a/src/virtual-machine.js +++ b/src/virtual-machine.js @@ -322,11 +322,39 @@ class VirtualMachine extends EventEmitter { return loadCostume(md5ext, costumeObject, this.runtime).then(() => { this.editingTarget.addCostume(costumeObject); this.editingTarget.setCostume( - this.editingTarget.sprite.costumes.length - 1 + this.editingTarget.getCostumes().length - 1 ); }); } + /** + * Duplicate the costume at the given index. Add it at that index + 1. + * @param {!int} costumeIndex Index of costume to duplicate + */ + duplicateCostume (costumeIndex) { + const originalCostume = this.editingTarget.getCostumes()[costumeIndex]; + const clone = Object.assign({}, originalCostume); + const md5ext = `${clone.assetId}.${clone.dataFormat}`; + loadCostume(md5ext, clone, this.runtime).then(() => { + this.editingTarget.addCostumeAt(clone, costumeIndex + 1); + this.editingTarget.setCostume(costumeIndex + 1); + this.emitTargetsUpdate(); + }); + } + + /** + * Duplicate the sound at the given index. Add it at that index + 1. + * @param {!int} soundIndex Index of sound to duplicate + */ + duplicateSound (soundIndex) { + const originalSound = this.editingTarget.getSounds()[soundIndex]; + const clone = Object.assign({}, originalSound); + loadSound(clone, this.runtime).then(() => { + this.editingTarget.addSoundAt(clone, soundIndex + 1); + this.emitTargetsUpdate(); + }); + } + /** * Rename a costume on the current editing target. * @param {int} costumeIndex - the index of the costume to be renamed. From 2239d1b92bb087446eb7a5a199cabb84e7b31734 Mon Sep 17 00:00:00 2001 From: DD Date: Fri, 23 Feb 2018 11:09:19 -0500 Subject: [PATCH 2/4] Use promises --- src/virtual-machine.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/virtual-machine.js b/src/virtual-machine.js index 6fdb1d0ec..4e0a2bb11 100644 --- a/src/virtual-machine.js +++ b/src/virtual-machine.js @@ -330,12 +330,13 @@ class VirtualMachine extends EventEmitter { /** * Duplicate the costume at the given index. Add it at that index + 1. * @param {!int} costumeIndex Index of costume to duplicate + * @returns {?Promise} - a promise that resolves when the costume has been decoded and added */ duplicateCostume (costumeIndex) { const originalCostume = this.editingTarget.getCostumes()[costumeIndex]; const clone = Object.assign({}, originalCostume); const md5ext = `${clone.assetId}.${clone.dataFormat}`; - loadCostume(md5ext, clone, this.runtime).then(() => { + return loadCostume(md5ext, clone, this.runtime).then(() => { this.editingTarget.addCostumeAt(clone, costumeIndex + 1); this.editingTarget.setCostume(costumeIndex + 1); this.emitTargetsUpdate(); @@ -345,11 +346,12 @@ class VirtualMachine extends EventEmitter { /** * Duplicate the sound at the given index. Add it at that index + 1. * @param {!int} soundIndex Index of sound to duplicate + * @returns {?Promise} - a promise that resolves when the sound has been decoded and added */ duplicateSound (soundIndex) { const originalSound = this.editingTarget.getSounds()[soundIndex]; const clone = Object.assign({}, originalSound); - loadSound(clone, this.runtime).then(() => { + return loadSound(clone, this.runtime).then(() => { this.editingTarget.addSoundAt(clone, soundIndex + 1); this.emitTargetsUpdate(); }); From 10789cd779ba684f9da1af8dd1dc9b8a1302e66a Mon Sep 17 00:00:00 2001 From: DD Date: Fri, 23 Feb 2018 16:21:07 -0500 Subject: [PATCH 3/4] Bring in Karishmas changes from save-load to ensure the sound gets updated in storage when edited --- src/virtual-machine.js | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/virtual-machine.js b/src/virtual-machine.js index 4e0a2bb11..e2b18f2a3 100644 --- a/src/virtual-machine.js +++ b/src/virtual-machine.js @@ -414,12 +414,34 @@ class VirtualMachine extends EventEmitter { * Update a sound buffer. * @param {int} soundIndex - the index of the sound to be updated. * @param {AudioBuffer} newBuffer - new audio buffer for the audio engine. + * @param {ArrayBuffer} soundEncoding - the new (wav) encoded sound to be stored */ - updateSoundBuffer (soundIndex, newBuffer) { - const id = this.editingTarget.sprite.sounds[soundIndex].soundId; + updateSoundBuffer (soundIndex, newBuffer, soundEncoding) { + const sound = this.editingTarget.sprite.sounds[soundIndex]; + const id = sound ? sound.soundId : null; if (id && this.runtime && this.runtime.audioEngine) { this.runtime.audioEngine.updateSoundBuffer(id, newBuffer); } + // Update sound in runtime + if (soundEncoding) { + // Now that we updated the sound, the format should also be updated + // so that the sound can eventually be decoded the right way. + // Sounds that were formerly 'adpcm', but were updated in sound editor + // will not get decoded by the audio engine correctly unless the format + // is updated as below. + sound.format = ''; + const storage = this.runtime.storage; + sound.assetId = storage.builtinHelper.cache( + storage.AssetType.Sound, + storage.DataFormat.WAV, + soundEncoding + ); + sound.md5 = `${sound.assetId}.${sound.dataFormat}`; + } + // If soundEncoding is null, it's because gui had a problem + // encoding the updated sound. We don't want to store anything in this + // case, and gui should have logged an error. + this.emitTargetsUpdate(); } From 9a65df4c12c619cff3e997c14a079bd3eb610c22 Mon Sep 17 00:00:00 2001 From: DD Date: Fri, 23 Feb 2018 16:24:18 -0500 Subject: [PATCH 4/4] Make index optional --- src/sprites/rendered-target.js | 40 ++++++++++++---------------------- src/virtual-machine.js | 4 ++-- 2 files changed, 16 insertions(+), 28 deletions(-) diff --git a/src/sprites/rendered-target.js b/src/sprites/rendered-target.js index aa1963480..ae02b72bd 100644 --- a/src/sprites/rendered-target.js +++ b/src/sprites/rendered-target.js @@ -401,22 +401,16 @@ class RenderedTarget extends Target { /** * Add a costume, taking care to avoid duplicate names. * @param {!object} costumeObject Object representing the costume. + * @param {?int} index Index at which to add costume */ - addCostume (costumeObject) { + addCostume (costumeObject, index) { const usedNames = this.sprite.costumes.map(costume => costume.name); costumeObject.name = StringUtil.unusedName(costumeObject.name, usedNames); - this.sprite.costumes.push(costumeObject); - } - - /** - * Add a costume at the given index, taking care to avoid duplicate names. - * @param {!object} costumeObject Object representing the costume. - * @param {!int} index Index at which to add costume - */ - addCostumeAt (costumeObject, index) { - const usedNames = this.sprite.costumes.map(costume => costume.name); - costumeObject.name = StringUtil.unusedName(costumeObject.name, usedNames); - this.sprite.costumes.splice(index, 0, costumeObject); + if (index) { + this.sprite.costumes.splice(index, 0, costumeObject); + } else { + this.sprite.costumes.push(costumeObject); + } } /** @@ -472,22 +466,16 @@ class RenderedTarget extends Target { /** * Add a sound, taking care to avoid duplicate names. * @param {!object} soundObject Object representing the sound. - * @param {!int} index Index at which to add costume + * @param {?int} index Index at which to add costume */ - addSoundAt (soundObject, index) { + addSound (soundObject, index) { const usedNames = this.sprite.sounds.map(sound => sound.name); soundObject.name = StringUtil.unusedName(soundObject.name, usedNames); - this.sprite.sounds.splice(index, 0, soundObject); - } - - /** - * Add a sound, taking care to avoid duplicate names. - * @param {!object} soundObject Object representing the sound. - */ - addSound (soundObject) { - const usedNames = this.sprite.sounds.map(sound => sound.name); - soundObject.name = StringUtil.unusedName(soundObject.name, usedNames); - this.sprite.sounds.push(soundObject); + if (index) { + this.sprite.sounds.splice(index, 0, soundObject); + } else { + this.sprite.sounds.push(soundObject); + } } /** diff --git a/src/virtual-machine.js b/src/virtual-machine.js index e2b18f2a3..f9fa45be3 100644 --- a/src/virtual-machine.js +++ b/src/virtual-machine.js @@ -337,7 +337,7 @@ class VirtualMachine extends EventEmitter { const clone = Object.assign({}, originalCostume); const md5ext = `${clone.assetId}.${clone.dataFormat}`; return loadCostume(md5ext, clone, this.runtime).then(() => { - this.editingTarget.addCostumeAt(clone, costumeIndex + 1); + this.editingTarget.addCostume(clone, costumeIndex + 1); this.editingTarget.setCostume(costumeIndex + 1); this.emitTargetsUpdate(); }); @@ -352,7 +352,7 @@ class VirtualMachine extends EventEmitter { const originalSound = this.editingTarget.getSounds()[soundIndex]; const clone = Object.assign({}, originalSound); return loadSound(clone, this.runtime).then(() => { - this.editingTarget.addSoundAt(clone, soundIndex + 1); + this.editingTarget.addSound(clone, soundIndex + 1); this.emitTargetsUpdate(); }); }