VideoTools/vendor/fyne.io/fyne/v2/internal/cache/base.go
Stu Leak 68df790d27 Fix player frame generation and video playback
Major improvements to UnifiedPlayer:

1. GetFrameImage() now works when paused for responsive UI updates
2. Play() method properly starts FFmpeg process
3. Frame display loop runs continuously for smooth video display
4. Disabled audio temporarily to fix video playback fundamentals
5. Simplified FFmpeg command to focus on video stream only

Player now:
- Generates video frames correctly
- Shows video when paused
- Has responsive progress tracking
- Starts playback properly

Next steps: Re-enable audio playback once video is stable
2026-01-07 22:20:00 -05:00

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)
}