From 7975fc47b894f03fa247d1f6bc708094528900ec Mon Sep 17 00:00:00 2001 From: Jacalz Date: Thu, 23 Jan 2025 11:00:55 +0100 Subject: [PATCH 1/3] Clean up background processes when changing tutorial in fyne_demo All animations and tickers were recreated on loading a new page. Animations resulted in just background CPU usage but the tickers can not (until go.mod defaults to Go 1.23) be GC'd before stop so they would tick in the background forever. --- cmd/fyne_demo/main.go | 4 ++++ cmd/fyne_demo/tutorials/advanced.go | 12 +++++++++- cmd/fyne_demo/tutorials/animation.go | 16 +++++++++++++ cmd/fyne_demo/tutorials/canvas.go | 10 +++++++- cmd/fyne_demo/tutorials/data.go | 4 ++++ cmd/fyne_demo/tutorials/widget.go | 34 ++++++++++++++++------------ 6 files changed, 63 insertions(+), 17 deletions(-) diff --git a/cmd/fyne_demo/main.go b/cmd/fyne_demo/main.go index 3a4c571f33..3f219d03d5 100644 --- a/cmd/fyne_demo/main.go +++ b/cmd/fyne_demo/main.go @@ -230,6 +230,10 @@ func makeNav(setTutorial func(tutorial tutorials.Tutorial), loadPrevious bool) f if t, ok := tutorials.Tutorials[uid]; ok { a.Preferences().SetString(preferenceCurrentTutorial, uid) setTutorial(t) + + for _, f := range tutorials.OnChangeFuncs { + f(uid) + } } }, } diff --git a/cmd/fyne_demo/tutorials/advanced.go b/cmd/fyne_demo/tutorials/advanced.go index 54b748cc6f..c7fb9479ea 100644 --- a/cmd/fyne_demo/tutorials/advanced.go +++ b/cmd/fyne_demo/tutorials/advanced.go @@ -1,6 +1,7 @@ package tutorials import ( + "fmt" "strconv" "time" @@ -36,8 +37,17 @@ func advancedScreen(win fyne.Window) fyne.CanvasObject { &widget.FormItem{Text: "Texture Scale", Widget: tex}, )) + ticker := time.NewTicker(time.Second) + + OnChangeFuncs = append(OnChangeFuncs, func(page string) { + if page != "advanced" { + fmt.Println("Stopped ticker") + ticker.Stop() + } + }) + go func(canvas fyne.Canvas) { - for range time.NewTicker(time.Second).C { + for range ticker.C { fyne.Do(func() { scale.SetText(scaleToString(canvas)) tex.SetText(textureScaleToString(canvas)) diff --git a/cmd/fyne_demo/tutorials/animation.go b/cmd/fyne_demo/tutorials/animation.go index ebda929c92..a62ebf72ba 100644 --- a/cmd/fyne_demo/tutorials/animation.go +++ b/cmd/fyne_demo/tutorials/animation.go @@ -46,6 +46,13 @@ func makeAnimationCanvas() fyne.CanvasObject { a2.Curve = fyne.AnimationLinear a2.Start() + OnChangeFuncs = append(OnChangeFuncs, func(page string) { + if page != "animations" { + a.Stop() + a2.Stop() + } + }) + running := true var toggle *widget.Button toggle = widget.NewButton("Stop", func() { @@ -71,6 +78,15 @@ func makeAnimationCurves() fyne.CanvasObject { label3, box3, a3 := makeAnimationCurveItem("EaseOut", fyne.AnimationEaseOut, 60+theme.Padding()*2) label4, box4, a4 := makeAnimationCurveItem("Linear", fyne.AnimationLinear, 90+theme.Padding()*3) + OnChangeFuncs = append(OnChangeFuncs, func(page string) { + if page != "animations" { + a1.Stop() + a2.Stop() + a3.Stop() + a4.Stop() + } + }) + start := widget.NewButton("Compare", func() { a1.Start() a2.Start() diff --git a/cmd/fyne_demo/tutorials/canvas.go b/cmd/fyne_demo/tutorials/canvas.go index f6df7f44b5..34487d6c95 100644 --- a/cmd/fyne_demo/tutorials/canvas.go +++ b/cmd/fyne_demo/tutorials/canvas.go @@ -20,8 +20,16 @@ func rgbGradient(x, y, w, h int) color.Color { // canvasScreen loads a graphics example panel for the demo app func canvasScreen(_ fyne.Window) fyne.CanvasObject { gradient := canvas.NewHorizontalGradient(color.NRGBA{0x80, 0, 0, 0xff}, color.NRGBA{0, 0x80, 0, 0xff}) + ticker := time.NewTicker(time.Second) + + OnChangeFuncs = append(OnChangeFuncs, func(page string) { + if page != "canvas" { + ticker.Stop() + } + }) + go func() { - for range time.NewTicker(time.Second).C { + for range ticker.C { fyne.Do(func() { gradient.Angle += 45 if gradient.Angle >= 360 { diff --git a/cmd/fyne_demo/tutorials/data.go b/cmd/fyne_demo/tutorials/data.go index ab731fb573..c6b8170a2a 100644 --- a/cmd/fyne_demo/tutorials/data.go +++ b/cmd/fyne_demo/tutorials/data.go @@ -4,6 +4,10 @@ import ( "fyne.io/fyne/v2" ) +// OnChangeFuncs is a slice of functions that can be registered +// to run when the user switches tutorial. +var OnChangeFuncs []func(string) + // Tutorial defines the data structure for a tutorial type Tutorial struct { Title, Intro string diff --git a/cmd/fyne_demo/tutorials/widget.go b/cmd/fyne_demo/tutorials/widget.go index 23db799adf..5001af02bb 100644 --- a/cmd/fyne_demo/tutorials/widget.go +++ b/cmd/fyne_demo/tutorials/widget.go @@ -405,7 +405,25 @@ func makeProgressTab(_ fyne.Window) fyne.CanvasObject { } infProgress := widget.NewProgressBarInfinite() - startProgress(progress, fprogress) + + progressAnimation := fyne.Animation{ + Curve: fyne.AnimationLinear, + Duration: 10 * time.Second, + Tick: func(percentage float32) { + value := float64(percentage) + progress.SetValue(value) + fprogress.SetValue(value) + }, + } + + progressAnimation.Start() + + OnChangeFuncs = append(OnChangeFuncs, func(page string) { + if page != "progress" { + progressAnimation.Stop() + infProgress.Stop() + } + }) return container.NewVBox( widget.NewLabel("Percent"), progress, @@ -463,20 +481,6 @@ func makeToolbarTab(_ fyne.Window) fyne.CanvasObject { return container.NewBorder(t, nil, nil, nil) } -func startProgress(progress, fprogress *widget.ProgressBar) { - progressAnimation := fyne.Animation{ - Curve: fyne.AnimationLinear, - Duration: 10 * time.Second, - Tick: func(percentage float32) { - value := float64(percentage) - progress.SetValue(value) - fprogress.SetValue(value) - }, - } - - progressAnimation.Start() -} - // widgetScreen shows a panel containing widget demos func widgetScreen(_ fyne.Window) fyne.CanvasObject { content := container.NewVBox( From df6e249cd4b66b6e6ad8d760370b9e938f3a9896 Mon Sep 17 00:00:00 2001 From: Jacalz Date: Thu, 23 Jan 2025 11:05:06 +0100 Subject: [PATCH 2/3] Make sure to not also grow cleanups to infinity --- cmd/fyne_demo/main.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmd/fyne_demo/main.go b/cmd/fyne_demo/main.go index 3f219d03d5..007d407b4d 100644 --- a/cmd/fyne_demo/main.go +++ b/cmd/fyne_demo/main.go @@ -228,12 +228,13 @@ func makeNav(setTutorial func(tutorial tutorials.Tutorial), loadPrevious bool) f }, OnSelected: func(uid string) { if t, ok := tutorials.Tutorials[uid]; ok { - a.Preferences().SetString(preferenceCurrentTutorial, uid) - setTutorial(t) - for _, f := range tutorials.OnChangeFuncs { f(uid) } + tutorials.OnChangeFuncs = nil // Loading a page registers a new cleanup. + + a.Preferences().SetString(preferenceCurrentTutorial, uid) + setTutorial(t) } }, } From 49a459534ac64b9a0b91a75222b94c5bab33af54 Mon Sep 17 00:00:00 2001 From: Jacalz Date: Thu, 23 Jan 2025 11:06:13 +0100 Subject: [PATCH 3/3] Remove leftover debug print --- cmd/fyne_demo/tutorials/advanced.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/cmd/fyne_demo/tutorials/advanced.go b/cmd/fyne_demo/tutorials/advanced.go index c7fb9479ea..42b0a004b3 100644 --- a/cmd/fyne_demo/tutorials/advanced.go +++ b/cmd/fyne_demo/tutorials/advanced.go @@ -1,7 +1,6 @@ package tutorials import ( - "fmt" "strconv" "time" @@ -41,7 +40,6 @@ func advancedScreen(win fyne.Window) fyne.CanvasObject { OnChangeFuncs = append(OnChangeFuncs, func(page string) { if page != "advanced" { - fmt.Println("Stopped ticker") ticker.Stop() } })