| 32 | 32 |
index int
|
| 33 | 33 |
|
| 34 | 34 |
operateState chan func(*bState)
|
| 35 | |
quit chan struct{}
|
|
35 |
done chan struct{}
|
|
36 |
shutdown chan struct{}
|
| 36 | 37 |
once sync.Once
|
| 37 | 38 |
|
| 38 | |
// cacheState is used after quit is closed
|
|
39 |
// cacheState is used after done is closed
|
| 39 | 40 |
cacheState *bState
|
| 40 | 41 |
}
|
| 41 | 42 |
|
|
| 96 | 97 |
b := &Bar{
|
| 97 | 98 |
priority: id,
|
| 98 | 99 |
operateState: make(chan func(*bState)),
|
| 99 | |
quit: make(chan struct{}),
|
|
100 |
done: make(chan struct{}),
|
|
101 |
shutdown: make(chan struct{}),
|
| 100 | 102 |
}
|
| 101 | 103 |
|
| 102 | 104 |
go b.serve(s, wg, cancel)
|
|
| 109 | 111 |
case b.operateState <- func(s *bState) {
|
| 110 | 112 |
s.prependFuncs = nil
|
| 111 | 113 |
}:
|
| 112 | |
case <-b.quit:
|
|
114 |
case <-b.done:
|
| 113 | 115 |
}
|
| 114 | 116 |
}
|
| 115 | 117 |
|
|
| 119 | 121 |
case b.operateState <- func(s *bState) {
|
| 120 | 122 |
s.appendFuncs = nil
|
| 121 | 123 |
}:
|
| 122 | |
case <-b.quit:
|
|
124 |
case <-b.done:
|
| 123 | 125 |
}
|
| 124 | 126 |
}
|
| 125 | 127 |
|
|
| 165 | 167 |
s.completed = true
|
| 166 | 168 |
}
|
| 167 | 169 |
}:
|
| 168 | |
case <-b.quit:
|
|
170 |
case <-b.done:
|
| 169 | 171 |
}
|
| 170 | 172 |
}
|
| 171 | 173 |
|
|
| 179 | 181 |
case b.operateState <- func(s *bState) {
|
| 180 | 182 |
s.refill = &refill{r, till}
|
| 181 | 183 |
}:
|
| 182 | |
case <-b.quit:
|
|
184 |
case <-b.done:
|
| 183 | 185 |
}
|
| 184 | 186 |
}
|
| 185 | 187 |
|
|
| 189 | 191 |
select {
|
| 190 | 192 |
case b.operateState <- func(s *bState) { result <- len(s.appendFuncs) }:
|
| 191 | 193 |
return <-result
|
| 192 | |
case <-b.quit:
|
|
194 |
case <-b.done:
|
| 193 | 195 |
return len(b.cacheState.appendFuncs)
|
| 194 | 196 |
}
|
| 195 | 197 |
}
|
|
| 200 | 202 |
select {
|
| 201 | 203 |
case b.operateState <- func(s *bState) { result <- len(s.prependFuncs) }:
|
| 202 | 204 |
return <-result
|
| 203 | |
case <-b.quit:
|
|
205 |
case <-b.done:
|
| 204 | 206 |
return len(b.cacheState.prependFuncs)
|
| 205 | 207 |
}
|
| 206 | 208 |
}
|
|
| 211 | 213 |
select {
|
| 212 | 214 |
case b.operateState <- func(s *bState) { result <- s.id }:
|
| 213 | 215 |
return <-result
|
| 214 | |
case <-b.quit:
|
|
216 |
case <-b.done:
|
| 215 | 217 |
return b.cacheState.id
|
| 216 | 218 |
}
|
| 217 | 219 |
}
|
|
| 222 | 224 |
select {
|
| 223 | 225 |
case b.operateState <- func(s *bState) { result <- s.current }:
|
| 224 | 226 |
return <-result
|
| 225 | |
case <-b.quit:
|
|
227 |
case <-b.done:
|
| 226 | 228 |
return b.cacheState.current
|
| 227 | 229 |
}
|
| 228 | 230 |
}
|
|
| 233 | 235 |
select {
|
| 234 | 236 |
case b.operateState <- func(s *bState) { result <- s.total }:
|
| 235 | 237 |
return <-result
|
| 236 | |
case <-b.quit:
|
|
238 |
case <-b.done:
|
| 237 | 239 |
return b.cacheState.total
|
| 238 | 240 |
}
|
| 239 | 241 |
}
|
|
| 246 | 248 |
s.total = total
|
| 247 | 249 |
s.dynamic = !final
|
| 248 | 250 |
}:
|
| 249 | |
case <-b.quit:
|
|
251 |
case <-b.done:
|
| 250 | 252 |
}
|
| 251 | 253 |
}
|
| 252 | 254 |
|
|
| 254 | 256 |
// Can be used as condition in for loop
|
| 255 | 257 |
func (b *Bar) InProgress() bool {
|
| 256 | 258 |
select {
|
| 257 | |
case <-b.quit:
|
|
259 |
case <-b.done:
|
| 258 | 260 |
return false
|
| 259 | 261 |
default:
|
| 260 | 262 |
return true
|
|
| 264 | 266 |
// Complete stops bar's progress tracking, but not removes the bar.
|
| 265 | 267 |
// If you need to remove, call Progress.RemoveBar(*Bar) instead.
|
| 266 | 268 |
func (b *Bar) Complete() {
|
| 267 | |
b.once.Do(b.shutdown)
|
| 268 | |
<-b.quit
|
| 269 | |
}
|
| 270 | |
|
| 271 | |
func (b *Bar) shutdown() {
|
| 272 | |
b.quit <- struct{}{}
|
|
269 |
b.once.Do(func() {
|
|
270 |
close(b.shutdown)
|
|
271 |
})
|
| 273 | 272 |
}
|
| 274 | 273 |
|
| 275 | 274 |
func (b *Bar) serve(s *bState, wg *sync.WaitGroup, cancel <-chan struct{}) {
|
|
275 |
defer func() {
|
|
276 |
b.cacheState = s
|
|
277 |
close(b.done)
|
|
278 |
wg.Done()
|
|
279 |
}()
|
| 276 | 280 |
for {
|
| 277 | 281 |
select {
|
| 278 | 282 |
case op := <-b.operateState:
|
| 279 | 283 |
op(s)
|
| 280 | 284 |
case <-cancel:
|
| 281 | 285 |
s.aborted = true
|
| 282 | |
cancel = nil
|
| 283 | |
go b.Complete()
|
| 284 | |
case <-b.quit:
|
| 285 | |
b.cacheState = s
|
| 286 | |
close(b.quit)
|
| 287 | |
wg.Done()
|
|
286 |
return
|
|
287 |
case <-b.shutdown:
|
| 288 | 288 |
return
|
| 289 | 289 |
}
|
| 290 | 290 |
}
|
|
| 310 | 310 |
s.draw(tw, prependWs, appendWs)
|
| 311 | 311 |
ch <- &bufReader{io.MultiReader(s.bufP, s.bufB, s.bufA), s.completed}
|
| 312 | 312 |
}:
|
| 313 | |
case <-b.quit:
|
|
313 |
case <-b.done:
|
| 314 | 314 |
s := b.cacheState
|
| 315 | 315 |
var r io.Reader
|
| 316 | 316 |
if s.panic != "" {
|