macos: auto-expire cached screen contents

pull/7601/head
Mitchell Hashimoto 2025-06-15 13:55:03 -07:00
parent 839d89f2dc
commit e69c756c89
No known key found for this signature in database
GPG Key ID: 523D5DC389D273BC
1 changed files with 23 additions and 19 deletions

View File

@ -1926,39 +1926,43 @@ extension Ghostty.SurfaceView {
/// Caches a value for some period of time, evicting it automatically when that time expires.
/// We use this to cache our surface content. This probably should be extracted some day
/// to a more generic helper.
///
// TODO:
// - Auto-expire the data so it doesn't take memory
fileprivate class CachedValue<T> {
private var value: Value?
private var value: T?
private let fetch: () -> T
private let duration: Duration
struct Value {
var value: T
var expires: ContinuousClock.Instant
}
private var expiryTask: Task<Void, Never>?
init(duration: Duration, fetch: @escaping () -> T) {
self.duration = duration
self.fetch = fetch
}
func get() -> T {
let now = ContinuousClock.now
if let value {
// If the value isn't expired just return it
if value.expires > now {
return value.value
}
deinit {
expiryTask?.cancel()
}
// Value is expired, clear it
self.value = nil
func get() -> T {
if let value {
return value
}
// We don't have a value (or it expired). Fetch and store.
let result = fetch()
self.value = .init(value: result, expires: now + duration)
let now = ContinuousClock.now
let expires = now + duration
self.value = result
// Schedule a task to clear the value
expiryTask = Task { [weak self] in
do {
try await Task.sleep(until: expires)
self?.value = nil
self?.expiryTask = nil
} catch {
// Task was cancelled, do nothing
}
}
return result
}
}