Codebase list golang-github-vbauerster-mpb / 9af2824
introduce left, right bar space Vladimir Bauer 9 years ago
8 changed file(s) with 64 addition(s) and 54 deletion(s). Raw diff Collapse all Expand all
1717 leftEnd byte
1818 rightEnd byte
1919
20 lastFrame []byte
21 lastStatus int
20 trimLeftSpace, trimRightSpace bool
2221
2322 incrCh chan int
2423 redrawReqCh chan *redrawRequest
3736 TimeElapsed, TimePerItemEstimate time.Duration
3837 }
3938
40 func (s *Statistics) eta() time.Duration {
39 func (s *Statistics) Eta() time.Duration {
4140 return time.Duration(s.Total-s.Current) * s.TimePerItemEstimate
4241 }
4342
6665
6766 // SetWidth sets width of the bar
6867 func (b *Bar) SetWidth(n int) *Bar {
69 if n <= 0 {
68 if n < 2 {
7069 return b
7170 }
7271 b.width = n
72 return b
73 }
74
75 func (b *Bar) TrimLeftSpace() *Bar {
76 b.trimLeftSpace = true
77 return b
78 }
79
80 func (b *Bar) TrimRightSpace() *Bar {
81 b.trimRightSpace = true
7382 return b
7483 }
7584
128137 }
129138
130139 // Current returns the actual current.
131 // If bar was stopped by Stop(), subsequent calls to Current will return -1
132140 func (b *Bar) Current() int {
133 if b.isDone() {
134 return -1
135 }
136141 respCh := make(chan int)
137142 b.currentReqCh <- respCh
138143 return <-respCh
163168 return b
164169 }
165170
166 // String returns the string representation of the bar
167 // func (b *Bar) String() string {
168 // if b.isDone() {
169 // return string(b.lastFrame)
170 // }
171 // respCh := make(chan []byte)
172 // b.redrawReqCh <- respCh
173 // return string(<-respCh)
174 // }
175
176171 type redrawRequest struct {
177172 width int
178173 respCh chan []byte
179174 }
180175
181176 func (b *Bar) Bytes(width int) []byte {
182 if b.isDone() {
183 return b.lastFrame
177 if width <= 0 {
178 width = b.width
184179 }
185180 respCh := make(chan []byte)
186181 b.redrawReqCh <- &redrawRequest{width, respCh}
190185 func (b *Bar) server(wg *sync.WaitGroup, total int) {
191186 timeStarted := time.Now()
192187 blockStartTime := timeStarted
193 // buf := make([]byte, 0, b.width+32)
194188 var tpie time.Duration
195189 var timeElapsed time.Duration
196190 var appendFuncs []DecoratorFunc
231225 respCh <- percentage(total, current, 100)
232226 case <-b.flushedCh:
233227 if completed && !b.isDone() {
234 stat := &Statistics{total, current, termWidth, timeElapsed, tpie}
235 b.lastFrame = b.draw(stat, appendFuncs, prependFuncs)
236 b.lastStatus = percentage(total, current, 100)
237228 close(b.done)
238229 wg.Done()
239 return
240230 }
241231 case <-b.stopCh:
242232 close(b.done)
243233 if !completed {
244234 wg.Done()
245235 }
246 return
247236 }
248237 }
249238 }
269258 prependCount := utf8.RuneCount(prependBlock)
270259 barCount := utf8.RuneCount(barBlock)
271260 appendCount := utf8.RuneCount(appendBlock)
261
262 var leftSpace, rightSpace []byte
263 space := []byte{' '}
264 if !b.trimLeftSpace {
265 prependCount++
266 leftSpace = space
267 }
268 if !b.trimRightSpace {
269 appendCount++
270 rightSpace = space
271 }
272
272273 totalCount := prependCount + barCount + appendCount
273
274274 if totalCount >= stat.TermWidth {
275275 newWidth := stat.TermWidth - prependCount - appendCount
276276 barBlock = b.fillBar(stat.Total, stat.Current, newWidth-1)
277277 }
278278
279 for _, block := range [...][]byte{prependBlock, barBlock, appendBlock} {
279 for _, block := range [...][]byte{prependBlock, leftSpace, barBlock, rightSpace, appendBlock} {
280280 buf = append(buf, block...)
281281 }
282282
287287 if width < 2 {
288288 return []byte{b.leftEnd, b.rightEnd}
289289 }
290
290291 buf := make([]byte, width)
291292 completedWidth := percentage(total, current, width)
292293
302303 }
303304 // set left and right ends bits
304305 buf[0], buf[width-1] = b.leftEnd, b.rightEnd
306
305307 return buf
306308 }
307309
315317 }
316318
317319 func (b *Bar) status() int {
318 if b.isDone() {
319 return b.lastStatus
320 }
321320 respCh := make(chan int)
322321 b.statusReqCh <- respCh
323322 return <-respCh
2929 func TerminalWidth() (int, error) {
3030 w := new(window)
3131 tio := syscall.TIOCGWINSZ
32 res, _, err := syscall.Syscall(syscall.SYS_IOCTL,
32 _, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
3333 tty.Fd(),
3434 uintptr(tio),
3535 uintptr(unsafe.Pointer(w)),
3636 )
37 if int(res) == -1 {
38 return 0, err
37 if errno != 0 {
38 return 0, errno
3939 }
4040 return int(w.Col), nil
4141 }
4242 func (b *Bar) PrependETA(padding int) *Bar {
4343 layout := "ETA%" + strconv.Itoa(padding) + "s"
4444 b.PrependFunc(func(s *Statistics) string {
45 return fmt.Sprintf(layout, time.Duration(s.eta().Seconds())*time.Second)
45 return fmt.Sprintf(layout, time.Duration(s.Eta().Seconds())*time.Second)
4646 })
4747 return b
4848 }
4949
5050 func (b *Bar) AppendETA() *Bar {
5151 b.AppendFunc(func(s *Statistics) string {
52 return fmt.Sprintf("ETA %s", time.Duration(s.eta().Seconds())*time.Second)
52 return fmt.Sprintf("ETA %s", time.Duration(s.Eta().Seconds())*time.Second)
5353 })
5454 return b
5555 }
2525 for i := 0; bar.InProgress(); i++ {
2626 time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
2727 bar.Incr(blockSize)
28 if bar.Current() > 42 {
29 p.RemoveBar(bar)
28 if bar.Current() > 42 && p.RemoveBar(bar) {
29 break
3030 }
3131 blockSize = rand.Intn(maxBlockSize) + 1
3232 }
3939 for i := 0; i < 100; i++ {
4040 time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
4141 bar2.Incr(1)
42 if bar2.Current() > 42 && p.RemoveBar(bar2) {
43 break
44 }
4245 blockSize = rand.Intn(maxBlockSize) + 1
4346 }
4447 }()
1818 p := mpb.New().SetWidth(64)
1919 // p := mpb.New().RefreshRate(80 * time.Millisecond).SetWidth(64)
2020
21 name1 := "Bar#1:"
22 bar1 := p.AddBar(50).AppendPercentage().PrependElapsed(3).PrependName(name1, len(name1))
21 name1 := "Bar#1: "
22 bar1 := p.AddBar(50).
23 PrependName(name1, len(name1)).PrependElapsed(3).
24 AppendPercentage().TrimRightSpace()
2325 wg.Add(1)
2426 go func() {
2527 defer wg.Done()
3133 }
3234 }()
3335
34 bar2 := p.AddBar(100).AppendPercentage().PrependElapsed(3).PrependName("", 0-len(name1))
36 bar2 := p.AddBar(100).
37 PrependName("", 0-len(name1)).PrependElapsed(3).
38 AppendPercentage().TrimRightSpace()
3539 wg.Add(1)
3640 go func() {
3741 defer wg.Done()
4347 }
4448 }()
4549
46 bar3 := p.AddBar(80).AppendPercentage().PrependElapsed(3).PrependName("Bar#3:", 0)
50 bar3 := p.AddBar(80).
51 PrependName("Bar#3: ", 0).PrependElapsed(3).
52 AppendPercentage().TrimRightSpace()
4753 wg.Add(1)
4854 go func() {
4955 defer wg.Done()
1818 p := mpb.New().SetWidth(64)
1919 // p := mpb.New().RefreshRate(100 * time.Millisecond).SetWidth(64)
2020
21 name1 := "Bar#1:"
22 bar1 := p.AddBar(50).AppendETA().PrependPercentage(3).PrependName(name1, len(name1))
21 name1 := "Bar#1: "
22 bar1 := p.AddBar(50).
23 PrependName(name1, len(name1)).PrependETA(4).
24 AppendPercentage().TrimRightSpace()
2325 wg.Add(1)
2426 go func() {
2527 defer wg.Done()
3133 }
3234 }()
3335
34 bar2 := p.AddBar(100).AppendETA().PrependPercentage(3).PrependName("", 0-len(name1))
36 bar2 := p.AddBar(100).
37 PrependName("", 0-len(name1)).PrependETA(4).
38 AppendPercentage().TrimRightSpace()
3539 wg.Add(1)
3640 go func() {
3741 defer wg.Done()
3943 for i := 0; i < 100; i++ {
4044 time.Sleep(time.Duration(blockSize) * (50*time.Millisecond + time.Duration(rand.Intn(5*int(time.Millisecond)))))
4145 bar2.Incr(1)
46 if bar2.Current() > 42 && p.RemoveBar(bar2) {
47 break
48 }
4249 blockSize = rand.Intn(maxBlockSize) + 1
4350 }
4451 }()
4552
46 bar3 := p.AddBar(80).AppendETA().PrependPercentage(3).PrependName("Bar#3:", 0)
53 bar3 := p.AddBar(80).
54 PrependName("Bar#3: ", 0).PrependETA(4).
55 AppendPercentage().TrimRightSpace()
4756 wg.Add(1)
4857 go func() {
4958 defer wg.Done()
5564 }
5665 }()
5766
58 time.Sleep(3 * time.Second)
59 // After removing the bar, it is good practice to ask underlying goroutine
60 // (2nd one in our example) to stop, so its wg.Done() will execute in time
61 p.RemoveBar(bar2)
62
6367 wg.Wait()
6468 p.Stop()
65 // p.AddBar(1) // panic: you cannot reuse p, create new one!
69 // p.AddBar(2) // panic: you cannot reuse p, create new one!
6670 fmt.Println("stop")
6771 }
184184 respCh <- len(bars)
185185 case <-t.C:
186186 width, _ := cwriter.TerminalWidth()
187 // fmt.Fprintf(os.Stderr, "twidth: %d\n", width)
188187 switch p.sort {
189188 case SortTop:
190189 sort.Sort(sort.Reverse(SortableBarSlice(bars)))
192191 sort.Sort(SortableBarSlice(bars))
193192 }
194193 for _, b := range bars {
195 // fmt.Fprintln(cw, b)
196194 buf := b.Bytes(width)
197195 buf = append(buf, '\n')
198196 cw.Write(buf)