Skip to content

Commit

Permalink
Refactor internal queue to avoid various edge cases
Browse files Browse the repository at this point in the history
Actual fix for #899
  • Loading branch information
goldfire committed Feb 10, 2018
1 parent 422d3cd commit bf83277
Showing 1 changed file with 30 additions and 19 deletions.
49 changes: 30 additions & 19 deletions src/howler.core.js
Original file line number Diff line number Diff line change
Expand Up @@ -689,9 +689,7 @@
if (id && !sound._paused) {
// Trigger the play event, in order to keep iterating through queue.
if (!internal) {
setTimeout(function() {
self._emit('play', 'queue');
}, 0);
self._loadQueue('play');
}

return sound._id;
Expand Down Expand Up @@ -775,9 +773,13 @@
// Releases the lock and executes queued actions.
var runLoadQueue = function() {
self._playLock = false;
self._loadQueue();
if (!internal) {
self._emit('play', sound._id);
}
};
play.then(runLoadQueue, runLoadQueue);
} else if (!internal) {
self._emit('play', sound._id);
}

// If the node is still paused, then we can assume there was a playback issue.
Expand All @@ -800,10 +802,6 @@
};
node.addEventListener('ended', self._endTimers[sound._id], false);
}

if (!internal) {
self._emit('play', sound._id);
}
} catch (err) {
self._emit('playerror', sound._id, err);
}
Expand Down Expand Up @@ -1465,7 +1463,19 @@
sound._node.currentTime = seek;
}

self._emit('seek', id);
// Wait for the play lock to be unset before emitting (HTML5 Audio).
if (playing && !self._webAudio) {
var emitSeek = function() {
if (!self._playLock) {
self._emit('seek', id);
} else {
setTimeout(emitSeek, 0);
}
};
setTimeout(emitSeek, 0);
} else {
self._emit('seek', id);
}
} else {
if (self._webAudio) {
var realTime = self.playing(id) ? Howler.ctx.currentTime - sound._playStart : 0;
Expand Down Expand Up @@ -1686,11 +1696,6 @@

// Loop through event store and fire all functions.
for (var i=events.length-1; i>=0; i--) {
// Don't fire listener on non-queue events if this is a queued event.
if (id === 'queue' && events[i].id !== id) {
continue;
}

// Only fire the listener if the correct ID is used.
if (!events[i].id || events[i].id === id || event === 'load') {
setTimeout(function(fn) {
Expand All @@ -1704,6 +1709,9 @@
}
}

// Pass the event type into load queue so that it can continue stepping.
self._loadQueue(event);

return self;
},

Expand All @@ -1713,19 +1721,22 @@
* after the previous has finished executing (even if async like play).
* @return {Howl}
*/
_loadQueue: function() {
_loadQueue: function(event) {
var self = this;

if (self._queue.length > 0) {
var task = self._queue[0];

// don't move onto the next task until this one is done
self.once(task.event, function() {
// Remove this task if a matching event was passed.
if (task.event === event) {
self._queue.shift();
self._loadQueue();
}, 'queue');
}

task.action();
// Run the task if no event type is passed.
if (!event) {
task.action();
}
}

return self;
Expand Down

0 comments on commit bf83277

Please sign in to comment.