Codebase list golang-github-vbauerster-mpb / 4cedf13
Refil is a struct for b.IncrWithReFill Vladimir Bauer 9 years ago
2 changed file(s) with 71 addition(s) and 67 deletion(s). Raw diff Collapse all Expand all
00 package mpb
11
22 import (
3 "fmt"
43 "io"
54 "math"
65 "sync"
2120
2221 // Bar represents a progress Bar
2322 type Bar struct {
24 stateReqCh chan state
25 incrCh chan int64
26 dCommandCh chan *dCommandData
27 flushedCh chan struct{}
28 removeReqCh chan struct{}
29 completeReqCh chan struct{}
30 done chan struct{}
31 cancel <-chan struct{}
23 stateReqCh chan state
24 incrCh chan incrReq
25 dCommandCh chan *dCommandData
26 flushedCh chan struct{}
27 removeReqCh chan struct{}
28 completedCh chan struct{}
29 done chan struct{}
30 cancel <-chan struct{}
3231
3332 // follawing are used after (*Bar.done) is closed
3433 width int
4645 TimePerItemEstimate time.Duration
4746 }
4847
48 // Refil is a struct for b.IncrWithReFill
49 type Refill struct {
50 Char rune
51 Till int64
52 }
53
4954 // Eta returns exponential-weighted-moving-average ETA estimator
5055 func (s *Statistics) Eta() time.Duration {
5156 return time.Duration(s.Total-s.Current) * s.TimePerItemEstimate
5257 }
5358
5459 type (
55 refill struct {
56 char rune
57 till int64
60 incrReq struct {
61 amount int64
62 refill *Refill
5863 }
5964 state struct {
6065 id int
7277 appendFuncs []DecoratorFunc
7378 prependFuncs []DecoratorFunc
7479 simpleSpinner func() byte
75 refill *refill
80 refill *Refill
7681 }
7782 )
7883
7984 func newBar(id int, total int64, wg *sync.WaitGroup, conf *userConf) *Bar {
8085 b := &Bar{
81 width: conf.width,
82 stateReqCh: make(chan state),
83 incrCh: make(chan int64, 1),
84 dCommandCh: make(chan *dCommandData),
85 flushedCh: make(chan struct{}, 1),
86 removeReqCh: make(chan struct{}),
87 completeReqCh: make(chan struct{}),
88 done: make(chan struct{}),
89 cancel: conf.cancel,
86 width: conf.width,
87 stateReqCh: make(chan state),
88 incrCh: make(chan incrReq),
89 dCommandCh: make(chan *dCommandData),
90 flushedCh: make(chan struct{}),
91 removeReqCh: make(chan struct{}),
92 completedCh: make(chan struct{}),
93 done: make(chan struct{}),
94 cancel: conf.cancel,
9095 }
9196
9297 s := state{
172177
173178 // Incr increments progress bar
174179 func (b *Bar) Incr(n int) {
175 if n < 1 || isClosed(b.done) {
176 return
177 }
178 b.incrCh <- int64(n)
180 b.IncrWithReFill(n, nil)
179181 }
180182
181183 // IncrWithReFill increments pb with different fill character
182 func (b *Bar) IncrWithReFill(n int, r rune) {
183 if isClosed(b.done) {
184 return
185 }
186 b.Incr(n)
187 // b.refillCh <- &refill{r, int64(n)}
188 s := <-b.stateReqCh
189 s.refill = &refill{r, int64(n)}
190 b.stateReqCh <- s
184 func (b *Bar) IncrWithReFill(n int, refill *Refill) {
185 if n < 1 {
186 return
187 }
188 select {
189 case b.incrCh <- incrReq{int64(n), refill}:
190 case <-b.done:
191 return
192 }
191193 }
192194
193195 // GetAppenders returns slice of appender DecoratorFunc
266268 // You should call this method when total is unknown and you've reached the point
267269 // of process completion.
268270 func (b *Bar) Completed() {
269 if isClosed(b.done) {
270 return
271 }
272 b.completeReqCh <- struct{}{}
271 select {
272 case b.completedCh <- struct{}{}:
273 case <-b.done:
274 return
275 }
273276 }
274277
275278 func (b *Bar) getState() state {
276 if isClosed(b.done) {
279 select {
280 case s := <-b.stateReqCh:
281 return s
282 case <-b.done:
277283 return b.state
278284 }
279 return <-b.stateReqCh
280285 }
281286
282287 func (b *Bar) server(wg *sync.WaitGroup, s state) {
283288 var incrStartTime time.Time
284289
285290 defer func() {
286 // b.stop(&barState, conf.width)
287 b.stop(&s)
291 b.state = s
288292 wg.Done()
289 fmt.Printf("Exited bar %d\n", s.id)
293 // fmt.Printf("Exited bar %d\n", s.id)
294 close(b.done)
290295 }()
291296
292297 for {
293298 select {
294299 case b.stateReqCh <- s:
295300 case s = <-b.stateReqCh:
296 case amount := <-b.incrCh:
301 case r := <-b.incrCh:
297302 if s.current == 0 {
298303 incrStartTime = time.Now()
299304 s.startTime = incrStartTime
300305 }
301 n := s.current + amount
306 n := s.current + r.amount
302307 if s.total > 0 && n > s.total {
303308 s.current = s.total
304309 s.completed = true
305310 break // break out of select
306311 }
307312 s.timeElapsed = time.Since(s.startTime)
308 s.updateTimePerItemEstimate(incrStartTime, amount)
313 s.updateTimePerItemEstimate(incrStartTime, r.amount)
309314 if n == s.total {
310315 s.completed = true
311316 }
312317 s.current = n
318 s.refill = r.refill
313319 incrStartTime = time.Now()
314320 case data := <-b.dCommandCh:
315321 switch data.action {
326332 if s.completed {
327333 return
328334 }
329 case <-b.completeReqCh:
335 case <-b.completedCh:
336 s.completed = true
330337 return
331338 case <-b.removeReqCh:
332339 return
336343 }
337344 }
338345
339 func (b *Bar) stop(s *state) {
340 b.state = *s
341 close(b.done)
342 }
343
344346 func (b *Bar) flushed() {
345 if isClosed(b.done) {
346 return
347 }
348 b.flushedCh <- struct{}{}
347 select {
348 case b.flushedCh <- struct{}{}:
349 case <-b.done:
350 return
351 }
349352 }
350353
351354 func (b *Bar) remove() {
352 if isClosed(b.done) {
353 return
354 }
355 b.removeReqCh <- struct{}{}
355 select {
356 case b.removeReqCh <- struct{}{}:
357 case <-b.done:
358 return
359 }
356360 }
357361
358362 func (b *Bar) render(rFn func(chan []byte), termWidth int, prependWs, appendWs *widthSync) <-chan []byte {
450454 return buf
451455 }
452456
453 func fillBar(total, current int64, width int, fmtBytes barFmtBytes, rf *refill) []byte {
457 func fillBar(total, current int64, width int, fmtBytes barFmtBytes, rf *Refill) []byte {
454458 if width < 2 || total <= 0 {
455459 return []byte{}
456460 }
464468 buf = append(buf, fmtBytes[rLeft]...)
465469
466470 if rf != nil {
467 till := percentage(total, rf.till, barWidth)
468 rbytes := make([]byte, utf8.RuneLen(rf.char))
469 utf8.EncodeRune(rbytes, rf.char)
471 till := percentage(total, rf.Till, barWidth)
472 rbytes := make([]byte, utf8.RuneLen(rf.Char))
473 utf8.EncodeRune(rbytes, rf.Char)
470474 // append refill rune
471475 for i := 0; i < till; i++ {
472476 buf = append(buf, rbytes...)
1010 barWidth int
1111 total int64
1212 current int64
13 barRefill *refill
13 barRefill *Refill
1414 want []byte
1515 }{
1616 {
6565 barWidth: 100,
6666 total: 100,
6767 current: 40,
68 barRefill: &refill{'+', 32},
68 barRefill: &Refill{'+', 32},
6969 want: []byte("[+++++++++++++++++++++++++++++++=======>-----------------------------------------------------------]"),
7070 },
7171 {