Last active
October 28, 2022 02:24
-
-
Save j3k0/1ec24f8b6a2a964d0c56738665ab0bc1 to your computer and use it in GitHub Desktop.
setTimeout based on the audioContext timer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function customTimeoutFunction(audioContext) { | |
let tasks = []; | |
let nextTaskId = 1; | |
function now() { | |
return audioContext.currentTime * 1000; | |
} | |
function scheduler() { | |
const currentTime = now(); | |
// Call due tasks | |
tasks.forEach(function(task) { | |
if (task.due <= currentTime) | |
task.fn(); | |
}); | |
// Then remove them from the list. | |
tasks = tasks.filter(function(task) { return task.due > currentTime; }); | |
// More tasks pending, keep calling the scheduler. | |
if (tasks.length > 0) { | |
window.requestAnimationFrame(scheduler); | |
} | |
} | |
return { | |
setTimeout: function(fn, delayMillis) { | |
const id = nextTaskId; | |
nextTaskId += 1; | |
tasks.push({ | |
id: id, | |
due: now() + delayMillis, | |
fn: fn | |
}); | |
if (tasks.length === 1) { | |
window.requestAnimationFrame(scheduler); | |
} | |
return id; | |
}, | |
clearTimeout: function(id) { | |
tasks = tasks.filter(function(t) { return t.id !== id; }); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function customTimeout(audioContext) { | |
let tasks = []; | |
let nextTaskId = 1; | |
let t0 = 0; | |
let now = 0; | |
function updateInternalTime() { | |
const t1 = audioContext.currentTime * 1000; // somehow | |
const deltaT = t1 - t0; | |
if (deltaT < 0) { // the time counter was reset? | |
return; // don't increase time. | |
} | |
if (deltaT > 1000) { // the app was backgrounded or frozen | |
deltaT = 1000; // don't allow big jumps in time | |
} | |
now += deltaT; | |
} | |
function scheduler() { | |
updateInternalTime(); | |
// Call due tasks | |
tasks.forEach(function(task) { | |
if (task.due <= now) | |
task.fn(); | |
}); | |
// Then remove them from the list. | |
tasks = tasks.filter(function(task) { return task.due > now; }); | |
// More tasks pending, keep calling the scheduler. | |
if (tasks.length > 0) { | |
t0 = audioContext.currentTime * 1000; | |
window.requestAnimationFrame(scheduler); | |
} | |
} | |
return { | |
setTimeout: function(fn, delayMillis) { | |
const id = nextTaskId; | |
nextTaskId += 1; | |
tasks.push({ | |
id: id, | |
due: now + delayMillis, | |
fn: fn | |
}); | |
if (tasks.length === 1) { | |
t0 = audioContext.currentTime * 1000; | |
window.requestAnimationFrame(scheduler); | |
} | |
return id; | |
}, | |
clearTimeout: function(id) { | |
tasks = tasks.filter(function(t) { return t.id !== id; }); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment