perf: fight replay memory leak fixes
Replace 32 bare setTimeout calls with tracked timeouts across all fight modules (effects, entrances, finishers, choreographies). All timers are now registered in cleanupTimers Set and cleared on scene destroy. Enhanced destroy() to also clean up active speech bubbles and explicitly destroy all remaining game objects before k.quit(). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
57703a28ad
commit
78f83a7520
@@ -386,7 +386,7 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
})
|
||||
lines.push(line)
|
||||
}
|
||||
setTimeout(() => { lines.forEach(l => { if (l.exists()) l.destroy() }) }, duration * 1000)
|
||||
trackedTimeout(() => { lines.forEach(l => { if (l.exists()) l.destroy() }) }, duration * 1000)
|
||||
}
|
||||
|
||||
// Flash the whole screen
|
||||
@@ -1802,7 +1802,7 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
const choreoCtx: ChoreoContext = {
|
||||
k, W, H, GROUND_Y, FRAME_SIZE, theme,
|
||||
safeColor: (color: string) => safeColor(k, color),
|
||||
trackedInterval, clearTracked,
|
||||
trackedTimeout, trackedInterval, clearTracked,
|
||||
spawnSparks, spawnBulletHoles, spawnExhaust, spawnProjectile,
|
||||
spawnShockwave, screenFlash, impactFreeze, spawnAfterimages,
|
||||
glitchRGB, scanlineGlitch, dimensionalShift,
|
||||
@@ -2041,7 +2041,7 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
else activeBubbleB = allEls
|
||||
|
||||
// Fade out after duration
|
||||
setTimeout(() => {
|
||||
trackedTimeout(() => {
|
||||
allEls.forEach(el => {
|
||||
if (!el.exists()) return
|
||||
k.tween(el.opacity, 0, 0.35, (v) => { el.opacity = v }).then(() => {
|
||||
@@ -2368,7 +2368,7 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
if (funnyAction === 0) {
|
||||
// Falls asleep, snaps awake
|
||||
for (let z = 0; z < 3; z++) {
|
||||
setTimeout(() => {
|
||||
trackedTimeout(() => {
|
||||
spawnEmoteText(judge.pos.x + 15, judge.pos.y - 20, 'Z', '#8888ff', 1.0)
|
||||
}, z * 400)
|
||||
}
|
||||
@@ -3441,11 +3441,19 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
stopMusic()
|
||||
stopTalking('a')
|
||||
stopTalking('b')
|
||||
// Destroy lingering speech bubbles
|
||||
activeBubbleA.forEach(o => { if (o.exists()) o.destroy() })
|
||||
activeBubbleB.forEach(o => { if (o.exists()) o.destroy() })
|
||||
activeBubbleA.length = 0
|
||||
activeBubbleB.length = 0
|
||||
// Clear all tracked timers
|
||||
for (const id of cleanupTimers) {
|
||||
clearInterval(id)
|
||||
clearTimeout(id)
|
||||
}
|
||||
cleanupTimers.clear()
|
||||
// Destroy all remaining game objects before quitting
|
||||
try { k.get('*').forEach(o => { if (o.exists()) o.destroy() }) } catch {}
|
||||
k.quit()
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user