diff --git a/bar.go b/bar.go index f2bccee..7cea8ab 100644 --- a/bar.go +++ b/bar.go @@ -38,6 +38,7 @@ extendedLines int toShutdown bool toDrop bool + noPop bool operateState chan func(*bState) frameCh chan io.Reader syncTableCh chan [][]chan int @@ -71,6 +72,7 @@ toComplete bool completeFlushed bool noBufBOnComplete bool + noPop bool aDecorators []decor.Decorator pDecorators []decor.Decorator amountReceivers []decor.AmountReceiver @@ -103,6 +105,7 @@ container: container, priority: bs.priority, toDrop: bs.dropOnComplete, + noPop: bs.noPop, operateState: make(chan func(*bState)), frameCh: make(chan io.Reader, 1), syncTableCh: make(chan [][]chan int), diff --git a/bar_option.go b/bar_option.go index 65e517d..5a1e11a 100644 --- a/bar_option.go +++ b/bar_option.go @@ -167,6 +167,14 @@ return MakeFillerTypeSpecificBarOption(chk, cb) } +// BarNoPop disables bar pop out of container. Effective when +// PopCompletedMode of container is enabled. +func BarNoPop() BarOption { + return func(s *bState) { + s.noPop = true + } +} + // BarReverse reverse mode, bar will progress from right to left. func BarReverse() BarOption { chk := func(filler Filler) (interface{}, bool) { diff --git a/progress.go b/progress.go index e732edc..bddc46a 100644 --- a/progress.go +++ b/progress.go @@ -261,9 +261,8 @@ func (s *pState) flush(cw *cwriter.Writer) error { var lineCount int - hlen := s.bHeap.Len() - bb := make([]*Bar, hlen) - for i := 0; i < hlen; i++ { + bm := make(map[*Bar]struct{}, s.bHeap.Len()) + for s.bHeap.Len() > 0 { b := heap.Pop(&s.bHeap).(*Bar) defer func() { if b.toShutdown { @@ -278,11 +277,7 @@ }() cw.ReadFrom(<-b.frameCh) lineCount += b.extendedLines + 1 - bb[i] = b - } - - for _, b := range bb { - heap.Push(&s.bHeap, b) + bm[b] = struct{}{} } for _, b := range s.barShutdownQueue { @@ -293,23 +288,29 @@ b.toDrop = true } if b.toDrop { - heap.Remove(&s.bHeap, b.index) + delete(bm, b) s.heapUpdated = true } else if s.popCompleted { - defer func() { - s.barPopQueue = append(s.barPopQueue, b) - }() + if !b.noPop { + defer func() { + s.barPopQueue = append(s.barPopQueue, b) + }() + } } b.cancel() } s.barShutdownQueue = s.barShutdownQueue[0:0] for _, b := range s.barPopQueue { - heap.Remove(&s.bHeap, b.index) + delete(bm, b) s.heapUpdated = true lineCount -= b.extendedLines + 1 } s.barPopQueue = s.barPopQueue[0:0] + + for b := range bm { + heap.Push(&s.bHeap, b) + } return cw.Flush(lineCount) }