Merge pull request #944 from fsih/duplicateCostume

Duplicate costume
This commit is contained in:
Paul Kaplan 2018-02-26 07:59:32 -05:00 committed by GitHub
commit 58702a78fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 7 deletions

View file

@ -401,12 +401,17 @@ class RenderedTarget extends Target {
/** /**
* Add a costume, taking care to avoid duplicate names. * Add a costume, taking care to avoid duplicate names.
* @param {!object} costumeObject Object representing the costume. * @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); const usedNames = this.sprite.costumes.map(costume => costume.name);
costumeObject.name = StringUtil.unusedName(costumeObject.name, usedNames); costumeObject.name = StringUtil.unusedName(costumeObject.name, usedNames);
if (index) {
this.sprite.costumes.splice(index, 0, costumeObject);
} else {
this.sprite.costumes.push(costumeObject); this.sprite.costumes.push(costumeObject);
} }
}
/** /**
* Rename a costume, taking care to avoid duplicate names. * Rename a costume, taking care to avoid duplicate names.
@ -461,12 +466,17 @@ class RenderedTarget extends Target {
/** /**
* Add a sound, taking care to avoid duplicate names. * Add a sound, taking care to avoid duplicate names.
* @param {!object} soundObject Object representing the sound. * @param {!object} soundObject Object representing the sound.
* @param {?int} index Index at which to add costume
*/ */
addSound (soundObject) { addSound (soundObject, index) {
const usedNames = this.sprite.sounds.map(sound => sound.name); const usedNames = this.sprite.sounds.map(sound => sound.name);
soundObject.name = StringUtil.unusedName(soundObject.name, usedNames); soundObject.name = StringUtil.unusedName(soundObject.name, usedNames);
if (index) {
this.sprite.sounds.splice(index, 0, soundObject);
} else {
this.sprite.sounds.push(soundObject); this.sprite.sounds.push(soundObject);
} }
}
/** /**
* Rename a sound, taking care to avoid duplicate names. * Rename a sound, taking care to avoid duplicate names.

View file

@ -322,11 +322,41 @@ class VirtualMachine extends EventEmitter {
return loadCostume(md5ext, costumeObject, this.runtime).then(() => { return loadCostume(md5ext, costumeObject, this.runtime).then(() => {
this.editingTarget.addCostume(costumeObject); this.editingTarget.addCostume(costumeObject);
this.editingTarget.setCostume( 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
* @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}`;
return loadCostume(md5ext, clone, this.runtime).then(() => {
this.editingTarget.addCostume(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
* @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);
return loadSound(clone, this.runtime).then(() => {
this.editingTarget.addSound(clone, soundIndex + 1);
this.emitTargetsUpdate();
});
}
/** /**
* Rename a costume on the current editing target. * Rename a costume on the current editing target.
* @param {int} costumeIndex - the index of the costume to be renamed. * @param {int} costumeIndex - the index of the costume to be renamed.
@ -384,12 +414,34 @@ class VirtualMachine extends EventEmitter {
* Update a sound buffer. * Update a sound buffer.
* @param {int} soundIndex - the index of the sound to be updated. * @param {int} soundIndex - the index of the sound to be updated.
* @param {AudioBuffer} newBuffer - new audio buffer for the audio engine. * @param {AudioBuffer} newBuffer - new audio buffer for the audio engine.
* @param {ArrayBuffer} soundEncoding - the new (wav) encoded sound to be stored
*/ */
updateSoundBuffer (soundIndex, newBuffer) { updateSoundBuffer (soundIndex, newBuffer, soundEncoding) {
const id = this.editingTarget.sprite.sounds[soundIndex].soundId; const sound = this.editingTarget.sprite.sounds[soundIndex];
const id = sound ? sound.soundId : null;
if (id && this.runtime && this.runtime.audioEngine) { if (id && this.runtime && this.runtime.audioEngine) {
this.runtime.audioEngine.updateSoundBuffer(id, newBuffer); 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(); this.emitTargetsUpdate();
} }