diff --git a/bar.go b/bar.go index 9c13624..919109e 100644 --- a/bar.go +++ b/bar.go @@ -174,10 +174,18 @@ return s.appendFuncs } +func (b *Bar) NumOfAppenders() int { + return len(b.GetAppenders()) +} + // GetPrependers returns slice of prepender DecoratorFunc func (b *Bar) GetPrependers() []DecoratorFunc { s := b.getState() return s.prependFuncs +} + +func (b *Bar) NumOfPrependers() int { + return len(b.GetPrependers()) } // GetStatistics returs *Statistics, which contains information like Tottal, @@ -247,8 +255,7 @@ if isClosed(b.done) { return b.state } - // ch := make(chan state, 1) - ch := make(chan state) + ch := make(chan state, 1) b.stateReqCh <- ch return <-ch } @@ -353,13 +360,13 @@ } } -func (b *Bar) bytes(termWidth int, ws *widthSync) []byte { +func (b *Bar) bytes(termWidth int, prependWs, appendWs *widthSync) []byte { s := b.getState() - return draw(&s, termWidth, ws) -} - -func draw(s *state, termWidth int, ws *widthSync) []byte { - if len(s.prependFuncs) != len(ws.listen) { + return draw(&s, termWidth, prependWs, appendWs) +} + +func draw(s *state, termWidth int, prependWs, appendWs *widthSync) []byte { + if len(s.prependFuncs) != len(prependWs.listen) || len(s.appendFuncs) != len(appendWs.listen) { return []byte{} } if termWidth <= 0 { @@ -367,17 +374,19 @@ } stat := newStatistics(s) - - // render append functions to the right of the bar - var appendBlock []byte - for _, f := range s.appendFuncs { - appendBlock = append(appendBlock, []byte(f(stat, nil, nil))...) - } // render prepend functions to the left of the bar var prependBlock []byte for i, f := range s.prependFuncs { - prependBlock = append(prependBlock, []byte(f(stat, ws.listen[i], ws.result[i]))...) + prependBlock = append(prependBlock, + []byte(f(stat, prependWs.listen[i], prependWs.result[i]))...) + } + + // render append functions to the right of the bar + var appendBlock []byte + for i, f := range s.appendFuncs { + appendBlock = append(appendBlock, + []byte(f(stat, appendWs.listen[i], appendWs.result[i]))...) } prependCount := utf8.RuneCount(prependBlock) diff --git a/bar_test.go b/bar_test.go index c483f82..f72b673 100644 --- a/bar_test.go +++ b/bar_test.go @@ -71,6 +71,9 @@ }, } + stopWidthListen := make(chan struct{}) + prependWs := newWidthSync(stopWidthListen, 1, 0) + appendWs := newWidthSync(stopWidthListen, 1, 0) for _, test := range tests { s := newTestState() s.width = test.barWidth @@ -79,7 +82,7 @@ if test.barRefill != nil { s.refill = test.barRefill } - got := draw(s, test.termWidth) + got := draw(s, test.termWidth, prependWs, appendWs) if !reflect.DeepEqual(test.want, got) { t.Errorf("Want: %q, Got: %q\n", test.want, got) } diff --git a/example/sort/main.go b/example/sort/main.go index 8b56581..0683ef5 100644 --- a/example/sort/main.go +++ b/example/sort/main.go @@ -96,7 +96,7 @@ } func getDecor() mpb.DecoratorFunc { - return func(s *mpb.Statistics) string { + return func(s *mpb.Statistics, myWidth chan<- int, maxWidth <-chan int) string { str := fmt.Sprintf("%d/%d", s.Current, s.Total) return fmt.Sprintf("%-7s", str) } diff --git a/example_test.go b/example_test.go index 0bef21f..aefa932 100644 --- a/example_test.go +++ b/example_test.go @@ -47,7 +47,7 @@ } func ExampleBar_PrependFunc() { - decor := func(s *mpb.Statistics) string { + decor := func(s *mpb.Statistics, myWidth chan<- int, maxWidth <-chan int) string { str := fmt.Sprintf("%d/%d", s.Current, s.Total) return fmt.Sprintf("%8s", str) } @@ -63,7 +63,7 @@ } func ExampleBar_AppendFunc() { - decor := func(s *mpb.Statistics) string { + decor := func(s *mpb.Statistics, myWidth chan<- int, maxWidth <-chan int) string { str := fmt.Sprintf("%d/%d", s.Current, s.Total) return fmt.Sprintf("%8s", str) } diff --git a/progress.go b/progress.go index 8b9794d..4fa15b2 100644 --- a/progress.go +++ b/progress.go @@ -251,10 +251,6 @@ } op.result <- ok } - if len(bars) > 0 { - numPrependers = len(bars[0].GetPrependers()) - // numAppenders = len(bars[0].GetAppenders()) - } case respCh := <-p.barCountReqCh: respCh <- len(bars) case beforeRender = <-p.brCh: @@ -269,37 +265,9 @@ beforeRender(bars) } - prepWidthSync := &widthSync{ - listen: make([]chan int, numPrependers), - result: make([]chan int, numPrependers), - } - for i := 0; i < numPrependers; i++ { - prepWidthSync.listen[i] = make(chan int, numBars) - prepWidthSync.result[i] = make(chan int, numBars) - } stopWidthListen := make(chan struct{}) - for i, listenCh := range prepWidthSync.listen { - go func(listenCh <-chan int, resultCh chan<- int) { - widths := make([]int, 0, numBars) - loop: - for { - select { - case w := <-listenCh: - widths = append(widths, w) - if len(widths) == numBars { - break loop - } - case <-stopWidthListen: - return - } - } - result := max(widths) - for i := 0; i < numBars; i++ { - resultCh <- result - } - close(resultCh) - }(listenCh, prepWidthSync.result[i]) - } + prependWs := newWidthSync(stopWidthListen, numBars, bars[0].NumOfPrependers()) + appendWs := newWidthSync(stopWidthListen, numBars, bars[0].NumOfAppenders()) width, _, _ := cwriter.GetTermSize() ibars := iBarsGen(bars, width) @@ -307,18 +275,18 @@ wg.Add(numBars) for i := 0; i < numBars; i++ { go func() { - // defer recoverIfPanic() - defer func() { - wg.Done() - }() - drawer(ibars, ibbCh, prepWidthSync) + defer recoverIfPanic() + drawer(ibars, ibbCh, prependWs, appendWs) }() } go func() { wg.Wait() close(ibbCh) close(stopWidthListen) - for _, ch := range prepWidthSync.listen { + for _, ch := range prependWs.listen { + close(ch) + } + for _, ch := range appendWs.listen { close(ch) } }() @@ -345,9 +313,43 @@ } } -func drawer(ibars <-chan indexedBar, ibbCh chan<- indexedBarBuffer) { +func newWidthSync(stopListen chan struct{}, numBars, numColumn int) *widthSync { + ws := &widthSync{ + listen: make([]chan int, numColumn), + result: make([]chan int, numColumn), + } + for i := 0; i < numColumn; i++ { + ws.listen[i] = make(chan int, numBars) + ws.result[i] = make(chan int, numBars) + } + for i, listenCh := range ws.listen { + go func(listenCh <-chan int, resultCh chan<- int) { + widths := make([]int, 0, numBars) + loop: + for { + select { + case w := <-listenCh: + widths = append(widths, w) + if len(widths) == numBars { + break loop + } + case <-stopListen: + return + } + } + result := max(widths) + for i := 0; i < numBars; i++ { + resultCh <- result + } + close(resultCh) + }(listenCh, ws.result[i]) + } + return ws +} + +func drawer(ibars <-chan indexedBar, c chan<- indexedBarBuffer, prependWs, appendWs *widthSync) { for b := range ibars { - buf := b.bar.bytes(b.termWidth, ws) + buf := b.bar.bytes(b.termWidth, prependWs, appendWs) buf = append(buf, '\n') ibbCh <- indexedBarBuffer{b.index, buf} }