diff --git a/bar.go b/bar.go index 271feb2..d20204c 100644 --- a/bar.go +++ b/bar.go @@ -51,7 +51,7 @@ buffers [3]*bytes.Buffer filler BarFiller extender extenderFunc - manualRefresh chan interface{} + refreshCh chan time.Time wait struct { bar *Bar // key for (*pState).queueBars @@ -186,7 +186,7 @@ if s.current >= s.total { s.current = s.total s.completed = true - b.forceRefresh(s.manualRefresh) + b.forceRefresh(s.refreshCh) } else { s.triggerComplete = true } @@ -214,7 +214,7 @@ if triggerCompleteNow { s.current = s.total s.completed = true - b.forceRefresh(s.manualRefresh) + b.forceRefresh(s.refreshCh) } }: case <-b.done: @@ -232,7 +232,7 @@ if s.triggerComplete && s.current >= s.total { s.current = s.total s.completed = true - b.forceRefresh(s.manualRefresh) + b.forceRefresh(s.refreshCh) } }: case <-b.done: @@ -254,7 +254,7 @@ if s.triggerComplete && s.current >= s.total { s.current = s.total s.completed = true - b.forceRefresh(s.manualRefresh) + b.forceRefresh(s.refreshCh) } }: case <-b.done: @@ -282,7 +282,7 @@ if s.triggerComplete && s.current >= s.total { s.current = s.total s.completed = true - b.forceRefresh(s.manualRefresh) + b.forceRefresh(s.refreshCh) } }: case <-b.done: @@ -312,7 +312,7 @@ if s.triggerComplete && s.current >= s.total { s.current = s.total s.completed = true - b.forceRefresh(s.manualRefresh) + b.forceRefresh(s.refreshCh) } }: case <-b.done: @@ -350,7 +350,7 @@ } s.aborted = true s.dropOnComplete = drop - b.forceRefresh(s.manualRefresh) + b.forceRefresh(s.refreshCh) }: case <-b.done: } @@ -449,12 +449,12 @@ } } -func (b *Bar) forceRefresh(refreshCh chan<- interface{}) { +func (b *Bar) forceRefresh(refreshCh chan<- time.Time) { b.container.bwg.Add(1) go b.forceRefreshImpl(refreshCh) } -func (b *Bar) forceRefreshImpl(refreshCh chan<- interface{}) { +func (b *Bar) forceRefreshImpl(refreshCh chan<- time.Time) { defer b.container.bwg.Done() var anyOtherRunning bool b.container.traverseBars(func(bar *Bar) bool { diff --git a/container_option.go b/container_option.go index 5d27d5f..c482576 100644 --- a/container_option.go +++ b/container_option.go @@ -39,10 +39,23 @@ // WithManualRefresh disables internal auto refresh time.Ticker. // Refresh will occur upon receive value from provided ch. -func WithManualRefresh(ch chan interface{}) ContainerOption { +func WithManualRefresh(ch <-chan interface{}) ContainerOption { return func(s *pState) { - s.manualRefresh = ch - s.disableAutoRefresh = true + s.manualRefresh = true + go func(refreshCh chan<- time.Time, done <-chan struct{}) { + for { + select { + case x := <-ch: + if t, ok := x.(time.Time); ok { + refreshCh <- t + } else { + refreshCh <- time.Now() + } + case <-done: + return + } + } + }(s.refreshCh, s.ctx.Done()) } } diff --git a/progress.go b/progress.go index fc32f9e..c62ebc7 100644 --- a/progress.go +++ b/progress.go @@ -36,23 +36,23 @@ ctx context.Context hm heapManager dropS, dropD chan struct{} + refreshCh chan time.Time rows []io.Reader // following are provided/overrided by user - refreshRate time.Duration - idCount int - reqWidth int - popPriority int - popCompleted bool - disableAutoRefresh bool - forceAutoRefresh bool - manualRefresh chan interface{} - renderDelay <-chan struct{} - shutdownNotifier chan<- interface{} - queueBars map[*Bar]*Bar - output io.Writer - debugOut io.Writer - uwg *sync.WaitGroup + refreshRate time.Duration + idCount int + reqWidth int + popPriority int + popCompleted bool + manualRefresh bool + forceAutoRefresh bool + renderDelay <-chan struct{} + shutdownNotifier chan<- interface{} + queueBars map[*Bar]*Bar + output io.Writer + debugOut io.Writer + uwg *sync.WaitGroup } // New creates new Progress container instance. It's not possible to @@ -71,6 +71,7 @@ hm: make(heapManager), dropS: make(chan struct{}), dropD: make(chan struct{}), + refreshCh: make(chan time.Time), rows: make([]io.Reader, 32), refreshRate: defaultRefreshRate, popPriority: math.MinInt32, @@ -83,10 +84,6 @@ if opt != nil { opt(s) } - } - - if s.manualRefresh == nil { - s.manualRefresh = make(chan interface{}) } p := &Progress{ @@ -274,7 +271,7 @@ ch := make(chan time.Time, 1) go func() { var autoRefresh <-chan time.Time - if (isTerminal || s.forceAutoRefresh) && !s.disableAutoRefresh { + if (isTerminal || s.forceAutoRefresh) && !s.manualRefresh { if s.renderDelay != nil { <-s.renderDelay } @@ -286,12 +283,8 @@ select { case t := <-autoRefresh: ch <- t - case x := <-s.manualRefresh: - if t, ok := x.(time.Time); ok { - ch <- t - } else { - ch <- time.Now() - } + case t := <-s.refreshCh: + ch <- t case <-s.ctx.Done(): close(done) return @@ -401,12 +394,12 @@ func (s *pState) makeBarState(total int64, filler BarFiller, options ...BarOption) *bState { bs := &bState{ - id: s.idCount, - priority: s.idCount, - reqWidth: s.reqWidth, - total: total, - filler: filler, - manualRefresh: s.manualRefresh, + id: s.idCount, + priority: s.idCount, + reqWidth: s.reqWidth, + total: total, + filler: filler, + refreshCh: s.refreshCh, } if total > 0 {