Skip to content

Commit 5ad50c6

Browse files
committed
feat: make progressbar could update according to an interval or update each time render was called.
1 parent d773ff3 commit 5ad50c6

File tree

1 file changed

+60
-11
lines changed

1 file changed

+60
-11
lines changed

progressbar.go

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ type state struct {
5050
counterTime time.Time
5151
counterNumSinceLast int64
5252
counterLastTenRates []float64
53+
spinnerIdx int // the index of spinner
5354

5455
maxLineWidth int
5556
currentBytes float64
@@ -105,6 +106,11 @@ type config struct {
105106
// spinnerTypeOptionUsed remembers if the spinnerType was changed manually
106107
spinnerTypeOptionUsed bool
107108

109+
// spinnerChangeInterval the change interval of spinner
110+
// if set this attribute to 0, the spinner only change when renderProgressBar was called
111+
// for example, each time when Add() was called,which will call renderProgressBar function
112+
spinnerChangeInterval time.Duration
113+
108114
// spinner represents the spinner as a slice of string
109115
spinner []string
110116

@@ -151,6 +157,18 @@ func OptionSetWidth(s int) Option {
151157
}
152158
}
153159

160+
// OptionSetSpinnerChangeInterval sets the spinner change interval
161+
// the spinner will change according to this value.
162+
// By default, this value is 100 * time.Millisecond
163+
// If you don't want to let this progressbar update by specified time interval
164+
// you can set this value to zero, then the spinner will change each time rendered,
165+
// such as when Add() or Describe() was called
166+
func OptionSetSpinnerChangeInterval(interval time.Duration) Option {
167+
return func(p *ProgressBar) {
168+
p.config.spinnerChangeInterval = interval
169+
}
170+
}
171+
154172
// OptionSpinnerType sets the type of spinner used for indeterminate bars
155173
func OptionSpinnerType(spinnerType int) Option {
156174
return func(p *ProgressBar) {
@@ -337,16 +355,17 @@ func NewOptions64(max int64, options ...Option) *ProgressBar {
337355
counterTime: time.Time{},
338356
},
339357
config: config{
340-
writer: os.Stdout,
341-
theme: defaultTheme,
342-
iterationString: "it",
343-
width: 40,
344-
max: max,
345-
throttleDuration: 0 * time.Nanosecond,
346-
elapsedTime: max == -1,
347-
predictTime: true,
348-
spinnerType: 9,
349-
invisible: false,
358+
writer: os.Stdout,
359+
theme: defaultTheme,
360+
iterationString: "it",
361+
width: 40,
362+
max: max,
363+
throttleDuration: 0 * time.Nanosecond,
364+
elapsedTime: max == -1,
365+
predictTime: true,
366+
spinnerType: 9,
367+
invisible: false,
368+
spinnerChangeInterval: 100 * time.Millisecond,
350369
},
351370
}
352371

@@ -374,6 +393,27 @@ func NewOptions64(max int64, options ...Option) *ProgressBar {
374393
b.RenderBlank()
375394
}
376395

396+
// if the render time interval attribute is set
397+
if b.config.spinnerChangeInterval != 0 {
398+
go func() {
399+
ticker := time.NewTicker(b.config.spinnerChangeInterval)
400+
defer ticker.Stop()
401+
for {
402+
select {
403+
case <-ticker.C:
404+
if b.IsFinished() {
405+
return
406+
}
407+
if b.IsStarted() {
408+
b.lock.Lock()
409+
b.render()
410+
b.lock.Unlock()
411+
}
412+
}
413+
}
414+
}()
415+
}
416+
377417
return &b
378418
}
379419

@@ -1058,7 +1098,16 @@ func renderProgressBar(c config, s *state) (int, error) {
10581098
if len(c.spinner) > 0 {
10591099
selectedSpinner = c.spinner
10601100
}
1061-
spinner := selectedSpinner[int(math.Round(math.Mod(float64(time.Since(s.startTime).Milliseconds()/100), float64(len(selectedSpinner)))))]
1101+
1102+
var spinner string
1103+
if c.spinnerChangeInterval != 0 {
1104+
// if the spinner is changed according to an interval, calculate it
1105+
spinner = selectedSpinner[int(math.Round(math.Mod(float64(time.Since(s.startTime).Nanoseconds()/c.spinnerChangeInterval.Nanoseconds()), float64(len(selectedSpinner)))))]
1106+
} else {
1107+
// if the spinner is changed according to the number render was called
1108+
spinner = selectedSpinner[s.spinnerIdx]
1109+
s.spinnerIdx = (s.spinnerIdx + 1) % len(selectedSpinner)
1110+
}
10621111
if c.elapsedTime {
10631112
if c.showDescriptionAtLineEnd {
10641113
str = fmt.Sprintf("\r%s %s [%s] %s ",

0 commit comments

Comments
 (0)