mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-19 03:11:20 -08:00
66 lines
1.4 KiB
TypeScript
66 lines
1.4 KiB
TypeScript
export type Cleanup = () => undefined
|
|
|
|
export class ResourceCleanupError extends Error {
|
|
constructor(readonly errors: unknown[]) {
|
|
super('Failed to release ArtPlayer resources')
|
|
this.name = 'ResourceCleanupError'
|
|
}
|
|
}
|
|
|
|
export default class ResourceScope {
|
|
private cleanups = new Set<() => void>()
|
|
private disposed = false
|
|
|
|
get closed(): boolean {
|
|
return this.disposed
|
|
}
|
|
|
|
add(cleanup: Cleanup): () => void {
|
|
let active = true
|
|
const release = () => {
|
|
if (!active)
|
|
return
|
|
active = false
|
|
this.cleanups.delete(release)
|
|
cleanup()
|
|
}
|
|
if (this.closed)
|
|
release()
|
|
else
|
|
this.cleanups.add(release)
|
|
return release
|
|
}
|
|
|
|
child(): ResourceScope {
|
|
const child = new ResourceScope()
|
|
const release = this.add(() => {
|
|
child.dispose()
|
|
})
|
|
child.add(() => {
|
|
release()
|
|
})
|
|
return child
|
|
}
|
|
|
|
dispose(): void {
|
|
if (this.closed)
|
|
return
|
|
this.disposed = true
|
|
const errors: unknown[] = []
|
|
// Unwind dependencies; release removes each registration before invoking it.
|
|
for (const release of Array.from(this.cleanups).reverse()) {
|
|
try {
|
|
release()
|
|
}
|
|
catch (error) {
|
|
if (error instanceof ResourceCleanupError)
|
|
errors.push(...error.errors)
|
|
else
|
|
errors.push(error)
|
|
}
|
|
}
|
|
if (errors.length)
|
|
throw new ResourceCleanupError(errors)
|
|
}
|
|
}
|