| 72 | 72 |
trimRightCh: make(chan bool),
|
| 73 | 73 |
stateReqCh: make(chan chan state, 1),
|
| 74 | 74 |
decoratorCh: make(chan *decorator),
|
| 75 | |
flushedCh: make(chan struct{}),
|
|
75 |
flushedCh: make(chan struct{}, 1),
|
| 76 | 76 |
removeReqCh: make(chan struct{}),
|
| 77 | 77 |
done: make(chan struct{}),
|
| 78 | 78 |
}
|
|
| 91 | 91 |
|
| 92 | 92 |
// TrimLeftSpace removes space befor LeftEnd charater
|
| 93 | 93 |
func (b *Bar) TrimLeftSpace() *Bar {
|
| 94 | |
if !b.isDone() {
|
| 95 | |
b.trimLeftCh <- true
|
| 96 | |
}
|
|
94 |
if IsClosed(b.done) {
|
|
95 |
return b
|
|
96 |
}
|
|
97 |
b.trimLeftCh <- true
|
| 97 | 98 |
return b
|
| 98 | 99 |
}
|
| 99 | 100 |
|
| 100 | 101 |
// TrimRightSpace removes space after RightEnd charater
|
| 101 | 102 |
func (b *Bar) TrimRightSpace() *Bar {
|
| 102 | |
if !b.isDone() {
|
| 103 | |
b.trimRightCh <- true
|
| 104 | |
}
|
|
103 |
if IsClosed(b.done) {
|
|
104 |
return b
|
|
105 |
}
|
|
106 |
b.trimRightCh <- true
|
| 105 | 107 |
return b
|
| 106 | 108 |
}
|
| 107 | 109 |
|
|
| 155 | 157 |
|
| 156 | 158 |
// Incr increments progress bar
|
| 157 | 159 |
func (b *Bar) Incr(n int) {
|
| 158 | |
if n > 0 && !b.isDone() {
|
|
160 |
if IsClosed(b.done) {
|
|
161 |
return
|
|
162 |
}
|
|
163 |
if n > 0 {
|
| 159 | 164 |
b.incrCh <- int64(n)
|
| 160 | 165 |
}
|
| 161 | 166 |
}
|
|
| 170 | 175 |
|
| 171 | 176 |
// Current returns the actual current.
|
| 172 | 177 |
func (b *Bar) Current() int64 {
|
| 173 | |
if b.isDone() {
|
|
178 |
if IsClosed(b.done) {
|
| 174 | 179 |
return b.lastState.current
|
| 175 | 180 |
}
|
| 176 | 181 |
ch := make(chan state, 1)
|
|
| 182 | 187 |
// InProgress returns true, while progress is running
|
| 183 | 188 |
// Can be used as condition in for loop
|
| 184 | 189 |
func (b *Bar) InProgress() bool {
|
| 185 | |
return !b.isDone()
|
|
190 |
return !IsClosed(b.done)
|
| 186 | 191 |
}
|
| 187 | 192 |
|
| 188 | 193 |
// PrependFunc prepends DecoratorFunc
|
| 189 | 194 |
func (b *Bar) PrependFunc(f DecoratorFunc) *Bar {
|
| 190 | |
if !b.isDone() {
|
| 191 | |
b.decoratorCh <- &decorator{decPrepend, f}
|
| 192 | |
}
|
| 193 | |
return b
|
| 194 | |
}
|
| 195 | |
|
|
195 |
if IsClosed(b.done) {
|
|
196 |
return b
|
|
197 |
}
|
|
198 |
b.decoratorCh <- &decorator{decPrepend, f}
|
|
199 |
return b
|
|
200 |
}
|
|
201 |
|
|
202 |
// RemoveAllPrependers removes all prepend functions
|
| 196 | 203 |
func (b *Bar) RemoveAllPrependers() {
|
| 197 | |
if !b.isDone() {
|
| 198 | |
b.decoratorCh <- &decorator{decPrependZero, nil}
|
| 199 | |
}
|
|
204 |
if IsClosed(b.done) {
|
|
205 |
return
|
|
206 |
}
|
|
207 |
b.decoratorCh <- &decorator{decPrependZero, nil}
|
| 200 | 208 |
}
|
| 201 | 209 |
|
| 202 | 210 |
// AppendFunc appends DecoratorFunc
|
| 203 | 211 |
func (b *Bar) AppendFunc(f DecoratorFunc) *Bar {
|
| 204 | |
if !b.isDone() {
|
| 205 | |
b.decoratorCh <- &decorator{decAppend, f}
|
| 206 | |
}
|
| 207 | |
return b
|
| 208 | |
}
|
| 209 | |
|
|
212 |
if IsClosed(b.done) {
|
|
213 |
return b
|
|
214 |
}
|
|
215 |
b.decoratorCh <- &decorator{decAppend, f}
|
|
216 |
return b
|
|
217 |
}
|
|
218 |
|
|
219 |
// RemoveAllAppenders removes all append functions
|
| 210 | 220 |
func (b *Bar) RemoveAllAppenders() {
|
| 211 | |
if !b.isDone() {
|
| 212 | |
b.decoratorCh <- &decorator{decAppendZero, nil}
|
| 213 | |
}
|
|
221 |
if IsClosed(b.done) {
|
|
222 |
return
|
|
223 |
}
|
|
224 |
b.decoratorCh <- &decorator{decAppendZero, nil}
|
| 214 | 225 |
}
|
| 215 | 226 |
|
| 216 | 227 |
func (b *Bar) bytes(width int) []byte {
|
| 217 | 228 |
if width <= 0 {
|
| 218 | 229 |
width = b.width
|
| 219 | 230 |
}
|
| 220 | |
if b.isDone() {
|
|
231 |
if IsClosed(b.done) {
|
| 221 | 232 |
return b.draw(b.lastState, width)
|
| 222 | 233 |
}
|
| 223 | 234 |
ch := make(chan state, 1)
|
|
| 283 | 294 |
close(b.done)
|
| 284 | 295 |
}
|
| 285 | 296 |
|
| 286 | |
func (b *Bar) flushDone() {
|
| 287 | |
if !b.isDone() {
|
| 288 | |
b.flushedCh <- struct{}{}
|
| 289 | |
}
|
|
297 |
func (b *Bar) flushed() {
|
|
298 |
if IsClosed(b.done) {
|
|
299 |
return
|
|
300 |
}
|
|
301 |
b.flushedCh <- struct{}{}
|
| 290 | 302 |
}
|
| 291 | 303 |
|
| 292 | 304 |
func (b *Bar) remove() {
|
| 293 | |
if !b.isDone() {
|
| 294 | |
b.removeReqCh <- struct{}{}
|
| 295 | |
}
|
|
305 |
if IsClosed(b.done) {
|
|
306 |
return
|
|
307 |
}
|
|
308 |
b.removeReqCh <- struct{}{}
|
| 296 | 309 |
}
|
| 297 | 310 |
|
| 298 | 311 |
func (b *Bar) draw(s state, termWidth int) []byte {
|
|
| 384 | 397 |
return buf
|
| 385 | 398 |
}
|
| 386 | 399 |
|
| 387 | |
func (b *Bar) isDone() bool {
|
| 388 | |
select {
|
| 389 | |
case <-b.done:
|
| 390 | |
return true
|
| 391 | |
default:
|
| 392 | |
return false
|
| 393 | |
}
|
| 394 | |
}
|
| 395 | |
|
| 396 | 400 |
func (b *Bar) status() int {
|
| 397 | 401 |
var total, current int64
|
| 398 | |
if b.isDone() {
|
|
402 |
if IsClosed(b.done) {
|
| 399 | 403 |
total = b.lastState.total
|
| 400 | 404 |
current = b.lastState.current
|
| 401 | 405 |
} else {
|