| 50 | 50 |
etaAlpha float64
|
| 51 | 51 |
total int64
|
| 52 | 52 |
current int64
|
|
53 |
dropRatio int64
|
| 53 | 54 |
trimLeftSpace bool
|
| 54 | 55 |
trimRightSpace bool
|
| 55 | 56 |
completed bool
|
| 56 | 57 |
aborted bool
|
|
58 |
dynamic bool
|
| 57 | 59 |
startTime time.Time
|
| 58 | 60 |
timeElapsed time.Duration
|
| 59 | 61 |
blockStartTime time.Time
|
| 60 | 62 |
timePerItem time.Duration
|
| 61 | 63 |
appendFuncs []decor.DecoratorFunc
|
| 62 | 64 |
prependFuncs []decor.DecoratorFunc
|
| 63 | |
simpleSpinner func() byte
|
| 64 | 65 |
refill *refill
|
| 65 | 66 |
bufP, bufB, bufA *bytes.Buffer
|
| 66 | 67 |
}
|
| 67 | 68 |
)
|
| 68 | 69 |
|
| 69 | 70 |
func newBar(ID int, total int64, wg *sync.WaitGroup, cancel <-chan struct{}, options ...BarOption) *Bar {
|
|
71 |
if total <= 0 {
|
|
72 |
total = time.Now().Unix()
|
|
73 |
}
|
|
74 |
|
| 70 | 75 |
s := state{
|
| 71 | |
id: ID,
|
| 72 | |
total: total,
|
| 73 | |
etaAlpha: etaAlpha,
|
| 74 | |
}
|
| 75 | |
|
| 76 | |
// if total <= 0 {
|
| 77 | |
// s.simpleSpinner = getSpinner()
|
| 78 | |
// }
|
|
76 |
id: ID,
|
|
77 |
total: total,
|
|
78 |
etaAlpha: etaAlpha,
|
|
79 |
dropRatio: 10,
|
|
80 |
}
|
| 79 | 81 |
|
| 80 | 82 |
for _, opt := range options {
|
| 81 | 83 |
opt(&s)
|
|
| 102 | 104 |
s.prependFuncs = nil
|
| 103 | 105 |
}:
|
| 104 | 106 |
case <-b.quit:
|
| 105 | |
return
|
| 106 | 107 |
}
|
| 107 | 108 |
}
|
| 108 | 109 |
|
|
| 113 | 114 |
s.appendFuncs = nil
|
| 114 | 115 |
}:
|
| 115 | 116 |
case <-b.quit:
|
| 116 | |
return
|
| 117 | 117 |
}
|
| 118 | 118 |
}
|
| 119 | 119 |
|
|
| 142 | 142 |
s.timeElapsed = time.Since(s.startTime)
|
| 143 | 143 |
s.updateTimePerItemEstimate(n)
|
| 144 | 144 |
if s.total > 0 && sum >= s.total {
|
| 145 | |
s.current = s.total
|
| 146 | |
s.completed = true
|
|
145 |
if s.dynamic {
|
|
146 |
sum -= sum * s.dropRatio / 100
|
|
147 |
} else {
|
|
148 |
s.current = s.total
|
|
149 |
s.completed = true
|
|
150 |
}
|
| 147 | 151 |
return
|
| 148 | 152 |
}
|
| 149 | 153 |
s.current = sum
|
| 150 | 154 |
s.blockStartTime = time.Now()
|
| 151 | 155 |
}:
|
| 152 | 156 |
case <-b.quit:
|
| 153 | |
return
|
| 154 | 157 |
}
|
| 155 | 158 |
}
|
| 156 | 159 |
|
|
| 165 | 168 |
s.refill = &refill{r, till}
|
| 166 | 169 |
}:
|
| 167 | 170 |
case <-b.quit:
|
| 168 | |
return
|
| 169 | 171 |
}
|
| 170 | 172 |
}
|
| 171 | 173 |
|
|
| 217 | 219 |
return <-result
|
| 218 | 220 |
case <-b.done:
|
| 219 | 221 |
return b.cacheState.total
|
|
222 |
}
|
|
223 |
}
|
|
224 |
|
|
225 |
// SetTotal sets total dynamically. The final param indicates the very last set,
|
|
226 |
// in other words you should set it to true when total is determined.
|
|
227 |
// Also you may consider providing your drop ratio via BarDropRatio BarOption func.
|
|
228 |
func (b *Bar) SetTotal(total int64, final bool) {
|
|
229 |
select {
|
|
230 |
case b.ops <- func(s *state) {
|
|
231 |
s.total = total
|
|
232 |
s.dynamic = !final
|
|
233 |
}:
|
|
234 |
case <-b.quit:
|
| 220 | 235 |
}
|
| 221 | 236 |
}
|
| 222 | 237 |
|
|
| 310 | 325 |
return ch
|
| 311 | 326 |
}
|
| 312 | 327 |
|
| 313 | |
func (s *state) updateFormat(format string) {
|
| 314 | |
for i, n := 0, 0; len(format) > 0; i++ {
|
| 315 | |
s.format[i], n = utf8.DecodeRuneInString(format)
|
| 316 | |
format = format[n:]
|
| 317 | |
}
|
| 318 | |
}
|
| 319 | |
|
| 320 | 328 |
func (s *state) updateTimePerItemEstimate(amount int) {
|
| 321 | 329 |
lastBlockTime := time.Since(s.blockStartTime) // shorthand for time.Now().Sub(t)
|
| 322 | 330 |
lastItemEstimate := float64(lastBlockTime) / float64(amount)
|
|
| 401 | 409 |
}
|
| 402 | 410 |
|
| 403 | 411 |
s.bufB.WriteRune(s.format[rRight])
|
| 404 | |
}
|
| 405 | |
|
| 406 | |
func concatenateBlocks(buf []byte, blocks ...[]byte) []byte {
|
| 407 | |
for _, block := range blocks {
|
| 408 | |
buf = append(buf, block...)
|
| 409 | |
}
|
| 410 | |
return buf
|
| 411 | 412 |
}
|
| 412 | 413 |
|
| 413 | 414 |
func newStatistics(s *state) *decor.Statistics {
|
|
| 423 | 424 |
}
|
| 424 | 425 |
}
|
| 425 | 426 |
|
| 426 | |
func getSpinner() func() byte {
|
| 427 | |
chars := []byte(`-\|/`)
|
| 428 | |
repeat := len(chars) - 1
|
| 429 | |
index := repeat
|
| 430 | |
return func() byte {
|
| 431 | |
if index == repeat {
|
| 432 | |
index = -1
|
| 433 | |
}
|
| 434 | |
index++
|
| 435 | |
return chars[index]
|
| 436 | |
}
|
| 437 | |
}
|
|
427 |
func concatenateBlocks(buf []byte, blocks ...[]byte) []byte {
|
|
428 |
for _, block := range blocks {
|
|
429 |
buf = append(buf, block...)
|
|
430 |
}
|
|
431 |
return buf
|
|
432 |
}
|
|
433 |
|
|
434 |
func (s *state) updateFormat(format string) {
|
|
435 |
for i, n := 0, 0; len(format) > 0; i++ {
|
|
436 |
s.format[i], n = utf8.DecodeRuneInString(format)
|
|
437 |
format = format[n:]
|
|
438 |
}
|
|
439 |
}
|