Merge pull request from mzgoddard/stop-other-sounds

Stop other sounds
This commit is contained in:
Michael "Z" Goddard 2018-10-23 15:11:08 -04:00 committed by GitHub
commit 5e5655c916
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 7 deletions

View file

@ -2,6 +2,12 @@ const MathUtil = require('../util/math-util');
const Cast = require('../util/cast');
const Clone = require('../util/clone');
/**
* Occluded boolean value to make its use more understandable.
* @const {boolean}
*/
const STORE_WAITING = true;
class Scratch3SoundBlocks {
constructor (runtime) {
/**
@ -10,10 +16,16 @@ class Scratch3SoundBlocks {
*/
this.runtime = runtime;
this.waitingSounds = {};
// Clear sound effects on green flag and stop button events.
this.stopAllSounds = this.stopAllSounds.bind(this);
this._stopWaitingSoundsForTarget = this._stopWaitingSoundsForTarget.bind(this);
this._clearEffectsForAllTargets = this._clearEffectsForAllTargets.bind(this);
if (this.runtime) {
this.runtime.on('PROJECT_STOP_ALL', this.stopAllSounds);
this.runtime.on('PROJECT_STOP_ALL', this._clearEffectsForAllTargets);
this.runtime.on('STOP_FOR_TARGET', this._stopWaitingSoundsForTarget);
this.runtime.on('PROJECT_START', this._clearEffectsForAllTargets);
}
@ -141,21 +153,44 @@ class Scratch3SoundBlocks {
playSound (args, util) {
// Don't return the promise, it's the only difference for AndWait
this.playSoundAndWait(args, util);
this._playSound(args, util);
}
playSoundAndWait (args, util) {
return this._playSound(args, util, STORE_WAITING);
}
_playSound (args, util, storeWaiting) {
const index = this._getSoundIndex(args.SOUND_MENU, util);
if (index >= 0) {
const {target} = util;
const {sprite} = target;
const {soundId} = sprite.sounds[index];
if (sprite.soundBank) {
if (storeWaiting === STORE_WAITING) {
this._addWaitingSound(target.id, soundId);
} else {
this._removeWaitingSound(target.id, soundId);
}
return sprite.soundBank.playSound(target, soundId);
}
}
}
_addWaitingSound (targetId, soundId) {
if (!this.waitingSounds[targetId]) {
this.waitingSounds[targetId] = new Set();
}
this.waitingSounds[targetId].add(soundId);
}
_removeWaitingSound (targetId, soundId) {
if (!this.waitingSounds[targetId]) {
return;
}
this.waitingSounds[targetId].delete(soundId);
}
_getSoundIndex (soundName, util) {
// if the sprite has no sounds, return -1
const len = util.target.sprite.sounds.length;
@ -201,6 +236,20 @@ class Scratch3SoundBlocks {
_stopAllSoundsForTarget (target) {
if (target.sprite.soundBank) {
target.sprite.soundBank.stopAllSounds(target);
if (this.waitingSounds[target.id]) {
this.waitingSounds[target.id].clear();
}
}
}
_stopWaitingSoundsForTarget (target) {
if (target.sprite.soundBank) {
if (this.waitingSounds[target.id]) {
for (const soundId of this.waitingSounds[target.id].values()) {
target.sprite.soundBank.stop(target, soundId);
}
this.waitingSounds[target.id].clear();
}
}
}

View file

@ -1074,9 +1074,6 @@ class RenderedTarget extends Target {
*/
onStopAll () {
this.clearEffects();
if (this.sprite.soundBank) {
this.sprite.soundBank.stopAllSounds();
}
}
/**

View file

@ -67,7 +67,7 @@ test('ask and stop all dismisses question', t => {
test('ask and stop other scripts dismisses if it is the last question', t => {
const rt = new Runtime();
const s = new Sensing(rt);
const util = {target: {visible: false}, thread: {}};
const util = {target: {visible: false, sprite: {}}, thread: {}};
const expectedQuestion = 'a question';
@ -94,8 +94,8 @@ test('ask and stop other scripts dismisses if it is the last question', t => {
test('ask and stop other scripts asks next question', t => {
const rt = new Runtime();
const s = new Sensing(rt);
const util = {target: {visible: false}, thread: {}};
const util2 = {target: {visible: false}, thread: {}};
const util = {target: {visible: false, sprite: {}}, thread: {}};
const util2 = {target: {visible: false, sprite: {}}, thread: {}};
const expectedQuestion = 'a question';
const nextQuestion = 'a followup';