1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465 |
- package progress
- import (
- "fmt"
- "io"
- "sync"
- "time"
- )
- type State interface {
- String() string
- }
- type Progress struct {
- mu sync.Mutex
- pos int
- w io.Writer
- ticker *time.Ticker
- states []State
- }
- func NewProgress(w io.Writer) *Progress {
- p := &Progress{pos: -1, w: w}
- go p.start()
- return p
- }
- func (p *Progress) Stop() {
- if p.ticker != nil {
- p.ticker.Stop()
- p.ticker = nil
- p.render()
- }
- }
- func (p *Progress) Add(key string, state State) {
- p.mu.Lock()
- defer p.mu.Unlock()
- p.states = append(p.states, state)
- }
- func (p *Progress) render() error {
- p.mu.Lock()
- defer p.mu.Unlock()
- fmt.Fprintf(p.w, "\033[%dA", p.pos)
- for _, state := range p.states {
- fmt.Fprintln(p.w, state.String())
- }
- if len(p.states) > 0 {
- p.pos = len(p.states)
- }
- return nil
- }
- func (p *Progress) start() {
- p.ticker = time.NewTicker(100 * time.Millisecond)
- for range p.ticker.C {
- p.render()
- }
- }
|