큰하트 애니메이션 대기열 처리 추가
This commit is contained in:
@@ -256,6 +256,15 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
private let sequenceMinInterval: TimeInterval = 1.0
|
||||
// 마지막 폭발 후 비 시작 허용 시각(지연 0.5s 반영)
|
||||
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 signatureList = [LiveRoomDonationResponse]()
|
||||
@@ -2113,6 +2122,15 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
}
|
||||
|
||||
private func addBigHeartAnimation() {
|
||||
if isBigHeartAnimationPlaying {
|
||||
bigHeartAnimationQueueCount += 1
|
||||
return
|
||||
}
|
||||
isBigHeartAnimationPlaying = true
|
||||
startBigHeartAnimation()
|
||||
}
|
||||
|
||||
private func startBigHeartAnimation() {
|
||||
// 로컬 발신 직후 1회는 원격 물 채움 연출을 생략하고 바로 연쇄 폭발만 실행
|
||||
if suppressNextRemoteWaterFill {
|
||||
suppressNextRemoteWaterFill = false
|
||||
@@ -2120,10 +2138,14 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
startExplosionSequence()
|
||||
return
|
||||
}
|
||||
// 스로틀: 과도한 중복 실행 방지
|
||||
// 스로틀: 과도한 중복 실행 방지(드랍 대신 지연)
|
||||
let now = Date()
|
||||
if now.timeIntervalSince(lastSequenceStartedAt) < sequenceMinInterval {
|
||||
DEBUG_LOG("BIG_HEART: throttled to protect performance")
|
||||
let elapsed = now.timeIntervalSince(lastSequenceStartedAt)
|
||||
if elapsed < sequenceMinInterval {
|
||||
let delay = sequenceMinInterval - elapsed
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in
|
||||
self?.startBigHeartAnimation()
|
||||
}
|
||||
return
|
||||
}
|
||||
lastSequenceStartedAt = now
|
||||
@@ -2240,6 +2262,7 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.bigHeartSequenceState = .exploding
|
||||
self.pendingExplosionBursts = 7
|
||||
|
||||
let bounds = UIScreen.main.bounds
|
||||
@@ -2257,8 +2280,10 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
self.explosionSequenceTimer = nil
|
||||
|
||||
// 마지막 폭발 후 0.5초 지연 뒤 비 시작
|
||||
self.bigHeartSequenceState = .waitingForRain
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.bigHeartSequenceState = .raining
|
||||
let rains = self.spawnHeartRainFromLastExplosion()
|
||||
if !rains.isEmpty {
|
||||
self.bigHeartParticles.append(contentsOf: rains)
|
||||
@@ -2266,6 +2291,9 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
self.startParticlesTimer()
|
||||
}
|
||||
}
|
||||
if rains.isEmpty && self.pendingExplosionBursts == 0 && self.bigHeartParticles.isEmpty {
|
||||
self.completeBigHeartAnimation()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -2404,16 +2432,35 @@ final class LiveRoomViewModel: NSObject, ObservableObject {
|
||||
}
|
||||
self.bigHeartParticles = merged
|
||||
if merged.isEmpty && self.pendingExplosionBursts == 0 {
|
||||
switch self.bigHeartSequenceState {
|
||||
case .waitingForRain, .exploding:
|
||||
break
|
||||
case .raining:
|
||||
self.completeBigHeartAnimation()
|
||||
self.bigHeartParticleTimer?.cancel()
|
||||
self.bigHeartParticleTimer = nil
|
||||
case .idle:
|
||||
self.bigHeartParticleTimer?.cancel()
|
||||
self.bigHeartParticleTimer = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
timer.resume()
|
||||
self.bigHeartParticleTimer = timer
|
||||
}
|
||||
}
|
||||
|
||||
private func completeBigHeartAnimation() {
|
||||
self.bigHeartSequenceState = .idle
|
||||
self.isBigHeartAnimationPlaying = false
|
||||
if self.bigHeartAnimationQueueCount > 0 {
|
||||
self.bigHeartAnimationQueueCount -= 1
|
||||
self.isBigHeartAnimationPlaying = true
|
||||
self.startBigHeartAnimation()
|
||||
}
|
||||
}
|
||||
|
||||
private func invalidateChat() {
|
||||
messageChangeFlag.toggle()
|
||||
if messages.count > 100 {
|
||||
|
||||
Reference in New Issue
Block a user