blob: 4e3bb5bec69902cff3b0cbbcd9df24e4a36bd240 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
package statusline
import (
"fmt"
"sync"
"time"
)
type stopWatch struct {
inner StatusLine
precision time.Duration
start time.Time
line string
once sync.Once
lines chan string
end1 chan bool
end2 chan struct{}
}
func StopWatch(sl StatusLine, precision time.Duration) StatusLine {
return &stopWatch{
inner: sl,
precision: precision,
lines: make(chan string),
end1: make(chan bool),
end2: make(chan struct{}),
}
}
func (sw *stopWatch) startWorker() {
go func() {
sw.start = time.Now()
ticker := time.NewTicker(sw.precision)
for {
select {
case <-ticker.C:
sw.tick()
case sw.line = <-sw.lines:
sw.tick()
case keep := <-sw.end1:
sw.tick()
sw.inner.End(keep)
ticker.Stop()
sw.end2 <- struct{}{}
close(sw.end2)
return
}
}
}()
}
func (sw *stopWatch) tick() {
d := time.Now().Sub(sw.start).Round(sw.precision)
sw.inner.Put(fmt.Sprintf("[ %v ] %s", d, sw.line))
}
func (sl *stopWatch) Put(line string) {
sl.once.Do(sl.startWorker)
sl.lines <- line
}
func (sl *stopWatch) End(keep bool) {
sl.once.Do(sl.startWorker)
sl.end1 <- keep
close(sl.lines)
close(sl.end1)
<-sl.end2
}
|