Codebase list golang-github-vbauerster-mpb / 7370f9d
spinner decorator and example Vladimir Bauer 7 years ago
2 changed file(s) with 96 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 package main
1
2 import (
3 "fmt"
4 "math/rand"
5 "sync"
6 "time"
7
8 "github.com/vbauerster/mpb/v4"
9 "github.com/vbauerster/mpb/v4/decor"
10 )
11
12 func init() {
13 rand.Seed(time.Now().UnixNano())
14 }
15
16 func main() {
17 var wg sync.WaitGroup
18 // pass &wg (optional), so p will wait for it eventually
19 p := mpb.New(mpb.WithWaitGroup(&wg), mpb.WithWidth(64))
20 total, numBars := 100, 3
21 wg.Add(numBars)
22
23 for i := 0; i < numBars; i++ {
24 name := fmt.Sprintf("Bar#%d:", i)
25 bar := p.AddBar(int64(total),
26 mpb.PrependDecorators(
27 // simple name decorator
28 decor.Name(name),
29 decor.OnComplete(
30 // spinner decorator with default style
31 decor.Spinner(nil, decor.WCSyncSpace), "done",
32 ),
33 ),
34 mpb.AppendDecorators(
35 // decor.DSyncWidth bit enables column width synchronization
36 decor.Percentage(decor.WCSyncWidth),
37 ),
38 )
39 // simulating some work
40 go func() {
41 defer wg.Done()
42 max := 100 * time.Millisecond
43 for i := 0; i < total; i++ {
44 start := time.Now()
45 time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10)
46 // ewma based decorators require work duration measurement
47 bar.IncrBy(1, time.Since(start))
48 }
49 }()
50 }
51 // Waiting for passed &wg and for all bars to complete and flush
52 p.Wait()
53 }
0 package decor
1
2 var defaultSpinnerStyle = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
3
4 // Spinner returns spinner decorator.
5 //
6 // `frames` spinner frames, if nil or len==0, default is used
7 //
8 // `wcc` optional WC config
9 func Spinner(frames []string, wcc ...WC) Decorator {
10 var wc WC
11 for _, widthConf := range wcc {
12 wc = widthConf
13 }
14 wc.Init()
15 if len(frames) == 0 {
16 frames = defaultSpinnerStyle
17 }
18 d := &spinnerDecorator{
19 WC: wc,
20 frames: frames,
21 }
22 return d
23 }
24
25 type spinnerDecorator struct {
26 WC
27 frames []string
28 complete *string
29 }
30
31 func (d *spinnerDecorator) Decor(st *Statistics) string {
32 if st.Completed && d.complete != nil {
33 return d.FormatMsg(*d.complete)
34 }
35 frame := d.frames[st.Current%int64(len(d.frames))]
36 return d.FormatMsg(frame)
37 }
38
39 func (d *spinnerDecorator) OnCompleteMessage(msg string) {
40 d.complete = &msg
41 }