diff --git a/bar.go b/bar.go index 1fa6725..dd1d967 100644 --- a/bar.go +++ b/bar.go @@ -33,16 +33,16 @@ quit chan struct{} // done channel is receiveable after b.server has been quit done chan struct{} - ops chan func(*state) + ops chan func(*bState) // following are used after b.done is receiveable - cacheState state + cacheState bState once sync.Once } type ( - state struct { + bState struct { id int width int format fmtRunes @@ -80,7 +80,7 @@ total = time.Now().Unix() } - s := state{ + s := bState{ id: ID, total: total, etaAlpha: etaAlpha, @@ -98,7 +98,7 @@ b := &Bar{ quit: make(chan struct{}), done: make(chan struct{}), - ops: make(chan func(*state)), + ops: make(chan func(*bState)), } go b.server(s, wg, cancel) @@ -108,7 +108,7 @@ // RemoveAllPrependers removes all prepend functions func (b *Bar) RemoveAllPrependers() { select { - case b.ops <- func(s *state) { + case b.ops <- func(s *bState) { s.prependFuncs = nil }: case <-b.quit: @@ -118,7 +118,7 @@ // RemoveAllAppenders removes all append functions func (b *Bar) RemoveAllAppenders() { select { - case b.ops <- func(s *state) { + case b.ops <- func(s *bState) { s.appendFuncs = nil }: case <-b.quit: @@ -141,7 +141,7 @@ return } select { - case b.ops <- func(s *state) { + case b.ops <- func(s *bState) { next := time.Now() if s.current == 0 { s.startTime = next @@ -172,7 +172,7 @@ return } select { - case b.ops <- func(s *state) { + case b.ops <- func(s *bState) { s.refill = &refill{r, till} }: case <-b.quit: @@ -182,7 +182,7 @@ func (b *Bar) NumOfAppenders() int { result := make(chan int, 1) select { - case b.ops <- func(s *state) { result <- len(s.appendFuncs) }: + case b.ops <- func(s *bState) { result <- len(s.appendFuncs) }: return <-result case <-b.done: return len(b.cacheState.appendFuncs) @@ -192,7 +192,7 @@ func (b *Bar) NumOfPrependers() int { result := make(chan int, 1) select { - case b.ops <- func(s *state) { result <- len(s.prependFuncs) }: + case b.ops <- func(s *bState) { result <- len(s.prependFuncs) }: return <-result case <-b.done: return len(b.cacheState.prependFuncs) @@ -203,7 +203,7 @@ func (b *Bar) ID() int { result := make(chan int, 1) select { - case b.ops <- func(s *state) { result <- s.id }: + case b.ops <- func(s *bState) { result <- s.id }: return <-result case <-b.done: return b.cacheState.id @@ -213,7 +213,7 @@ func (b *Bar) Current() int64 { result := make(chan int64, 1) select { - case b.ops <- func(s *state) { result <- s.current }: + case b.ops <- func(s *bState) { result <- s.current }: return <-result case <-b.done: return b.cacheState.current @@ -223,7 +223,7 @@ func (b *Bar) Total() int64 { result := make(chan int64, 1) select { - case b.ops <- func(s *state) { result <- s.total }: + case b.ops <- func(s *bState) { result <- s.total }: return <-result case <-b.done: return b.cacheState.total @@ -235,7 +235,7 @@ // Also you may consider providing your drop ratio via BarDropRatio BarOption func. func (b *Bar) SetTotal(total int64, final bool) { select { - case b.ops <- func(s *state) { + case b.ops <- func(s *bState) { s.total = total s.dynamic = !final }: @@ -266,7 +266,7 @@ close(b.quit) } -func (b *Bar) server(s state, wg *sync.WaitGroup, cancel <-chan struct{}) { +func (b *Bar) server(s bState, wg *sync.WaitGroup, cancel <-chan struct{}) { defer func() { b.cacheState = s close(b.done) @@ -292,7 +292,7 @@ go func() { select { - case b.ops <- func(s *state) { + case b.ops <- func(s *bState) { defer func() { // recovering if external decorators panic if p := recover(); p != nil { @@ -324,14 +324,14 @@ return ch } -func (s *state) updateTimePerItemEstimate(amount int, now, next time.Time) { +func (s *bState) updateTimePerItemEstimate(amount int, now, next time.Time) { lastBlockTime := now.Sub(s.blockStartTime) lastItemEstimate := float64(lastBlockTime) / float64(amount) s.timePerItem = time.Duration((s.etaAlpha * lastItemEstimate) + (1-s.etaAlpha)*float64(s.timePerItem)) s.blockStartTime = next } -func (s *state) draw(termWidth int, prependWs, appendWs *widthSync) { +func (s *bState) draw(termWidth int, prependWs, appendWs *widthSync) { if termWidth <= 0 { termWidth = s.width } @@ -374,7 +374,7 @@ s.bufA.WriteByte('\n') } -func (s *state) fillBar(width int) { +func (s *bState) fillBar(width int) { s.bufB.Reset() s.bufB.WriteRune(s.format[rLeft]) if width <= 2 { @@ -415,7 +415,7 @@ s.bufB.WriteRune(s.format[rRight]) } -func newStatistics(s *state) *decor.Statistics { +func newStatistics(s *bState) *decor.Statistics { return &decor.Statistics{ ID: s.id, Completed: s.completed, @@ -428,7 +428,7 @@ } } -func (s *state) updateFormat(format string) { +func (s *bState) updateFormat(format string) { for i, n := 0, 0; len(format) > 0; i++ { s.format[i], n = utf8.DecodeRuneInString(format) format = format[n:] diff --git a/bar_option.go b/bar_option.go index b5b8eff..d21fc34 100644 --- a/bar_option.go +++ b/bar_option.go @@ -4,48 +4,48 @@ // BarOption is a function option which changes the default behavior of a bar, // if passed to p.AddBar(int64, ...BarOption) -type BarOption func(*state) +type BarOption func(*bState) // AppendDecorators let you inject decorators to the bar's right side func AppendDecorators(appenders ...decor.DecoratorFunc) BarOption { - return func(bs *state) { - bs.appendFuncs = append(bs.appendFuncs, appenders...) + return func(s *bState) { + s.appendFuncs = append(s.appendFuncs, appenders...) } } // PrependDecorators let you inject decorators to the bar's left side func PrependDecorators(prependers ...decor.DecoratorFunc) BarOption { - return func(bs *state) { - bs.prependFuncs = append(bs.prependFuncs, prependers...) + return func(s *bState) { + s.prependFuncs = append(s.prependFuncs, prependers...) } } // BarTrimLeft trims left side space of the bar func BarTrimLeft() BarOption { - return func(bs *state) { - bs.trimLeftSpace = true + return func(s *bState) { + s.trimLeftSpace = true } } // BarTrimRight trims right space of the bar func BarTrimRight() BarOption { - return func(bs *state) { - bs.trimRightSpace = true + return func(s *bState) { + s.trimRightSpace = true } } // BarTirm trims both left and right spaces of the bar func BarTrim() BarOption { - return func(bs *state) { - bs.trimLeftSpace = true - bs.trimRightSpace = true + return func(s *bState) { + s.trimLeftSpace = true + s.trimRightSpace = true } } // BarID overwrites internal bar id func BarID(id int) BarOption { - return func(bs *state) { - bs.id = id + return func(s *bState) { + s.id = id } } @@ -53,8 +53,8 @@ // You can play with it, if you're not satisfied with default behavior. // Default value is 0.25. func BarEtaAlpha(a float64) BarOption { - return func(bs *state) { - bs.etaAlpha = a + return func(s *bState) { + s.etaAlpha = a } } @@ -62,19 +62,19 @@ // If progress tip reaches total, but total is not final value yet, tip will be // dropped by specified ratio. func BarDropRatio(ratio int64) BarOption { - return func(bs *state) { - bs.dropRatio = ratio + return func(s *bState) { + s.dropRatio = ratio } } func barWidth(w int) BarOption { - return func(bs *state) { - bs.width = w + return func(s *bState) { + s.width = w } } func barFormat(format string) BarOption { - return func(bs *state) { - bs.updateFormat(format) + return func(s *bState) { + s.updateFormat(format) } } diff --git a/draw_test.go b/draw_test.go index 15d7c4f..7bd6967 100644 --- a/draw_test.go +++ b/draw_test.go @@ -117,8 +117,8 @@ } } -func newTestState() *state { - s := &state{ +func newTestState() *bState { + s := &bState{ trimLeftSpace: true, trimRightSpace: true, bufP: new(bytes.Buffer), diff --git a/options.go b/options.go index acaa941..0800657 100644 --- a/options.go +++ b/options.go @@ -12,75 +12,75 @@ // ProgressOption is a function option which changes the default behavior of // progress pool, if passed to mpb.New(...ProgressOption) -type ProgressOption func(*pConf) +type ProgressOption func(*pState) // WithWaitGroup provides means to have a single joint point. // If *sync.WaitGroup is provided, you can safely call just p.Stop() // without calling Wait() on provided *sync.WaitGroup. // Makes sense when there are more than one bar to render. func WithWaitGroup(wg *sync.WaitGroup) ProgressOption { - return func(c *pConf) { - c.ewg = wg + return func(s *pState) { + s.ewg = wg } } // WithWidth overrides default width 80 func WithWidth(w int) ProgressOption { - return func(c *pConf) { + return func(s *pState) { if w >= 0 { - c.width = w + s.width = w } } } // WithFormat overrides default bar format "[=>-]" func WithFormat(format string) ProgressOption { - return func(c *pConf) { + return func(s *pState) { if utf8.RuneCountInString(format) == formatLen { - c.format = format + s.format = format } } } // WithRefreshRate overrides default 100ms refresh rate func WithRefreshRate(d time.Duration) ProgressOption { - return func(c *pConf) { - c.ticker.Stop() - c.ticker = time.NewTicker(d) - c.rr = d + return func(s *pState) { + s.ticker.Stop() + s.ticker = time.NewTicker(d) + s.rr = d } } // WithBeforeRenderFunc provided BeforeRender func, // will be called before each render cycle. func WithBeforeRenderFunc(f BeforeRender) ProgressOption { - return func(c *pConf) { - c.beforeRender = f + return func(s *pState) { + s.beforeRender = f } } // WithCancel provide your cancel channel, // which you plan to close at some point. func WithCancel(ch <-chan struct{}) ProgressOption { - return func(c *pConf) { - c.cancel = ch + return func(s *pState) { + s.cancel = ch } } // WithShutdownNotifier provided chanel will be closed, inside p.Stop() call func WithShutdownNotifier(ch chan struct{}) ProgressOption { - return func(c *pConf) { - c.shutdownNotifier = ch + return func(s *pState) { + s.shutdownNotifier = ch } } // Output overrides default output os.Stdout func Output(w io.Writer) ProgressOption { - return func(c *pConf) { + return func(s *pState) { if w == nil { w = ioutil.Discard } - c.cw = cwriter.New(w) + s.cw = cwriter.New(w) } } @@ -88,7 +88,7 @@ // writer. Could be useful if you want to output something below the bars, while // they're rendering. func OutputInterceptors(interseptors ...func(io.Writer)) ProgressOption { - return func(c *pConf) { - c.interceptors = interseptors + return func(s *pState) { + s.interceptors = interseptors } } diff --git a/options_go1.7.go b/options_go1.7.go index a3cddab..5ebf37b 100644 --- a/options_go1.7.go +++ b/options_go1.7.go @@ -5,9 +5,9 @@ import "context" func WithContext(ctx context.Context) ProgressOption { - return func(c *pConf) { + return func(s *pState) { if ctx != nil { - c.cancel = ctx.Done() + s.cancel = ctx.Done() } } } diff --git a/progress.go b/progress.go index 771bb92..52261c5 100644 --- a/progress.go +++ b/progress.go @@ -18,8 +18,8 @@ Result []chan int } - // progress config, fields are adjustable by user indirectly - pConf struct { + // progress state, which may contain several bars + pState struct { bars []*Bar idCounter int @@ -57,14 +57,14 @@ quit chan struct{} // done channel is receiveable after p.server has been quit done chan struct{} - ops chan func(*pConf) + ops chan func(*pState) } // New creates new Progress instance, which orchestrates bars rendering process. // Accepts mpb.ProgressOption funcs for customization. func New(options ...ProgressOption) *Progress { // defaults - conf := pConf{ + conf := pState{ bars: make([]*Bar, 0, 3), width: pwidth, format: pformat, @@ -82,7 +82,7 @@ ewg: conf.ewg, wg: new(sync.WaitGroup), done: make(chan struct{}), - ops: make(chan func(*pConf)), + ops: make(chan func(*pState)), quit: make(chan struct{}), } go p.server(conf) @@ -94,7 +94,7 @@ p.wg.Add(1) result := make(chan *Bar, 1) select { - case p.ops <- func(c *pConf) { + case p.ops <- func(c *pState) { options = append(options, barWidth(c.width), barFormat(c.format)) b := newBar(c.idCounter, total, p.wg, c.cancel, options...) c.bars = append(c.bars, b) @@ -111,7 +111,7 @@ func (p *Progress) RemoveBar(b *Bar) bool { result := make(chan bool, 1) select { - case p.ops <- func(c *pConf) { + case p.ops <- func(c *pState) { var ok bool for i, bar := range c.bars { if bar == b { @@ -133,7 +133,7 @@ func (p *Progress) BarCount() int { result := make(chan int, 1) select { - case p.ops <- func(c *pConf) { + case p.ops <- func(c *pState) { result <- len(c.bars) }: return <-result @@ -208,43 +208,43 @@ return ws } -func (p *pConf) writeAndFlush(tw, numP, numA int) (err error) { +func (s *pState) writeAndFlush(tw, numP, numA int) (err error) { if numP < 0 && numA < 0 { return } - if p.beforeRender != nil { - p.beforeRender(p.bars) + if s.beforeRender != nil { + s.beforeRender(s.bars) } wSyncTimeout := make(chan struct{}) - time.AfterFunc(p.rr, func() { + time.AfterFunc(s.rr, func() { close(wSyncTimeout) }) - prependWs := newWidthSync(wSyncTimeout, len(p.bars), numP) - appendWs := newWidthSync(wSyncTimeout, len(p.bars), numA) - - sequence := make([]<-chan *bufReader, len(p.bars)) - for i, b := range p.bars { + prependWs := newWidthSync(wSyncTimeout, len(s.bars), numP) + appendWs := newWidthSync(wSyncTimeout, len(s.bars), numA) + + sequence := make([]<-chan *bufReader, len(s.bars)) + for i, b := range s.bars { sequence[i] = b.render(tw, prependWs, appendWs) } var i int for r := range fanIn(sequence...) { - _, err = p.cw.ReadFrom(r) + _, err = s.cw.ReadFrom(r) defer func(bar *Bar, complete bool) { if complete { bar.Complete() } - }(p.bars[i], r.complete) + }(s.bars[i], r.complete) i++ } - for _, interceptor := range p.interceptors { - interceptor(p.cw) - } - - if e := p.cw.Flush(); err == nil { + for _, interceptor := range s.interceptors { + interceptor(s.cw) + } + + if e := s.cw.Flush(); err == nil { err = e } return diff --git a/progress_posix.go b/progress_posix.go index cf75333..5012535 100644 --- a/progress_posix.go +++ b/progress_posix.go @@ -13,13 +13,13 @@ "github.com/vbauerster/mpb/cwriter" ) -func (p *Progress) server(conf pConf) { +func (p *Progress) server(s pState) { winch := make(chan os.Signal, 1) signal.Notify(winch, syscall.SIGWINCH) defer func() { - if conf.shutdownNotifier != nil { - close(conf.shutdownNotifier) + if s.shutdownNotifier != nil { + close(s.shutdownNotifier) } signal.Stop(winch) close(p.done) @@ -34,13 +34,13 @@ for { select { case op := <-p.ops: - op(&conf) - case <-conf.ticker.C: - if len(conf.bars) == 0 { + op(&s) + case <-s.ticker.C: + if len(s.bars) == 0 { runtime.Gosched() break } - b0 := conf.bars[0] + b0 := s.bars[0] if numP == -1 { numP = b0.NumOfPrependers() } @@ -48,31 +48,31 @@ numA = b0.NumOfAppenders() } tw, _, _ := cwriter.TermSize() - err := conf.writeAndFlush(tw, numP, numA) + err := s.writeAndFlush(tw, numP, numA) if err != nil { fmt.Fprintln(os.Stderr, err) } case <-winch: tw, _, _ := cwriter.TermSize() - err := conf.writeAndFlush(tw-tw/8, numP, numA) + err := s.writeAndFlush(tw-tw/8, numP, numA) if err != nil { fmt.Fprintln(os.Stderr, err) } if timer != nil && timer.Reset(resumeDelay) { break } - conf.ticker.Stop() + s.ticker.Stop() timer = time.NewTimer(resumeDelay) resumeTicker = timer.C case <-resumeTicker: - conf.ticker = time.NewTicker(conf.rr) + s.ticker = time.NewTicker(s.rr) resumeTicker = nil - case <-conf.cancel: - conf.ticker.Stop() - conf.cancel = nil + case <-s.cancel: + s.ticker.Stop() + s.cancel = nil case <-p.quit: - if conf.cancel != nil { - conf.ticker.Stop() + if s.cancel != nil { + s.ticker.Stop() } return } diff --git a/progress_windows.go b/progress_windows.go index 98f79bc..ddbe8b1 100644 --- a/progress_windows.go +++ b/progress_windows.go @@ -10,10 +10,10 @@ "github.com/vbauerster/mpb/cwriter" ) -func (p *Progress) server(conf pConf) { +func (p *Progress) server(s pState) { defer func() { - if conf.shutdownNotifier != nil { - close(conf.shutdownNotifier) + if s.shutdownNotifier != nil { + close(s.shutdownNotifier) } close(p.done) }() @@ -23,13 +23,13 @@ for { select { case op := <-p.ops: - op(&conf) - case <-conf.ticker.C: - if len(conf.bars) == 0 { + op(&s) + case <-s.ticker.C: + if len(s.bars) == 0 { runtime.Gosched() break } - b0 := conf.bars[0] + b0 := s.bars[0] if numP == -1 { numP = b0.NumOfPrependers() } @@ -37,16 +37,16 @@ numA = b0.NumOfAppenders() } tw, _, _ := cwriter.TermSize() - err := conf.writeAndFlush(tw, numP, numA) + err := s.writeAndFlush(tw, numP, numA) if err != nil { fmt.Fprintln(os.Stderr, err) } - case <-conf.cancel: - conf.ticker.Stop() - conf.cancel = nil + case <-s.cancel: + s.ticker.Stop() + s.cancel = nil case <-p.quit: - if conf.cancel != nil { - conf.ticker.Stop() + if s.cancel != nil { + s.ticker.Stop() } return }