playcanvas / engine

JavaScript game engine built on WebGL, WebGPU, WebXR and glTF
https://playcanvas.com
MIT License
9.65k stars 1.34k forks source link

_state is always 'running' onVisibilityChange or app. #4299

Open lukasharing opened 2 years ago

lukasharing commented 2 years ago

https://github.com/playcanvas/engine/blob/9083d81072c32d5dbb4394a72925e644fddc1c8a/src/sound/manager.js#L130-L132

Although the property this._state inside the AudioManager is private. When the app calles onVisibilityChange, and isHidden is false, then the value this._state is always "running" but this.suspended is true. This also occours calling: "_soundManager.suspend()" manually,

_safelySuspendContext() {
    if (!this._context) return;
    this._context.suspend().then(() => {
        this.suspended = true;
        this.fire('suspend');
    }).catch(() => {
        this.fire('suspend:fail');
    });
}
suspend() {
    if (this.context && (this._state === CONTEXT_STATE_RUNNING)) {
        this._safelySuspendContext();
    }
}

_safelyResumeContext() {
    if (!this._context) return;
    this._context.resume().then(() => {
        this.suspended = false;
        this.fire('resume');
        // if after the callback the state is not yet running, add interaction listeners to resume context later
        if (this._context.state !== CONTEXT_STATE_RUNNING) {
            this._addAudioContextUserInteractionListeners();
        }
    }).catch(() => {
        this.fire('resume:fail');
        // if context could not be resumed at this point (for instance, due to auto-play policy),
        // add interaction listeners to resume the context later
        this._addAudioContextUserInteractionListeners();
    });
}
resume() {
    // attempt to safely resume the AudioContext
    if (this.context && (this._state === CONTEXT_STATE_INTERRUPTED || this._state === CONTEXT_STATE_SUSPENDED)) {
        this._safelyResumeContext();
    }
}
mvaligursky commented 2 years ago

@jpauloruschel might know this code well.