macos: auto-expire cached screen contents
parent
839d89f2dc
commit
e69c756c89
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue