package uiprogress
import (
"fmt"
"io"
"os"
"time"
"github.com/gosuri/uilive"
)
// Out is the default writer to render progress bars to
var Out = os.Stdout
// RefreshInterval in the default time duration to wait for refreshing the output
var RefreshInterval = time.Millisecond * 10
// Progress represents the container that renders progress bars
type Progress struct {
// Out is the writer to render progress bars to
Out io.Writer
// Width is the width of the progress bars
Width int
// Bars is the collection of progress bars
// Bars []*Bar
// RefreshInterval in the time duration to wait for refreshing the output
RefreshInterval time.Duration
lw *uilive.Writer
stopChan chan struct{}
// mtx *sync.RWMutex
bars chan Bar
ticker *time.Ticker
}
// New returns a new progress bar with defaults
func New() *Progress {
return &Progress{
Width: Width,
Out: Out,
RefreshInterval: RefreshInterval,
lw: uilive.New(),
stopChan: make(chan struct{}),
bars: make(chan Bar),
}
}
// Listen listens for updates and renders the progress bars
func (p *Progress) Listen() {
bars := make([]Bar, 0)
p.lw.Out = p.Out
loop:
for {
select {
case <-p.stopChan: // interrupt
return
case bar, ok := <-p.bars:
if !ok {
break loop
}
bars = append(bars, bar)
default:
time.Sleep(p.RefreshInterval)
p.mtx.RLock()
for _, bar := range p.Bars {
fmt.Fprintln(p.lw, bar.String())
}
p.lw.Flush()
p.mtx.RUnlock()
}
}
}