fckeuspy-go/vendor/fyne.io/fyne/v2/internal/cache/base.go

123 lines
2.8 KiB
Go

package cache
import (
"os"
"time"
"fyne.io/fyne/v2"
)
var (
ValidDuration = 1 * time.Minute
cleanTaskInterval = ValidDuration / 2
lastClean time.Time
skippedCleanWithCanvasRefresh = false
// testing purpose only
timeNow = time.Now
)
func init() {
if t, err := time.ParseDuration(os.Getenv("FYNE_CACHE")); err == nil {
ValidDuration = t
cleanTaskInterval = ValidDuration / 2
}
}
// Clean run cache clean task, it should be called on paint events.
func Clean(canvasRefreshed bool) {
now := timeNow()
// do not run clean task too fast
if now.Sub(lastClean) < 10*time.Second {
if canvasRefreshed {
skippedCleanWithCanvasRefresh = true
}
return
}
if skippedCleanWithCanvasRefresh {
skippedCleanWithCanvasRefresh = false
canvasRefreshed = true
}
if !canvasRefreshed && now.Sub(lastClean) < cleanTaskInterval {
return
}
destroyExpiredSvgs(now)
destroyExpiredFontMetrics(now)
if canvasRefreshed {
// Destroy renderers on canvas refresh to avoid flickering screen.
destroyExpiredRenderers(now)
// canvases cache should be invalidated only on canvas refresh, otherwise there wouldn't
// be a way to recover them later
destroyExpiredCanvases(now)
}
lastClean = timeNow()
}
// CleanCanvas performs a complete remove of all the objects that belong to the specified
// canvas. Usually used to free all objects from a closing windows.
func CleanCanvas(canvas fyne.Canvas) {
canvases.Range(func(obj fyne.CanvasObject, cinfo *canvasInfo) bool {
if cinfo.canvas != canvas {
return true
}
canvases.Delete(obj)
wid, ok := obj.(fyne.Widget)
if !ok {
return true
}
rinfo, ok := renderers.LoadAndDelete(wid)
if !ok {
return true
}
rinfo.renderer.Destroy()
overrides.Delete(wid)
return true
})
}
// ResetThemeCaches clears all the svg and text size cache maps
func ResetThemeCaches() {
svgs.Clear()
fontSizeCache.Clear()
}
// destroyExpiredCanvases deletes objects from the canvases cache.
func destroyExpiredCanvases(now time.Time) {
canvases.Range(func(obj fyne.CanvasObject, cinfo *canvasInfo) bool {
if cinfo.isExpired(now) {
canvases.Delete(obj)
}
return true
})
}
// destroyExpiredRenderers deletes the renderer from the cache and calls
// renderer.Destroy()
func destroyExpiredRenderers(now time.Time) {
renderers.Range(func(wid fyne.Widget, rinfo *rendererInfo) bool {
if rinfo.isExpired(now) {
rinfo.renderer.Destroy()
overrides.Delete(wid)
renderers.Delete(wid)
}
return true
})
}
type expiringCache struct {
expires time.Time
}
// isExpired check if the cache data is expired.
func (c *expiringCache) isExpired(now time.Time) bool {
return c.expires.Before(now)
}
// setAlive updates expiration time.
func (c *expiringCache) setAlive() {
c.expires = timeNow().Add(ValidDuration)
}