큰하트 애니메이션 대기열 처리 추가

This commit is contained in:
Yu Sung
2026-01-16 15:15:59 +09:00
parent c84227008c
commit a34c050d25

View File

@@ -256,6 +256,15 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
private let sequenceMinInterval: TimeInterval = 1.0 private let sequenceMinInterval: TimeInterval = 1.0
// ( 0.5s ) // ( 0.5s )
private var rainEligibleAt: Date? = nil private var rainEligibleAt: Date? = nil
private enum BigHeartSequenceState {
case idle
case exploding
case waitingForRain
case raining
}
private var bigHeartSequenceState: BigHeartSequenceState = .idle
private var bigHeartAnimationQueueCount: Int = 0
private var isBigHeartAnimationPlaying: Bool = false
var signatureImageUrls = [String]() var signatureImageUrls = [String]()
var signatureList = [LiveRoomDonationResponse]() var signatureList = [LiveRoomDonationResponse]()
@@ -2113,6 +2122,15 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
} }
private func addBigHeartAnimation() { private func addBigHeartAnimation() {
if isBigHeartAnimationPlaying {
bigHeartAnimationQueueCount += 1
return
}
isBigHeartAnimationPlaying = true
startBigHeartAnimation()
}
private func startBigHeartAnimation() {
// 1 // 1
if suppressNextRemoteWaterFill { if suppressNextRemoteWaterFill {
suppressNextRemoteWaterFill = false suppressNextRemoteWaterFill = false
@@ -2120,10 +2138,14 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
startExplosionSequence() startExplosionSequence()
return return
} }
// : // : ( )
let now = Date() let now = Date()
if now.timeIntervalSince(lastSequenceStartedAt) < sequenceMinInterval { let elapsed = now.timeIntervalSince(lastSequenceStartedAt)
DEBUG_LOG("BIG_HEART: throttled to protect performance") if elapsed < sequenceMinInterval {
let delay = sequenceMinInterval - elapsed
DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in
self?.startBigHeartAnimation()
}
return return
} }
lastSequenceStartedAt = now lastSequenceStartedAt = now
@@ -2240,6 +2262,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { return } guard let self = self else { return }
self.bigHeartSequenceState = .exploding
self.pendingExplosionBursts = 7 self.pendingExplosionBursts = 7
let bounds = UIScreen.main.bounds let bounds = UIScreen.main.bounds
@@ -2257,8 +2280,10 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
self.explosionSequenceTimer = nil self.explosionSequenceTimer = nil
// 0.5 // 0.5
self.bigHeartSequenceState = .waitingForRain
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
guard let self = self else { return } guard let self = self else { return }
self.bigHeartSequenceState = .raining
let rains = self.spawnHeartRainFromLastExplosion() let rains = self.spawnHeartRainFromLastExplosion()
if !rains.isEmpty { if !rains.isEmpty {
self.bigHeartParticles.append(contentsOf: rains) self.bigHeartParticles.append(contentsOf: rains)
@@ -2266,6 +2291,9 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
self.startParticlesTimer() self.startParticlesTimer()
} }
} }
if rains.isEmpty && self.pendingExplosionBursts == 0 && self.bigHeartParticles.isEmpty {
self.completeBigHeartAnimation()
}
} }
return return
} }
@@ -2404,8 +2432,17 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
} }
self.bigHeartParticles = merged self.bigHeartParticles = merged
if merged.isEmpty && self.pendingExplosionBursts == 0 { if merged.isEmpty && self.pendingExplosionBursts == 0 {
self.bigHeartParticleTimer?.cancel() switch self.bigHeartSequenceState {
self.bigHeartParticleTimer = nil case .waitingForRain, .exploding:
break
case .raining:
self.completeBigHeartAnimation()
self.bigHeartParticleTimer?.cancel()
self.bigHeartParticleTimer = nil
case .idle:
self.bigHeartParticleTimer?.cancel()
self.bigHeartParticleTimer = nil
}
} }
} }
} }
@@ -2414,6 +2451,16 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
} }
} }
private func completeBigHeartAnimation() {
self.bigHeartSequenceState = .idle
self.isBigHeartAnimationPlaying = false
if self.bigHeartAnimationQueueCount > 0 {
self.bigHeartAnimationQueueCount -= 1
self.isBigHeartAnimationPlaying = true
self.startBigHeartAnimation()
}
}
private func invalidateChat() { private func invalidateChat() {
messageChangeFlag.toggle() messageChangeFlag.toggle()
if messages.count > 100 { if messages.count > 100 {