| 42 | 42 |
operateState chan func(*bState)
|
| 43 | 43 |
cmdValue chan int
|
| 44 | 44 |
frameReaderCh chan io.Reader
|
|
45 |
bufNL *bytes.Buffer
|
| 45 | 46 |
|
| 46 | 47 |
// done is closed by Bar's goroutine, after cacheState is written
|
| 47 | 48 |
done chan struct{}
|
|
| 69 | 70 |
refill *refill
|
| 70 | 71 |
bufP, bufB, bufA *bytes.Buffer
|
| 71 | 72 |
panicMsg string
|
|
73 |
newLineExtendFn func(bool, io.Writer)
|
| 72 | 74 |
|
| 73 | 75 |
// following options are assigned to the *Bar
|
| 74 | 76 |
priority int
|
|
| 118 | 120 |
|
| 119 | 121 |
if b.runningBar != nil {
|
| 120 | 122 |
b.priority = b.runningBar.priority
|
|
123 |
}
|
|
124 |
|
|
125 |
if s.newLineExtendFn != nil {
|
|
126 |
b.bufNL = bytes.NewBuffer(make([]byte, 0, s.width))
|
| 121 | 127 |
}
|
| 122 | 128 |
|
| 123 | 129 |
go b.serve(wg, s, cancel)
|
|
| 282 | 288 |
}
|
| 283 | 289 |
|
| 284 | 290 |
func (b *Bar) render(debugOut io.Writer, tw int, pSyncer, aSyncer *widthSyncer) {
|
| 285 | |
var r io.Reader
|
| 286 | 291 |
select {
|
| 287 | 292 |
case b.operateState <- func(s *bState) {
|
| 288 | 293 |
defer func() {
|
| 289 | |
// recovering if external decorators panic
|
|
294 |
// recovering if user defined decorator panics for example
|
| 290 | 295 |
if p := recover(); p != nil {
|
| 291 | 296 |
s.panicMsg = fmt.Sprintf("panic: %v", p)
|
| 292 | |
s.pDecorators = nil
|
| 293 | |
s.aDecorators = nil
|
| 294 | |
s.toComplete = true
|
| 295 | |
// truncate panic msg to one tw line, if necessary
|
| 296 | |
r = strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%ds\n", tw), s.panicMsg))
|
| 297 | 297 |
fmt.Fprintf(debugOut, "%s %s bar id %02d %v\n", "[mpb]", time.Now(), s.id, s.panicMsg)
|
|
298 |
b.frameReaderCh <- &frameReader{
|
|
299 |
Reader: strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%ds\n", tw), s.panicMsg)),
|
|
300 |
toShutdown: true,
|
|
301 |
}
|
| 298 | 302 |
}
|
| 299 | |
b.frameReaderCh <- &frameReader{
|
| 300 | |
Reader: r,
|
| 301 | |
toShutdown: s.toComplete && !s.completeFlushed,
|
| 302 | |
removeOnComplete: s.removeOnComplete,
|
| 303 | |
}
|
| 304 | |
s.completeFlushed = s.toComplete
|
| 305 | 303 |
}()
|
| 306 | |
r = s.draw(tw, pSyncer, aSyncer)
|
|
304 |
r := s.draw(tw, pSyncer, aSyncer)
|
|
305 |
if s.newLineExtendFn != nil {
|
|
306 |
b.bufNL.Reset()
|
|
307 |
s.newLineExtendFn(s.completeFlushed, b.bufNL)
|
|
308 |
r = io.MultiReader(r, b.bufNL)
|
|
309 |
}
|
|
310 |
b.frameReaderCh <- &frameReader{
|
|
311 |
Reader: r,
|
|
312 |
toShutdown: s.toComplete && !s.completeFlushed,
|
|
313 |
removeOnComplete: s.removeOnComplete,
|
|
314 |
}
|
|
315 |
s.completeFlushed = s.toComplete
|
| 307 | 316 |
}:
|
| 308 | 317 |
case <-b.done:
|
| 309 | 318 |
s := b.cacheState
|
| 310 | |
if s.panicMsg != "" {
|
| 311 | |
r = strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%ds\n", tw), s.panicMsg))
|
| 312 | |
} else {
|
| 313 | |
r = s.draw(tw, pSyncer, aSyncer)
|
| 314 | |
}
|
| 315 | |
b.frameReaderCh <- &frameReader{
|
| 316 | |
Reader: r,
|
| 317 | |
}
|
|
319 |
r := s.draw(tw, pSyncer, aSyncer)
|
|
320 |
if s.newLineExtendFn != nil {
|
|
321 |
b.bufNL.Reset()
|
|
322 |
s.newLineExtendFn(s.completeFlushed, b.bufNL)
|
|
323 |
r = io.MultiReader(r, b.bufNL)
|
|
324 |
}
|
|
325 |
b.frameReaderCh <- &frameReader{Reader: r}
|
| 318 | 326 |
}
|
| 319 | 327 |
}
|
| 320 | 328 |
|
|
| 323 | 331 |
|
| 324 | 332 |
if termWidth <= 0 {
|
| 325 | 333 |
termWidth = s.width
|
|
334 |
}
|
|
335 |
|
|
336 |
if s.panicMsg != "" {
|
|
337 |
return strings.NewReader(fmt.Sprintf(fmt.Sprintf("%%.%ds\n", termWidth), s.panicMsg))
|
| 326 | 338 |
}
|
| 327 | 339 |
|
| 328 | 340 |
stat := newStatistics(s)
|