Codebase list golang-github-vbauerster-mpb / f35fd6c
server<-t.C: sequencing without helper map Vladimir Bauer 9 years ago
2 changed file(s) with 34 addition(s) and 47 deletion(s). Raw diff Collapse all Expand all
360360 }
361361 }
362362
363 func (b *Bar) bytes(termWidth int, prependWs, appendWs *widthSync) []byte {
364 s := b.getState()
365 return draw(&s, termWidth, prependWs, appendWs)
363 func (b *Bar) render(rFn func(chan []byte), termWidth int, prependWs, appendWs *widthSync) <-chan []byte {
364 ch := make(chan []byte)
365
366 go func() {
367 defer rFn(ch)
368 s := b.getState()
369 buf := draw(&s, termWidth, prependWs, appendWs)
370 buf = append(buf, '\n')
371 ch <- buf
372 }()
373
374 return ch
366375 }
367376
368377 func draw(s *state, termWidth int, prependWs, appendWs *widthSync) []byte {
11
22 import (
33 "errors"
4 "fmt"
45 "io"
56 "log"
67 "os"
227228 close(p.done)
228229 }()
229230
230 var wg sync.WaitGroup
231 recoverIfPanic := func() {
231 recoverFn := func(ch chan []byte) {
232232 if p := recover(); p != nil {
233 logger.Printf("unexpected panic: %+v\n", p)
234233 var buf [4096]byte
235234 n := runtime.Stack(buf[:], false)
236235 os.Stderr.Write(buf[:n])
236 ch <- []byte(fmt.Sprintln(p))
237237 }
238 wg.Done()
238 close(ch)
239239 }
240240
241241 var beforeRender BeforeRender
291291 appendWs := newWidthSync(quitWidthSyncCh, numBars, b0.NumOfAppenders())
292292
293293 width, _, _ := cwriter.GetTermSize()
294 ibars := iBarsGen(bars, width)
295 ibbCh := make(chan indexedBarBuffer)
296 wg.Add(numBars)
297 for i := 0; i < numBars; i++ {
298 go func() {
299 defer recoverIfPanic()
300 drawer(ibars, ibbCh, prependWs, appendWs)
301 }()
302 }
303 go func() {
304 wg.Wait()
305 close(ibbCh)
306 for _, ch := range prependWs.listen {
307 close(ch)
308 }
309 for _, ch := range appendWs.listen {
310 close(ch)
311 }
312 }()
313
314 m := make(map[int][]byte, len(bars))
315 for ibb := range ibbCh {
316 m[ibb.index] = ibb.buf
317 }
318 for i := 0; i < len(bars); i++ {
319 cw.Write(m[i])
294
295 sequence := make([]<-chan []byte, numBars)
296 for i, b := range bars {
297 sequence[i] = b.render(recoverFn, width, prependWs, appendWs)
298 }
299
300 ch := fanIn(sequence...)
301
302 for buf := range ch {
303 cw.Write(buf)
320304 }
321305
322306 cw.Flush()
370354 return ws
371355 }
372356
373 func drawer(ibars <-chan indexedBar, ibbCh chan<- indexedBarBuffer, prependWs, appendWs *widthSync) {
374 for b := range ibars {
375 buf := b.bar.bytes(b.termWidth, prependWs, appendWs)
376 buf = append(buf, '\n')
377 ibbCh <- indexedBarBuffer{b.index, buf}
378 }
379 }
380
381 func iBarsGen(bars []*Bar, width int) <-chan indexedBar {
382 ibars := make(chan indexedBar)
357 func fanIn(inputs ...<-chan []byte) <-chan []byte {
358 ch := make(chan []byte)
359
383360 go func() {
384 defer close(ibars)
385 for i, b := range bars {
386 ibars <- indexedBar{i, width, b}
361 defer close(ch)
362 for _, input := range inputs {
363 ch <- <-input
387364 }
388365 }()
389 return ibars
366
367 return ch
390368 }
391369
392370 // isClosed check if ch closed