diff --git a/_examples/barExtenderRev/go.mod b/_examples/barExtenderRev/go.mod new file mode 100644 index 0000000..ab870af --- /dev/null +++ b/_examples/barExtenderRev/go.mod @@ -0,0 +1,5 @@ +module github.com/vbauerster/mpb/_examples/barExtenderRev + +go 1.14 + +require github.com/vbauerster/mpb/v7 v7.5.0 diff --git a/_examples/barExtenderRev/main.go b/_examples/barExtenderRev/main.go new file mode 100644 index 0000000..b37e9c5 --- /dev/null +++ b/_examples/barExtenderRev/main.go @@ -0,0 +1,132 @@ +package main + +import ( + "fmt" + "io" + "math/rand" + "sync/atomic" + "time" + + "github.com/vbauerster/mpb/v7" + "github.com/vbauerster/mpb/v7/decor" +) + +var curTask uint32 +var doneTasks uint32 + +type task struct { + id int + total int + bar *mpb.Bar +} + +func main() { + numTasks := 4 + + var total int + var filler mpb.BarFiller + tasks := make([]*task, numTasks) + + for i := 0; i < numTasks; i++ { + task := &task{ + id: i, + total: rand.Intn(101) + 100, + } + total += task.total + filler = middleware(filler, task.id) + tasks[i] = task + } + + filler = newLineMiddleware(filler) + + p := mpb.New() + + for i := 0; i < numTasks; i++ { + var waitBar *mpb.Bar + if i != 0 { + waitBar = tasks[i-1].bar + } + total := tasks[i].total + bar := p.AddBar(int64(total), + mpb.BarExtenderRev(filler), + mpb.BarQueueAfter(waitBar, false), + mpb.PrependDecorators( + decor.Name("current:", decor.WCSyncWidthR), + ), + mpb.AppendDecorators( + decor.Percentage(decor.WCSyncWidth), + ), + ) + tasks[i].bar = bar + } + + tb := p.AddBar(int64(total), + mpb.PrependDecorators( + decor.Any(func(st decor.Statistics) string { + var done uint32 + if st.Completed { + done = uint32(len(tasks)) + } else { + done = atomic.LoadUint32(&doneTasks) + } + return fmt.Sprintf("TOTAL(%d/%d)", done, len(tasks)) + }, decor.WCSyncWidthR), + ), + mpb.AppendDecorators( + decor.Percentage(decor.WCSyncWidth), + ), + ) + + for _, t := range tasks { + atomic.StoreUint32(&curTask, uint32(t.id)) + complete(tb, t) + atomic.AddUint32(&doneTasks, 1) + } + + p.Wait() +} + +func middleware(base mpb.BarFiller, id int) mpb.BarFiller { + var done bool + fn := func(w io.Writer, _ int, st decor.Statistics) { + if !done { + cur := atomic.LoadUint32(&curTask) == uint32(id) + if !st.Completed && cur { + fmt.Fprintf(w, "=> Taksk %02d\n", id) + return + } else if !cur { + fmt.Fprintf(w, " Taksk %02d\n", id) + return + } else { + done = cur + } + } + fmt.Fprintf(w, " Taksk %02d: Done!\n", id) + } + if id == 0 { + return mpb.BarFillerFunc(fn) + } + return mpb.BarFillerFunc(func(w io.Writer, reqWidth int, st decor.Statistics) { + fn(w, reqWidth, st) + base.Fill(w, reqWidth, st) + }) +} + +func newLineMiddleware(base mpb.BarFiller) mpb.BarFiller { + return mpb.BarFillerFunc(func(w io.Writer, reqWidth int, st decor.Statistics) { + fmt.Fprintln(w) + base.Fill(w, reqWidth, st) + }) +} + +func complete(tb *mpb.Bar, t *task) { + bar := t.bar + max := 100 * time.Millisecond + for !bar.Completed() { + n := rand.Int63n(10) + 1 + bar.IncrInt64(n) + tb.IncrInt64(n) + time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10) + } + bar.Wait() +}