mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-27 01:21:20 -08:00
refactor(ambilight): [PKG-AMBILIGHT-03] split typed lifecycle and recover native canvas sampling
This commit is contained in:
1 parent
43f0e9a8c6
commit
6caee44dbf
25 files changed
+1680
-306
No files matched your search
@@ -0,0 +1,74 @@
|
||||
export function createFrameLoop(frequency: number, playing: () => boolean, update: (active: () => boolean) => void) {
|
||||
let state: 'stopped' | 'running' | 'destroyed' = 'stopped'
|
||||
let pending: number | null = null
|
||||
let generation = 0
|
||||
let inFrame = false
|
||||
let lastUpdateTime = 0
|
||||
|
||||
function schedule() {
|
||||
const current = generation
|
||||
try {
|
||||
pending = requestAnimationFrame(() => {
|
||||
if (state !== 'running' || current !== generation)
|
||||
return
|
||||
pending = null
|
||||
tick()
|
||||
})
|
||||
}
|
||||
catch (error) {
|
||||
state = 'stopped'
|
||||
generation++
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
function tick() {
|
||||
const current = generation
|
||||
const active = () => state === 'running' && current === generation
|
||||
inFrame = true
|
||||
try {
|
||||
const now = performance.now()
|
||||
if (now - lastUpdateTime < 1000 / frequency || !playing() || !active())
|
||||
return
|
||||
lastUpdateTime = now
|
||||
update(active)
|
||||
}
|
||||
finally {
|
||||
inFrame = false
|
||||
if (state === 'running' && pending === null)
|
||||
schedule()
|
||||
}
|
||||
}
|
||||
|
||||
function start() {
|
||||
if (state !== 'stopped')
|
||||
return
|
||||
state = 'running'
|
||||
generation++
|
||||
if (!inFrame)
|
||||
tick()
|
||||
}
|
||||
|
||||
function stop() {
|
||||
if (state === 'destroyed')
|
||||
return
|
||||
state = 'stopped'
|
||||
generation++
|
||||
const frame = pending
|
||||
pending = null
|
||||
if (frame !== null)
|
||||
cancelAnimationFrame(frame)
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
if (state === 'destroyed')
|
||||
return
|
||||
state = 'destroyed'
|
||||
generation++
|
||||
const frame = pending
|
||||
pending = null
|
||||
if (frame !== null)
|
||||
cancelAnimationFrame(frame)
|
||||
}
|
||||
return { start, stop, destroy }
|
||||
}
|
||||
Reference in new issue
Block a user