Let StitchedImage invalidate cache based on time

This commit is contained in:
David Vogel 2023-12-23 01:15:05 +01:00
parent 3016919348
commit a0d5c13557
2 changed files with 34 additions and 2 deletions

View File

@ -1,4 +1,4 @@
// Copyright (c) 2022 David Vogel
// Copyright (c) 2022-2023 David Vogel
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
@ -21,6 +21,8 @@ type StitchedImageCache struct {
rect image.Rectangle // Position and size of the cached area.
image *image.RGBA // Cached RGBA image. The bounds of this image are determined by the filename.
idleCounter byte // Is incremented when this cache object idles, and reset every time the cache is used.
}
func NewStitchedImageCache(stitchedImage *StitchedImage, rect image.Rectangle) StitchedImageCache {
@ -30,6 +32,21 @@ func NewStitchedImageCache(stitchedImage *StitchedImage, rect image.Rectangle) S
}
}
// InvalidateAuto invalidates this cache object when it had idled for too long.
// The cache will be invalidated after `threshold + 1` calls to InvalidateAuto.
func (sic *StitchedImageCache) InvalidateAuto(threshold byte) {
sic.Lock()
defer sic.Unlock()
if sic.image != nil {
if sic.idleCounter >= threshold {
sic.image = nil
return
}
sic.idleCounter++
}
}
// Invalidate clears the cached image.
func (sic *StitchedImageCache) Invalidate() {
sic.Lock()
@ -43,6 +60,8 @@ func (sic *StitchedImageCache) Regenerate() *image.RGBA {
sic.Lock()
defer sic.Unlock()
sic.idleCounter = 0
// Check if there is already a cache image.
if sic.image != nil {
return sic.image
@ -114,6 +133,7 @@ func (sic *StitchedImageCache) RGBAAt(x, y int) color.RGBA {
sic.Lock()
if sic.image != nil {
defer sic.Unlock()
sic.idleCounter = 0
return sic.image.RGBAAt(x, y)
}
sic.Unlock()

View File

@ -1,4 +1,4 @@
// Copyright (c) 2022 David Vogel
// Copyright (c) 2022-2023 David Vogel
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
@ -10,6 +10,7 @@ import (
"image"
"image/color"
"sync/atomic"
"time"
)
// StitchedImageCacheGridSize defines the worker chunk size when the cache image is regenerated.
@ -71,6 +72,17 @@ func NewStitchedImage(tiles ImageTiles, bounds image.Rectangle, blendMethod Stit
stitchedImage.cacheRowYOffset = -bounds.Min.Y
stitchedImage.cacheRows = cacheRows
// Start ticker to automatically invalidate caches.
// Due to this, the stitchedImage object is not composable, as this goroutine will always have a reference.
go func() {
ticker := time.NewTicker(1 * time.Second)
for range ticker.C {
for rowIndex := range stitchedImage.cacheRows {
stitchedImage.cacheRows[rowIndex].InvalidateAuto(3) // Invalidate cache row after 3 seconds of being idle.
}
}
}()
return stitchedImage, nil
}