Codebase list golang-github-vbauerster-mpb / 7e13cb5
refactoring: BarFiller Vladimir Bauer 6 years ago
5 changed file(s) with 115 addition(s) and 94 deletion(s). Raw diff Collapse all Expand all
1010 "time"
1111 "unicode/utf8"
1212
13 "github.com/vbauerster/mpb/v4/decor"
13 "github.com/vbauerster/mpb/v5/decor"
1414 )
1515
16 // Filler interface.
17 // Bar renders by calling Filler's Fill method. You can literally have
18 // any bar kind, by implementing this interface and passing it to the
19 // *Progress.Add method.
20 type Filler interface {
16 // BarFiller interface.
17 // Bar renders itself by calling BarFiller's Fill method. You can
18 // literally have any bar kind, by implementing this interface and
19 // passing it to the *Progress.Add method.
20 type BarFiller interface {
2121 Fill(w io.Writer, width int, stat *decor.Statistics)
2222 }
2323
24 // FillerFunc is function type adapter to convert function into Filler.
25 type FillerFunc func(w io.Writer, width int, stat *decor.Statistics)
26
27 func (f FillerFunc) Fill(w io.Writer, width int, stat *decor.Statistics) {
24 // BarFillerFunc is function type adapter to convert function into Filler.
25 type BarFillerFunc func(w io.Writer, width int, stat *decor.Statistics)
26
27 func (f BarFillerFunc) Fill(w io.Writer, width int, stat *decor.Statistics) {
2828 f(w, width, stat)
29 }
30
31 // WrapFiller interface.
32 // If you're implementing custom Filler by wrapping a built-in one,
33 // it is necessary to implement this interface to retain functionality
34 // of built-in Filler.
35 type WrapFiller interface {
36 Base() Filler
3729 }
3830
3931 // Bar represents a progress Bar.
6557 type extFunc func(in io.Reader, tw int, st *decor.Statistics) (out io.Reader, lines int)
6658
6759 type bState struct {
68 baseF Filler
69 filler Filler
60 baseF BarFiller
61 filler BarFiller
7062 id int
7163 width int
7264 total int64
7365 current int64
66 lastN int64
67 iterated bool
7468 trimSpace bool
7569 toComplete bool
7670 completeFlushed bool
7771 noPop bool
7872 aDecorators []decor.Decorator
7973 pDecorators []decor.Decorator
80 amountReceivers []decor.AmountReceiver
74 averageDecorators []decor.AverageDecorator
75 ewmaDecorators []decor.EwmaDecorator
8176 shutdownListeners []decor.ShutdownListener
82 averageAdjusters []decor.AverageAdjuster
8377 bufP, bufB, bufA *bytes.Buffer
8478 extender extFunc
8579
182176 }
183177 }
184178
185 // AdjustAverageDecorators updates start time of all average decorators.
186 // Useful for resume-able tasks.
187 func (b *Bar) AdjustAverageDecorators(startTime time.Time) {
188 b.operateState <- func(s *bState) {
189 for _, adjuster := range s.averageAdjusters {
190 adjuster.AverageAdjust(startTime)
191 }
192 }
193 }
194
195179 // TraverseDecorators traverses all available decorators and calls cb func on each.
196 func (b *Bar) TraverseDecorators(cb decor.CBFunc) {
180 func (b *Bar) TraverseDecorators(cb func(decor.Decorator)) {
197181 b.operateState <- func(s *bState) {
198182 for _, decorators := range [...][]decor.Decorator{
199183 s.pDecorators,
207191 }
208192
209193 // SetTotal sets total dynamically.
210 // Set complete to true, to trigger bar complete event now.
194 // If total is less or equal to zero it takes progress' current value.
195 // If complete is true, complete event will be triggered.
211196 func (b *Bar) SetTotal(total int64, complete bool) {
212197 select {
213198 case b.operateState <- func(s *bState) {
226211 }
227212 }
228213
229 // SetCurrent sets progress' current to arbitrary amount.
230 func (b *Bar) SetCurrent(current int64, wdd ...time.Duration) {
231 select {
232 case b.operateState <- func(s *bState) {
233 for _, ar := range s.amountReceivers {
234 ar.NextAmount(current-s.current, wdd...)
235 }
214 // SetCurrent sets progress' current to an arbitrary value.
215 func (b *Bar) SetCurrent(current int64) {
216 select {
217 case b.operateState <- func(s *bState) {
218 s.iterated = true
219 s.lastN = current - s.current
236220 s.current = current
237221 if s.total > 0 && s.current >= s.total {
238222 s.current = s.total
244228 }
245229 }
246230
247 // Increment is a shorthand for b.IncrInt64(1, wdd...).
248 func (b *Bar) Increment(wdd ...time.Duration) {
249 b.IncrInt64(1, wdd...)
250 }
251
252 // IncrBy is a shorthand for b.IncrInt64(int64(n), wdd...).
253 func (b *Bar) IncrBy(n int, wdd ...time.Duration) {
254 b.IncrInt64(int64(n), wdd...)
255 }
256
257 // IncrInt64 increments progress bar by amount of n. wdd is an optional
258 // work duration i.e. time.Since(start), which expected to be passed,
259 // if any ewma based decorator is used.
260 func (b *Bar) IncrInt64(n int64, wdd ...time.Duration) {
261 select {
262 case b.operateState <- func(s *bState) {
263 for _, ar := range s.amountReceivers {
264 ar.NextAmount(n, wdd...)
265 }
231 // Increment is a shorthand for b.IncrInt64(1).
232 func (b *Bar) Increment() {
233 b.IncrInt64(1)
234 }
235
236 // IncrBy is a shorthand for b.IncrInt64(int64(n)).
237 func (b *Bar) IncrBy(n int) {
238 b.IncrInt64(int64(n))
239 }
240
241 // IncrInt64 increments progress by amount of n.
242 func (b *Bar) IncrInt64(n int64) {
243 select {
244 case b.operateState <- func(s *bState) {
245 s.iterated = true
246 s.lastN = n
266247 s.current += n
267248 if s.total > 0 && s.current >= s.total {
268249 s.current = s.total
269250 s.toComplete = true
270251 go b.refreshTillShutdown()
252 }
253 }:
254 case <-b.done:
255 }
256 }
257
258 // DecoratorEwmaUpdate updates all EWMA based decorators. Should be
259 // called on each iteration, because EWMA's unit of measure is an
260 // iteration's taken time. Panics if called before *Bar.Incr... family
261 // methods.
262 func (b *Bar) DecoratorEwmaUpdate(dur time.Duration) {
263 select {
264 case b.operateState <- func(s *bState) {
265 ewmaIterationUpdate(false, s, dur)
266 }:
267 case <-b.done:
268 ewmaIterationUpdate(true, b.cacheState, dur)
269 }
270 }
271
272 // DecoratorAverageAdjust adjusts all average based decorators. Call
273 // if you need to adjust start time of all average based decorators
274 // or after progress resume.
275 func (b *Bar) DecoratorAverageAdjust(start time.Time) {
276 select {
277 case b.operateState <- func(s *bState) {
278 for _, d := range s.averageDecorators {
279 d.AverageAdjust(start)
271280 }
272281 }:
273282 case <-b.done:
367376 }
368377
369378 func (b *Bar) subscribeDecorators() {
370 var amountReceivers []decor.AmountReceiver
379 var averageDecorators []decor.AverageDecorator
380 var ewmaDecorators []decor.EwmaDecorator
371381 var shutdownListeners []decor.ShutdownListener
372 var averageAdjusters []decor.AverageAdjuster
373382 b.TraverseDecorators(func(d decor.Decorator) {
374 if d, ok := d.(decor.AmountReceiver); ok {
375 amountReceivers = append(amountReceivers, d)
383 if d, ok := d.(decor.AverageDecorator); ok {
384 averageDecorators = append(averageDecorators, d)
385 }
386 if d, ok := d.(decor.EwmaDecorator); ok {
387 ewmaDecorators = append(ewmaDecorators, d)
376388 }
377389 if d, ok := d.(decor.ShutdownListener); ok {
378390 shutdownListeners = append(shutdownListeners, d)
379391 }
380 if d, ok := d.(decor.AverageAdjuster); ok {
381 averageAdjusters = append(averageAdjusters, d)
382 }
383392 })
384393 b.operateState <- func(s *bState) {
385 s.amountReceivers = amountReceivers
394 s.averageDecorators = averageDecorators
395 s.ewmaDecorators = ewmaDecorators
386396 s.shutdownListeners = shutdownListeners
387 s.averageAdjusters = averageAdjusters
388397 }
389398 }
390399
474483 }
475484 return d
476485 }
486
487 func ewmaIterationUpdate(done bool, s *bState, dur time.Duration) {
488 if !done && !s.iterated {
489 panic("increment required before ewma iteration update")
490 } else {
491 s.iterated = false
492 }
493 for _, d := range s.ewmaDecorators {
494 d.EwmaUpdate(s.lastN, dur)
495 }
496 }
33 "io"
44 "unicode/utf8"
55
6 "github.com/vbauerster/mpb/v4/decor"
7 "github.com/vbauerster/mpb/v4/internal"
6 "github.com/vbauerster/mpb/v5/decor"
7 "github.com/vbauerster/mpb/v5/internal"
88 )
99
1010 const (
4444 }
4545
4646 // NewBarFiller constucts mpb.Filler, to be used with *Progress.Add method.
47 func NewBarFiller(style string, reverse bool) Filler {
47 func NewBarFiller(style string, reverse bool) BarFiller {
4848 if style == "" {
4949 style = DefaultBarStyle
5050 }
8383 Base() Decorator
8484 }
8585
86 // AmountReceiver interface.
87 // EWMA based decorators need to implement this one.
88 type AmountReceiver interface {
89 NextAmount(int64, ...time.Duration)
86 // EwmaDecorator interface.
87 // EWMA based decorators must to implement this one.
88 type EwmaDecorator interface {
89 IterationUpdate(int64, time.Duration)
90 }
91
92 // AverageDecorator interface.
93 // Average decorators should implement this interface to provide start
94 // time adjustment facility, for resume-able tasks.
95 type AverageDecorator interface {
96 Adjust(time.Time)
9097 }
9198
9299 // ShutdownListener interface.
96103 Shutdown()
97104 }
98105
99 // AverageAdjuster interface.
100 // Average decorators should implement this interface to provide start
101 // time adjustment facility, for resume-able tasks.
102 type AverageAdjuster interface {
103 AverageAdjust(time.Time)
104 }
105
106 // CBFunc convenience call back func type.
107 type CBFunc func(Decorator)
108
109106 // Global convenience instances of WC with sync width bit set.
107 // To be used with multiple bars only, i.e. not effective for single bar usage.
110108 var (
111109 WCSyncWidth = WC{C: DSyncWidth}
112110 WCSyncWidthR = WC{C: DSyncWidthR}
1111 "sync"
1212 "time"
1313
14 "github.com/vbauerster/mpb/v4/cwriter"
15 "github.com/vbauerster/mpb/v4/decor"
14 "github.com/vbauerster/mpb/v5/cwriter"
15 "github.com/vbauerster/mpb/v5/decor"
1616 )
1717
1818 const (
110110 // Add creates a bar which renders itself by provided filler.
111111 // Set total to 0, if you plan to update it later.
112112 // Panics if *Progress instance is done, i.e. called after *Progress.Wait().
113 func (p *Progress) Add(total int64, filler Filler, options ...BarOption) *Bar {
113 func (p *Progress) Add(total int64, filler BarFiller, options ...BarOption) *Bar {
114114 if filler == nil {
115115 filler = NewBarFiller(DefaultBarStyle, false)
116116 }
339339 }
340340 }
341341
342 func (s *pState) makeBarState(total int64, filler Filler, options ...BarOption) *bState {
342 func (s *pState) makeBarState(total int64, filler BarFiller, options ...BarOption) *bState {
343343 bs := &bState{
344344 total: total,
345345 baseF: extractBaseFiller(filler),
387387 }
388388 }
389389
390 func extractBaseFiller(f Filler) Filler {
391 if f, ok := f.(WrapFiller); ok {
390 func extractBaseFiller(f BarFiller) BarFiller {
391 type wrapper interface {
392 Base() BarFiller
393 }
394 if f, ok := f.(wrapper); ok {
392395 return extractBaseFiller(f.Base())
393396 }
394397 return f
44 "strings"
55 "unicode/utf8"
66
7 "github.com/vbauerster/mpb/v4/decor"
7 "github.com/vbauerster/mpb/v5/decor"
88 )
99
1010 // SpinnerAlignment enum.
2727 }
2828
2929 // NewSpinnerFiller constucts mpb.Filler, to be used with *Progress.Add method.
30 func NewSpinnerFiller(style []string, alignment SpinnerAlignment) Filler {
30 func NewSpinnerFiller(style []string, alignment SpinnerAlignment) BarFiller {
3131 if len(style) == 0 {
3232 style = DefaultSpinnerStyle
3333 }