diablo2-web/tests/p0-529-async-lifecycle.test.ts

53 lines
1.8 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest'
import { ActorAnimator } from '../src/client/render/actor-animator.ts'
import type { LoadedMonsterArt } from '../src/client/render/monster-art.ts'
import { LoadGeneration, type AtlasHandle, type SpriteRenderer } from '../src/client/render/renderer.ts'
import * as entityArtLoader from '../src/client/scene/entity-art-loader.ts'
function createTrackingRenderer() {
let nextHandle = 1
const liveHandles = new Set<AtlasHandle>()
const deletedHandles: AtlasHandle[] = []
const renderer = {
addAtlas: vi.fn((_source: unknown, _w: number, _h: number): AtlasHandle => {
const h = nextHandle++ as unknown as AtlasHandle
liveHandles.add(h)
return h
}),
deleteAtlas: vi.fn((h: AtlasHandle) => {
if (liveHandles.delete(h)) {
deletedHandles.push(h)
}
}),
setPalette: vi.fn(),
get liveTextureCount() {
return liveHandles.size
},
} as unknown as SpriteRenderer & { liveTextureCount: number }
return { renderer, liveHandles, deletedHandles }
}
describe('P0 #529: Async Scene LoadGeneration Cancellation & GPU Texture Disposal', () => {
it('LoadGeneration increments generation IDs and aborts prior AbortSignal instances', () => {
const loadGen = new LoadGeneration()
expect(loadGen.current).toBe(0)
const { gen: gen1, signal: sig1 } = loadGen.next()
expect(gen1).toBe(1)
expect(loadGen.isCurrent(gen1)).toBe(true)
expect(sig1.aborted).toBe(false)
const { gen: gen2 } = loadGen.next()
expect(gen2).toBe(2)
expect(loadGen.isCurrent(gen1)).toBe(false)
expect(loadGen.isCurrent(gen2)).toBe(true)
expect(sig1.aborted).toBe(true)
loadGen.invalidate()
expect(loadGen.isCurrent(gen2)).toBe(false)
expect(loadGen.signal.aborted).toBe(true)
})
})