diff --git a/options.go b/options.go index f9930b0..58eb5dd 100644 --- a/options.go +++ b/options.go @@ -43,7 +43,17 @@ // Refresh will occur upon receive value from provided ch. func WithManualRefresh(ch <-chan time.Time) ContainerOption { return func(s *pState) { - s.manualRefreshCh = ch + s.manualRefresh = ch + } +} + +// WithRenderDelay delays rendering. By default rendering starts as +// soon as bar is added, with this option it's possible to delay +// rendering process by keeping provided chan unclosed. In other words +// rendering will start as soon as provided chan is closed. +func WithRenderDelay(ch <-chan struct{}) ContainerOption { + return func(s *pState) { + s.renderDelay = ch } } @@ -61,7 +71,7 @@ func WithOutput(w io.Writer) ContainerOption { return func(s *pState) { if w == nil { - s.manualRefreshCh = make(chan time.Time) + s.manualRefresh = make(chan time.Time) s.output = ioutil.Discard return } diff --git a/progress.go b/progress.go index 546d7a1..52e27ed 100644 --- a/progress.go +++ b/progress.go @@ -49,7 +49,8 @@ popCompleted bool rr time.Duration uwg *sync.WaitGroup - manualRefreshCh <-chan time.Time + manualRefresh <-chan time.Time + renderDelay <-chan struct{} shutdownNotifier chan struct{} parkedBars map[*Bar]*Bar output io.Writer @@ -208,7 +209,7 @@ manualOrTickCh, cleanUp := s.manualOrTick() defer cleanUp() - refreshCh := fanInRefreshSrc(p.done, p.forceRefresh, manualOrTickCh) + refreshCh := fanInRefreshSrc(p.done, s.renderDelay, p.forceRefresh, manualOrTickCh) for { select { @@ -304,8 +305,8 @@ } func (s *pState) manualOrTick() (<-chan time.Time, func()) { - if s.manualRefreshCh != nil { - return s.manualRefreshCh, func() {} + if s.manualRefresh != nil { + return s.manualRefresh, func() {} } ticker := time.NewTicker(s.rr) return ticker.C, ticker.Stop @@ -373,12 +374,14 @@ } } -func fanInRefreshSrc(done <-chan struct{}, channels ...<-chan time.Time) <-chan time.Time { +func fanInRefreshSrc(done, delay <-chan struct{}, channels ...<-chan time.Time) <-chan time.Time { var wg sync.WaitGroup multiplexedStream := make(chan time.Time) + start := make(chan struct{}) multiplex := func(c <-chan time.Time) { defer wg.Done() + <-start // source channels are never closed (time.Ticker never closes associated // channel), so we cannot simply range over a c, instead we use select // inside infinite loop @@ -396,6 +399,15 @@ } } + if delay != nil { + go func() { + <-delay + close(start) + }() + } else { + close(start) + } + wg.Add(len(channels)) for _, c := range channels { go multiplex(c)