import Foundation /// Whether anyone is looking at the app: the phone UI in the foreground, or CarPlay connected. /// Work that only feeds a screen (stemd polling, a shallow output buffer for snappy faders) /// checks this, so a locked phone playing music does as little as it can. enum AppActivity { private static let lock = UnfairLock() nonisolated(unsafe) private static var phone = true nonisolated(unsafe) private static var car = false nonisolated(unsafe) private static var waiters: [CheckedContinuation] = [] static var isActive: Bool { lock.with { phone || car } } static func setPhone(_ on: Bool) { update { phone = on } } static func setCar(_ on: Bool) { update { car = on } } private static func update(_ change: () -> Void) { let ready = lock.with { () -> [CheckedContinuation] in change() guard phone || car else { return [] } defer { waiters = [] } return waiters } ready.forEach { $0.resume() } } /// Returns once the app is active, at once if it already is. static func untilActive() async { await withCheckedContinuation { (c: CheckedContinuation) in let now = lock.with { () -> Bool in if phone || car { return true } waiters.append(c) return false } if now { c.resume() } } } }