diff --git a/bar.go b/bar.go index 297cfa6..b282ab0 100644 --- a/bar.go +++ b/bar.go @@ -38,7 +38,6 @@ boolCh chan bool frameReaderCh chan *frameReader syncTableCh chan [][]chan int - bufNL *bytes.Buffer // done is closed by Bar's goroutine, after cacheState is written done chan struct{} @@ -65,6 +64,7 @@ shutdownListeners []decor.ShutdownListener refill *refill bufP, bufB, bufA *bytes.Buffer + bufNL *bytes.Buffer panicMsg string newLineExtendFn func(io.Writer, *decor.Statistics) @@ -78,6 +78,7 @@ } frameReader struct { io.Reader + extendedLines int toShutdown bool removeOnComplete bool } @@ -121,7 +122,7 @@ } if s.newLineExtendFn != nil { - b.bufNL = bytes.NewBuffer(make([]byte, 0, s.width)) + s.bufNL = bytes.NewBuffer(make([]byte, 0, s.width)) } go b.serve(wg, s, cancel) @@ -283,13 +284,16 @@ } }() r := s.draw(tw) + var extendedLines int if s.newLineExtendFn != nil { - b.bufNL.Reset() - s.newLineExtendFn(b.bufNL, newStatistics(s)) - r = io.MultiReader(r, b.bufNL) + s.bufNL.Reset() + s.newLineExtendFn(s.bufNL, newStatistics(s)) + extendedLines = countLines(s.bufNL.Bytes()) + r = io.MultiReader(r, s.bufNL) } b.frameReaderCh <- &frameReader{ Reader: r, + extendedLines: extendedLines, toShutdown: s.toComplete && !s.completeFlushed, removeOnComplete: s.removeOnComplete, } @@ -298,12 +302,17 @@ case <-b.done: s := b.cacheState r := s.draw(tw) + var extendedLines int if s.newLineExtendFn != nil { - b.bufNL.Reset() - s.newLineExtendFn(b.bufNL, newStatistics(s)) - r = io.MultiReader(r, b.bufNL) - } - b.frameReaderCh <- &frameReader{Reader: r} + s.bufNL.Reset() + s.newLineExtendFn(s.bufNL, newStatistics(s)) + extendedLines = countLines(s.bufNL.Bytes()) + r = io.MultiReader(r, s.bufNL) + } + b.frameReaderCh <- &frameReader{ + Reader: r, + extendedLines: extendedLines, + } } } @@ -435,3 +444,7 @@ } return } + +func countLines(b []byte) int { + return bytes.Count(b, []byte("\n")) +} diff --git a/cwriter/writer.go b/cwriter/writer.go index 8e7d01d..06adb90 100644 --- a/cwriter/writer.go +++ b/cwriter/writer.go @@ -27,22 +27,18 @@ type Writer struct { out io.Writer buf bytes.Buffer - lineSep []byte lineCount int } // New returns a new Writer with defaults func New(w io.Writer) *Writer { - return &Writer{ - out: w, - lineSep: []byte("\n"), - } + return &Writer{out: w} } // Flush flushes the underlying buffer -func (w *Writer) Flush() error { +func (w *Writer) Flush(lineCount int) error { err := w.clearLines() - w.lineCount = bytes.Count(w.buf.Bytes(), w.lineSep) + w.lineCount = lineCount // WriteTo takes care of w.buf.Reset if _, e := w.buf.WriteTo(w.out); err == nil { err = e diff --git a/progress.go b/progress.go index 4f6d5a3..b8f1c74 100644 --- a/progress.go +++ b/progress.go @@ -193,18 +193,15 @@ go bar.render(s.debugOut, tw) } - if err := s.flush(); err != nil { + if err := s.flush(s.bHeap.Len()); err != nil { fmt.Fprintf(s.debugOut, "%s %s %v\n", "[mpb]", time.Now(), err) } } -func (s *pState) flush() (err error) { +func (s *pState) flush(lineCount int) (err error) { for s.bHeap.Len() > 0 { bar := heap.Pop(s.bHeap).(*Bar) frameReader := <-bar.frameReaderCh - if _, e := s.cw.ReadFrom(frameReader); e != nil { - err = e - } defer func() { if frameReader.toShutdown { // shutdown at next flush, in other words decrement underlying WaitGroup @@ -223,11 +220,11 @@ } heap.Push(s.bHeap, bar) }() - } - - if e := s.cw.Flush(); err == nil { - err = e - } + _, err = s.cw.ReadFrom(frameReader) + lineCount += frameReader.extendedLines + } + + err = s.cw.Flush(lineCount) for i := len(s.shutdownPending) - 1; i >= 0; i-- { close(s.shutdownPending[i].shutdown)