Codebase list golang-github-vbauerster-mpb / da24632
RemoveBar implementation Vladimir Bauer 9 years ago
1 changed file(s) with 47 addition(s) and 13 deletion(s). Raw diff Collapse all Expand all
88 "github.com/gosuri/uilive"
99 )
1010
11 type opType uint
12
13 const (
14 add opType = iota
15 remove
16 )
17
18 const refreshRate = 30
19
1120 // progress represents the container that renders progress bars
1221 type progress struct {
1322 // out is the writer to render progress bars to
1827
1928 lw *uilive.Writer
2029
21 // new Bars can be added over this channel
22 bars chan *Bar
30 op chan *operation
2331
2432 // new refresh interval to be send over this channel
2533 interval chan time.Duration
34 }
35
36 type operation struct {
37 kind opType
38 bar *Bar
39 ok chan bool
2640 }
2741
2842 // New returns a new progress bar with defaults
3044 p := &progress{
3145 out: os.Stdout,
3246 lw: uilive.New(),
33 bars: make(chan *Bar),
47 op: make(chan *operation),
3448 interval: make(chan time.Duration),
3549 }
3650 go p.server()
3751 return p
3852 }
3953
40 // RefreshInterval overrides default interval value 30 ms
41 func (p *progress) RefreshInterval(d time.Duration) *progress {
54 // RefreshRate overrides default (30ms) refreshRate value
55 func (p *progress) RefreshRate(d time.Duration) *progress {
4256 p.interval <- d
4357 return p
4458 }
5468 func (p *progress) AddBar(total int) *Bar {
5569 bar := NewBar(total)
5670 // bar.Width = p.Width
57 p.bars <- bar
71 p.op <- &operation{add, bar, nil}
5872 return bar
73 }
74
75 func (p *progress) RemoveBar(b *Bar) bool {
76 result := make(chan bool)
77 p.op <- &operation{remove, b, result}
78 return <-result
5979 }
6080
6181 // Bypass returns a writer which allows non-buffered data to be written to the underlying output
6585
6686 // Stop stops listening
6787 func (p *progress) Stop() {
68 close(p.bars)
88 close(p.op)
6989 }
7090
71 // server listens for updates and renders the progress bars
91 // server monitors underlying channels and renders any progress bars
7292 func (p *progress) server() {
73 t := time.NewTicker(30 * time.Millisecond)
93 t := time.NewTicker(refreshRate * time.Millisecond)
7494 bars := make([]*Bar, 0)
7595 p.lw.Out = p.out
7696 for {
7797 select {
78 case bar, ok := <-p.bars:
98 case op, ok := <-p.op:
7999 if !ok {
80100 t.Stop()
101 close(p.interval)
81102 return
82103 }
83 bars = append(bars, bar)
104 switch op.kind {
105 case add:
106 bars = append(bars, op.bar)
107 case remove:
108 var ok bool
109 for i, b := range bars {
110 if b == op.bar {
111 bars = append(bars[:i], bars[i+1:]...)
112 ok = true
113 break
114 }
115 }
116 op.ok <- ok
117 }
84118 case <-t.C:
85 for _, bar := range bars {
86 fmt.Fprintln(p.lw, bar.String())
119 for _, b := range bars {
120 fmt.Fprintln(p.lw, b.String())
87121 }
88122 p.lw.Flush()
89123 case d := <-p.interval: