From 1dd907c22c979a8b5873da3f26b01a4c35a54106 Mon Sep 17 00:00:00 2001 From: Jacob Date: Wed, 3 Jan 2024 14:34:21 +0100 Subject: [PATCH] Remove the lock from internal basewidget --- internal/widget/base.go | 54 +++++++++++++---------------------------- 1 file changed, 17 insertions(+), 37 deletions(-) diff --git a/internal/widget/base.go b/internal/widget/base.go index c647535596..2e7044ba7c 100644 --- a/internal/widget/base.go +++ b/internal/widget/base.go @@ -2,7 +2,6 @@ package widget import ( "math" - "sync" "sync/atomic" "fyne.io/fyne/v2" @@ -12,12 +11,10 @@ import ( // Base provides a helper that handles basic widget behaviours. type Base struct { - hidden bool + hidden atomic.Bool position atomic.Uint64 size atomic.Uint64 - - impl fyne.Widget - propertyLock sync.RWMutex + impl atomic.Pointer[fyne.Widget] } // ExtendBaseWidget is used by an extending widget to make use of BaseWidget functionality. @@ -27,9 +24,7 @@ func (w *Base) ExtendBaseWidget(wid fyne.Widget) { return } - w.propertyLock.Lock() - defer w.propertyLock.Unlock() - w.impl = wid + w.impl.Store(&wid) } // Size gets the current size of this widget. @@ -81,10 +76,7 @@ func (w *Base) MinSize() fyne.Size { // Visible returns whether or not this widget should be visible. // Note that this may not mean it is currently visible if a parent has been hidden. func (w *Base) Visible() bool { - w.propertyLock.RLock() - defer w.propertyLock.RUnlock() - - return !w.hidden + return !w.hidden.Load() } // Show this widget so it becomes visible @@ -93,9 +85,11 @@ func (w *Base) Show() { return } - w.setFieldsAndRefresh(func() { - w.hidden = false - }) + impl := w.super() + if impl == nil { + return + } + impl.Refresh() } // Hide this widget so it is no longer visible @@ -104,11 +98,9 @@ func (w *Base) Hide() { return } - w.propertyLock.Lock() - w.hidden = true - impl := w.impl - w.propertyLock.Unlock() + w.hidden.Store(true) + impl := w.super() if impl == nil { return } @@ -126,27 +118,15 @@ func (w *Base) Refresh() { render.Refresh() } -// setFieldsAndRefresh helps to make changes to a widget that should be followed by a refresh. -// This method is a guaranteed thread-safe way of directly manipulating widget fields. -func (w *Base) setFieldsAndRefresh(f func()) { - w.propertyLock.Lock() - f() - impl := w.impl - w.propertyLock.Unlock() - - if impl == nil { - return - } - impl.Refresh() -} - // super will return the actual object that this represents. // If extended then this is the extending widget, otherwise it is nil. func (w *Base) super() fyne.Widget { - w.propertyLock.RLock() - impl := w.impl - w.propertyLock.RUnlock() - return impl + impl := w.impl.Load() + if impl == nil { + return nil + } + + return *impl } // Repaint instructs the containing canvas to redraw, even if nothing changed.