refactor(canvas): [PKG-CANVAS-03] own media and frame lifecycle in strict TypeScript

This commit is contained in:
Harvey Zhao committed 2026-09-12 13:11:07 +08:00
1 parent e931520e66
commit 2b319109cd
29 files changed
+2015 -362

No files matched your search

@@ -0,0 +1,69 @@
export function createFrameScheduler(draw: (valid: () => boolean) => Promise<void>, active: () => boolean) {
let running = false
let closed = false
let busy = false
let pending = false
let generation = 0
let frame: number | null = null
function cancel(): void {
if (frame !== null)
cancelAnimationFrame(frame)
frame = null
}
function drain(): void {
if (busy || closed || !active())
return
if (pending) {
pending = false
busy = true
const version = generation
const valid = () => !closed && active() && generation === version
const complete = () => {
busy = false
drain()
}
// An observer throwing must not leave the scheduler busy or reject unhandled.
void draw(valid).then(complete, complete)
}
else if (running && frame === null) {
frame = requestAnimationFrame(() => {
frame = null
pending = true
drain()
})
}
}
function request(): void {
if (closed || !active())
return
generation++
pending = true
cancel()
drain()
}
function stop(): void {
running = false
pending = false
generation++
cancel()
}
return {
request,
start() {
if (running || closed || !active())
return
running = true
request()
},
stop,
destroy() {
closed = true
stop()
},
}
}