Codebase list golang-github-vbauerster-mpb / 5143d91
Dynamic total auto increment Vladimir Bauer 8 years ago
4 changed file(s) with 107 addition(s) and 44 deletion(s). Raw diff Collapse all Expand all
4242
4343 type (
4444 bState struct {
45 id int
46 width int
47 format fmtRunes
48 etaAlpha float64
49 total int64
50 current int64
51 dropRatio int64
52 trimLeftSpace bool
53 trimRightSpace bool
54 completed bool
55 aborted bool
56 dynamic bool
57 startTime time.Time
58 timeElapsed time.Duration
59 blockStartTime time.Time
60 timePerItem time.Duration
61 appendFuncs []decor.DecoratorFunc
62 prependFuncs []decor.DecoratorFunc
63 refill *refill
64 bufP, bufB, bufA *bytes.Buffer
65 panic string
45 id int
46 width int
47 format fmtRunes
48 etaAlpha float64
49 total int64
50 current int64
51 totalAutoIncrTrigger int64
52 totalAutoIncrBy int64
53 trimLeftSpace bool
54 trimRightSpace bool
55 completed bool
56 aborted bool
57 dynamic bool
58 startTime time.Time
59 timeElapsed time.Duration
60 blockStartTime time.Time
61 timePerItem time.Duration
62 appendFuncs []decor.DecoratorFunc
63 prependFuncs []decor.DecoratorFunc
64 refill *refill
65 bufP, bufB, bufA *bytes.Buffer
66 panic string
6667 }
6768 refill struct {
6869 char rune
8081 }
8182
8283 s := &bState{
83 id: id,
84 total: total,
85 etaAlpha: etaAlpha,
86 dropRatio: 10,
84 id: id,
85 total: total,
86 etaAlpha: etaAlpha,
87 totalAutoIncrTrigger: 10,
8788 }
8889
8990 for _, opt := range options {
152153 }
153154 s.current += int64(n)
154155 if s.dynamic {
155 for s.current >= s.total {
156 s.current -= s.current * s.dropRatio / 100
156 curp := decor.CalcPercentage(s.total, s.current, 100)
157 if 100-curp <= s.totalAutoIncrTrigger {
158 s.total += s.totalAutoIncrBy
157159 }
158160 } else if s.current >= s.total {
159161 s.current = s.total
388390 // bar s.width without leftEnd and rightEnd runes
389391 barWidth := width - 2
390392
391 completedWidth := decor.CalcPercentage(s.total, s.current, barWidth)
393 completedWidth := decor.CalcPercentage(s.total, s.current, int64(barWidth))
392394
393395 if s.refill != nil {
394 till := decor.CalcPercentage(s.total, s.refill.till, barWidth)
396 till := decor.CalcPercentage(s.total, s.refill.till, int64(barWidth))
395397 // append refill rune
396 for i := 0; i < till; i++ {
398 var i int64
399 for i = 0; i < till; i++ {
397400 s.bufB.WriteRune(s.refill.char)
398401 }
399 for i := till; i < completedWidth; i++ {
402 for i = till; i < completedWidth; i++ {
400403 s.bufB.WriteRune(s.format[rFill])
401404 }
402405 } else {
403 for i := 0; i < completedWidth; i++ {
406 var i int64
407 for i = 0; i < completedWidth; i++ {
404408 s.bufB.WriteRune(s.format[rFill])
405409 }
406410 }
407411
408 if completedWidth < barWidth && completedWidth > 0 {
412 if completedWidth < int64(barWidth) && completedWidth > 0 {
409413 _, size := utf8.DecodeLastRune(s.bufB.Bytes())
410414 s.bufB.Truncate(s.bufB.Len() - size)
411415 s.bufB.WriteRune(s.format[rTip])
412416 }
413417
414 for i := completedWidth; i < barWidth; i++ {
418 for i := completedWidth; i < int64(barWidth); i++ {
415419 s.bufB.WriteRune(s.format[rEmpty])
416420 }
417421
5757 }
5858 }
5959
60 // BarDropRatio sets drop ratio, default is 10. Effective when total is dynamic.
61 // If progress tip reaches total, but total is not final value yet, tip will be
62 // dropped by specified ratio.
63 func BarDropRatio(ratio int64) BarOption {
60 // BarDynamicTotal enables dynamic total behaviour.
61 func BarDynamicTotal() BarOption {
6462 return func(s *bState) {
65 s.dropRatio = ratio
63 s.dynamic = true
64 }
65 }
66
67 // BarAutoIncrTotal auto increment total by amount, when trigger percentage remained till bar completion.
68 // In other words: say you've set trigger = 10, then auto increment will start after bar reaches 90 %.
69 func BarAutoIncrTotal(trigger, amount int64) BarOption {
70 return func(s *bState) {
71 s.dynamic = true
72 s.totalAutoIncrTrigger = trigger
73 s.totalAutoIncrBy = amount
6674 }
6775 }
6876
203203 }
204204 }
205205
206 func CalcPercentage(total, current int64, width int) int {
206 func CalcPercentage(total, current, width int64) int64 {
207207 if total == 0 || current > total {
208208 return 0
209209 }
213213 // num = 2.34 will return 2
214214 // num = 2.44 will return 3
215215 if math.Max(diff, 0.6) == diff {
216 return int(num)
217 }
218 return int(ceil)
219 }
216 return int64(num)
217 }
218 return int64(ceil)
219 }
0 package main
1
2 import (
3 "math/rand"
4 "time"
5
6 "github.com/vbauerster/mpb"
7 "github.com/vbauerster/mpb/decor"
8 )
9
10 func main() {
11 p := mpb.New()
12
13 // initialize bar with dynamic total and initial total guess = 80
14 bar := p.AddBar(80,
15 // indicate that total is dynamic
16 mpb.BarDynamicTotal(),
17 // trigger total auto increment by 1, when 18 % remains till bar completion
18 mpb.BarAutoIncrTotal(18, 1),
19 mpb.PrependDecorators(
20 decor.CountersNoUnit("%d / %d", 12, 0),
21 ),
22 mpb.AppendDecorators(
23 decor.Percentage(5, 0),
24 ),
25 )
26
27 totalUpd1 := make(chan struct{})
28 totalUpd2 := make(chan struct{})
29 go func() {
30 <-totalUpd1
31 // intermediate not final total update
32 bar.SetTotal(200, false)
33 <-totalUpd2
34 // final total update
35 bar.SetTotal(300, true)
36 }()
37
38 for i := 0; i < 300; i++ {
39 if i == 140 {
40 close(totalUpd1)
41 }
42 if i == 250 {
43 close(totalUpd2)
44 }
45 time.Sleep(time.Duration(rand.Intn(10)+1) * time.Second / 100)
46 bar.Increment()
47 }
48
49 p.Stop()
50 }