refactor examples and bar_test.go
Vladimir Bauer
9 years ago
| 173 | 173 | return s.appendFuncs |
| 174 | 174 | } |
| 175 | 175 | |
| 176 | func (b *Bar) NumOfAppenders() int { | |
| 177 | return len(b.GetAppenders()) | |
| 178 | } | |
| 179 | ||
| 176 | 180 | // GetPrependers returns slice of prepender DecoratorFunc |
| 177 | 181 | func (b *Bar) GetPrependers() []DecoratorFunc { |
| 178 | 182 | s := b.getState() |
| 179 | 183 | return s.prependFuncs |
| 184 | } | |
| 185 | ||
| 186 | func (b *Bar) NumOfPrependers() int { | |
| 187 | return len(b.GetPrependers()) | |
| 180 | 188 | } |
| 181 | 189 | |
| 182 | 190 | // GetStatistics returs *Statistics, which contains information like Tottal, |
| 246 | 254 | if isClosed(b.done) { |
| 247 | 255 | return b.state |
| 248 | 256 | } |
| 249 | // ch := make(chan state, 1) | |
| 250 | ch := make(chan state) | |
| 257 | ch := make(chan state, 1) | |
| 251 | 258 | b.stateReqCh <- ch |
| 252 | 259 | return <-ch |
| 253 | 260 | } |
| 352 | 359 | } |
| 353 | 360 | } |
| 354 | 361 | |
| 355 | func (b *Bar) bytes(termWidth int, ws *widthSync) []byte { | |
| 362 | func (b *Bar) bytes(termWidth int, prependWs, appendWs *widthSync) []byte { | |
| 356 | 363 | s := b.getState() |
| 357 | return draw(&s, termWidth, ws) | |
| 358 | } | |
| 359 | ||
| 360 | func draw(s *state, termWidth int, ws *widthSync) []byte { | |
| 361 | if len(s.prependFuncs) != len(ws.listen) { | |
| 364 | return draw(&s, termWidth, prependWs, appendWs) | |
| 365 | } | |
| 366 | ||
| 367 | func draw(s *state, termWidth int, prependWs, appendWs *widthSync) []byte { | |
| 368 | if len(s.prependFuncs) != len(prependWs.listen) || len(s.appendFuncs) != len(appendWs.listen) { | |
| 362 | 369 | return []byte{} |
| 363 | 370 | } |
| 364 | 371 | if termWidth <= 0 { |
| 366 | 373 | } |
| 367 | 374 | |
| 368 | 375 | stat := newStatistics(s) |
| 369 | ||
| 370 | // render append functions to the right of the bar | |
| 371 | var appendBlock []byte | |
| 372 | for _, f := range s.appendFuncs { | |
| 373 | appendBlock = append(appendBlock, []byte(f(stat, nil, nil))...) | |
| 374 | } | |
| 375 | 376 | |
| 376 | 377 | // render prepend functions to the left of the bar |
| 377 | 378 | var prependBlock []byte |
| 378 | 379 | for i, f := range s.prependFuncs { |
| 379 | prependBlock = append(prependBlock, []byte(f(stat, ws.listen[i], ws.result[i]))...) | |
| 380 | prependBlock = append(prependBlock, | |
| 381 | []byte(f(stat, prependWs.listen[i], prependWs.result[i]))...) | |
| 382 | } | |
| 383 | ||
| 384 | // render append functions to the right of the bar | |
| 385 | var appendBlock []byte | |
| 386 | for i, f := range s.appendFuncs { | |
| 387 | appendBlock = append(appendBlock, | |
| 388 | []byte(f(stat, appendWs.listen[i], appendWs.result[i]))...) | |
| 380 | 389 | } |
| 381 | 390 | |
| 382 | 391 | prependCount := utf8.RuneCount(prependBlock) |
| 70 | 70 | }, |
| 71 | 71 | } |
| 72 | 72 | |
| 73 | stopWidthListen := make(chan struct{}) | |
| 74 | prependWs := newWidthSync(stopWidthListen, 1, 0) | |
| 75 | appendWs := newWidthSync(stopWidthListen, 1, 0) | |
| 73 | 76 | for _, test := range tests { |
| 74 | 77 | s := newTestState() |
| 75 | 78 | s.width = test.barWidth |
| 78 | 81 | if test.barRefill != nil { |
| 79 | 82 | s.refill = test.barRefill |
| 80 | 83 | } |
| 81 | got := draw(s, test.termWidth) | |
| 84 | got := draw(s, test.termWidth, prependWs, appendWs) | |
| 82 | 85 | if !reflect.DeepEqual(test.want, got) { |
| 83 | 86 | t.Errorf("Want: %q, Got: %q\n", test.want, got) |
| 84 | 87 | } |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | 97 | func getDecor() mpb.DecoratorFunc { |
| 98 | return func(s *mpb.Statistics) string { | |
| 98 | return func(s *mpb.Statistics, myWidth chan<- int, maxWidth <-chan int) string { | |
| 99 | 99 | str := fmt.Sprintf("%d/%d", s.Current, s.Total) |
| 100 | 100 | return fmt.Sprintf("%-7s", str) |
| 101 | 101 | } |
| 46 | 46 | } |
| 47 | 47 | |
| 48 | 48 | func ExampleBar_PrependFunc() { |
| 49 | decor := func(s *mpb.Statistics) string { | |
| 49 | decor := func(s *mpb.Statistics, myWidth chan<- int, maxWidth <-chan int) string { | |
| 50 | 50 | str := fmt.Sprintf("%d/%d", s.Current, s.Total) |
| 51 | 51 | return fmt.Sprintf("%8s", str) |
| 52 | 52 | } |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | 64 | func ExampleBar_AppendFunc() { |
| 65 | decor := func(s *mpb.Statistics) string { | |
| 65 | decor := func(s *mpb.Statistics, myWidth chan<- int, maxWidth <-chan int) string { | |
| 66 | 66 | str := fmt.Sprintf("%d/%d", s.Current, s.Total) |
| 67 | 67 | return fmt.Sprintf("%8s", str) |
| 68 | 68 | } |
| 250 | 250 | } |
| 251 | 251 | op.result <- ok |
| 252 | 252 | } |
| 253 | if len(bars) > 0 { | |
| 254 | numPrependers = len(bars[0].GetPrependers()) | |
| 255 | // numAppenders = len(bars[0].GetAppenders()) | |
| 256 | } | |
| 257 | 253 | case respCh := <-p.barCountReqCh: |
| 258 | 254 | respCh <- len(bars) |
| 259 | 255 | case beforeRender = <-p.brCh: |
| 268 | 264 | beforeRender(bars) |
| 269 | 265 | } |
| 270 | 266 | |
| 271 | prepWidthSync := &widthSync{ | |
| 272 | listen: make([]chan int, numPrependers), | |
| 273 | result: make([]chan int, numPrependers), | |
| 274 | } | |
| 275 | for i := 0; i < numPrependers; i++ { | |
| 276 | prepWidthSync.listen[i] = make(chan int, numBars) | |
| 277 | prepWidthSync.result[i] = make(chan int, numBars) | |
| 278 | } | |
| 279 | 267 | stopWidthListen := make(chan struct{}) |
| 280 | for i, listenCh := range prepWidthSync.listen { | |
| 281 | go func(listenCh <-chan int, resultCh chan<- int) { | |
| 282 | widths := make([]int, 0, numBars) | |
| 283 | loop: | |
| 284 | for { | |
| 285 | select { | |
| 286 | case w := <-listenCh: | |
| 287 | widths = append(widths, w) | |
| 288 | if len(widths) == numBars { | |
| 289 | break loop | |
| 290 | } | |
| 291 | case <-stopWidthListen: | |
| 292 | return | |
| 293 | } | |
| 294 | } | |
| 295 | result := max(widths) | |
| 296 | for i := 0; i < numBars; i++ { | |
| 297 | resultCh <- result | |
| 298 | } | |
| 299 | close(resultCh) | |
| 300 | }(listenCh, prepWidthSync.result[i]) | |
| 301 | } | |
| 268 | prependWs := newWidthSync(stopWidthListen, numBars, bars[0].NumOfPrependers()) | |
| 269 | appendWs := newWidthSync(stopWidthListen, numBars, bars[0].NumOfAppenders()) | |
| 302 | 270 | |
| 303 | 271 | width, _, _ := cwriter.GetTermSize() |
| 304 | 272 | ibars := iBarsGen(bars, width) |
| 306 | 274 | wg.Add(numBars) |
| 307 | 275 | for i := 0; i < numBars; i++ { |
| 308 | 276 | go func() { |
| 309 | // defer recoverIfPanic() | |
| 310 | defer func() { | |
| 311 | wg.Done() | |
| 312 | }() | |
| 313 | drawer(ibars, ibbCh, prepWidthSync) | |
| 277 | defer recoverIfPanic() | |
| 278 | drawer(ibars, ibbCh, prependWs, appendWs) | |
| 314 | 279 | }() |
| 315 | 280 | } |
| 316 | 281 | go func() { |
| 317 | 282 | wg.Wait() |
| 318 | 283 | close(ibbCh) |
| 319 | 284 | close(stopWidthListen) |
| 320 | for _, ch := range prepWidthSync.listen { | |
| 285 | for _, ch := range prependWs.listen { | |
| 286 | close(ch) | |
| 287 | } | |
| 288 | for _, ch := range appendWs.listen { | |
| 321 | 289 | close(ch) |
| 322 | 290 | } |
| 323 | 291 | }() |
| 344 | 312 | } |
| 345 | 313 | } |
| 346 | 314 | |
| 347 | func drawer(ibars <-chan indexedBar, ibbCh chan<- indexedBarBuffer) { | |
| 315 | func newWidthSync(stopListen chan struct{}, numBars, numColumn int) *widthSync { | |
| 316 | ws := &widthSync{ | |
| 317 | listen: make([]chan int, numColumn), | |
| 318 | result: make([]chan int, numColumn), | |
| 319 | } | |
| 320 | for i := 0; i < numColumn; i++ { | |
| 321 | ws.listen[i] = make(chan int, numBars) | |
| 322 | ws.result[i] = make(chan int, numBars) | |
| 323 | } | |
| 324 | for i, listenCh := range ws.listen { | |
| 325 | go func(listenCh <-chan int, resultCh chan<- int) { | |
| 326 | widths := make([]int, 0, numBars) | |
| 327 | loop: | |
| 328 | for { | |
| 329 | select { | |
| 330 | case w := <-listenCh: | |
| 331 | widths = append(widths, w) | |
| 332 | if len(widths) == numBars { | |
| 333 | break loop | |
| 334 | } | |
| 335 | case <-stopListen: | |
| 336 | return | |
| 337 | } | |
| 338 | } | |
| 339 | result := max(widths) | |
| 340 | for i := 0; i < numBars; i++ { | |
| 341 | resultCh <- result | |
| 342 | } | |
| 343 | close(resultCh) | |
| 344 | }(listenCh, ws.result[i]) | |
| 345 | } | |
| 346 | return ws | |
| 347 | } | |
| 348 | ||
| 349 | func drawer(ibars <-chan indexedBar, c chan<- indexedBarBuffer, prependWs, appendWs *widthSync) { | |
| 348 | 350 | for b := range ibars { |
| 349 | buf := b.bar.bytes(b.termWidth, ws) | |
| 351 | buf := b.bar.bytes(b.termWidth, prependWs, appendWs) | |
| 350 | 352 | buf = append(buf, '\n') |
| 351 | 353 | ibbCh <- indexedBarBuffer{b.index, buf} |
| 352 | 354 | } |