Skip to content

Commit 5ebfdf9

Browse files
committed
new: added App.QueueUpdateContext and App.QueueUpdateDrawContext
1 parent 037df49 commit 5ebfdf9

File tree

1 file changed

+42
-4
lines changed

1 file changed

+42
-4
lines changed

application.go

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tview
22

33
import (
4+
"context"
45
"strings"
56
"sync"
67
"time"
@@ -478,7 +479,7 @@ EventLoop:
478479
case update := <-a.updates:
479480
update.f()
480481
if update.done != nil {
481-
update.done <- struct{}{}
482+
close(update.done)
482483
}
483484
}
484485
}
@@ -843,12 +844,40 @@ func (a *Application) GetFocus() Primitive {
843844
//
844845
// This function returns after f has executed.
845846
func (a *Application) QueueUpdate(f func()) *Application {
846-
ch := make(chan struct{})
847-
a.updates <- queuedUpdate{f: f, done: ch}
848-
<-ch
847+
_ = a.QueueUpdateContext(context.Background(), f)
848+
849849
return a
850850
}
851851

852+
// QueueUpdateContext is used to synchronize access to primitives from non-main
853+
// goroutines. The provided function will be executed as part of the event loop
854+
// and thus will not cause race conditions with other such update functions or
855+
// the Draw() function.
856+
//
857+
// Note that Draw() is not implicitly called after the execution of f as that
858+
// may not be desirable. You can call Draw() from f if the screen should be
859+
// refreshed after each update. Alternatively, use QueueUpdateDraw() to follow
860+
// up with an immediate refresh of the screen.
861+
//
862+
// This function returns with nil after f has executed or with an error
863+
// if context is done before that.
864+
func (a *Application) QueueUpdateContext(ctx context.Context, f func()) error {
865+
ch := make(chan struct{})
866+
select {
867+
case <-ctx.Done():
868+
return ctx.Err()
869+
case a.updates <- queuedUpdate{f: f, done: ch}:
870+
}
871+
872+
select {
873+
case <-ctx.Done():
874+
return ctx.Err()
875+
case <-ch:
876+
}
877+
878+
return nil
879+
}
880+
852881
// QueueUpdateDraw works like QueueUpdate() except it refreshes the screen
853882
// immediately after executing f.
854883
func (a *Application) QueueUpdateDraw(f func()) *Application {
@@ -859,6 +888,15 @@ func (a *Application) QueueUpdateDraw(f func()) *Application {
859888
return a
860889
}
861890

891+
// QueueUpdateDrawContext works like QueueUpdateContext() except it refreshes the screen
892+
// immediately after executing f.
893+
func (a *Application) QueueUpdateDrawContext(ctx context.Context, f func()) error {
894+
return a.QueueUpdateContext(ctx, func() {
895+
f()
896+
a.draw()
897+
})
898+
}
899+
862900
// QueueEvent sends an event to the Application event loop.
863901
//
864902
// It is not recommended for event to be nil.

0 commit comments

Comments
 (0)