diff --git a/bar.go b/bar.go index 134c3cb..3ff91c0 100644 --- a/bar.go +++ b/bar.go @@ -155,6 +155,28 @@ } } +// EnableTriggerComplete enables triggering complete event by increment +// methods or triggers it now if bar already has been incremented up +// to the total. Triggering complete event is auto disabled if bar +// constructed with `total <= 0`. +func (b *Bar) EnableTriggerComplete() { + select { + case b.operateState <- func(s *bState) { + if s.triggerComplete { + return + } + if s.current >= s.total { + s.current = s.total + s.completed = true + go b.forceRefresh() + } else { + s.triggerComplete = true + } + }: + case <-b.done: + } +} + // SetTotal sets total to an arbitrary value. Setting it to negative // value is equivalent to (*Bar).SetTotal((*Bar).Current(), bool). func (b *Bar) SetTotal(total int64, triggerCompleteNow bool) { diff --git a/bar_test.go b/bar_test.go index 95d37c1..ba288e4 100644 --- a/bar_test.go +++ b/bar_test.go @@ -46,6 +46,56 @@ if !bar.Aborted() { t.Error("bar isn't aborted after abort call") + } + + p.Wait() +} + +func TestBarEnableTriggerCompleteAndIncrementBefore(t *testing.T) { + p := mpb.New(mpb.WithWidth(80), mpb.WithOutput(ioutil.Discard)) + bar := p.AddBar(0) // never complete bar + + for _, f := range []func(){ + func() { bar.SetTotal(40, false) }, + func() { bar.IncrBy(60) }, + func() { bar.SetTotal(80, false) }, + func() { bar.IncrBy(20) }, + } { + f() + if bar.Completed() { + t.Fail() + } + } + + bar.EnableTriggerComplete() + + if !bar.Completed() { + t.Fail() + } + + p.Wait() +} + +func TestBarEnableTriggerCompleteAndIncrementAfter(t *testing.T) { + p := mpb.New(mpb.WithWidth(80), mpb.WithOutput(ioutil.Discard)) + bar := p.AddBar(0) // never complete bar + + for _, f := range []func(){ + func() { bar.SetTotal(40, false) }, + func() { bar.IncrBy(60) }, + func() { bar.SetTotal(80, false) }, + func() { bar.EnableTriggerComplete() }, + } { + f() + if bar.Completed() { + t.Fail() + } + } + + bar.IncrBy(20) + + if !bar.Completed() { + t.Fail() } p.Wait()