-
Notifications
You must be signed in to change notification settings - Fork 0
/
loading.go
executable file
·157 lines (128 loc) · 3.15 KB
/
loading.go
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package nfo
import (
"fmt"
"github.com/cmcoffee/snugforge/xsync"
"sync"
"sync/atomic"
"time"
)
func init() {
PleaseWait.Set(func() string { return "Please wait ..." }, []string{"[> ]", "[>> ]", "[>>>]", "[ >>]", "[ >]", "[ <]", "[ <<]", "[<<<]", "[<< ]", "[< ]"})
}
// PleaseWait is a wait prompt to display between requests.
var PleaseWait = new(loading)
type loading struct {
flag xsync.BitFlag
message func() string
anim_1 []string
anim_2 []string
mutex sync.Mutex
counter int32
}
type loading_backup struct {
message func() string
anim_1 []string
anim_2 []string
}
const (
loading_show = 1 << iota
transfer_monitor_active
)
func (B *loading_backup) Restore() {
PleaseWait.Set(B.message, B.anim_1, B.anim_2)
}
func (L *loading) Backup() *loading_backup {
L.mutex.Lock()
defer L.mutex.Unlock()
return &loading_backup{L.message, L.anim_1, L.anim_2}
}
// Specify a "Please wait" animated PleaseWait line.
func (L *loading) Set(message func() string, loader ...[]string) {
L.mutex.Lock()
defer L.mutex.Unlock()
if len(loader) == 0 {
return
}
var anim_1, anim_2 []string
anim_1 = loader[0]
if len(loader) > 1 {
anim_2 = loader[1]
}
if anim_2 == nil || len(anim_2) < len(anim_1) {
anim_2 = make([]string, len(anim_1))
}
L.message = message
L.anim_1 = anim_1
L.anim_2 = anim_2
count := atomic.AddInt32(&L.counter, 1)
go func(message func() string, anim_1 []string, anim_2 []string, count int32) {
for count == atomic.LoadInt32(&L.counter) {
for i, str := range anim_1 {
if L.flag.Has(loading_show) && !L.flag.Has(transfer_monitor_active) && count == atomic.LoadInt32(&L.counter) {
Flash("%s %s %s", str, message(), anim_2[i])
}
time.Sleep(125 * time.Millisecond)
}
}
}(message, anim_1, anim_2, count)
}
// Displays loader. "[>>>] Working, Please wait."
func (L *loading) Show() {
L.flag.Set(loading_show)
}
// Hides display loader.
func (L *loading) Hide() {
L.flag.Unset(loading_show)
time.Sleep(time.Millisecond)
Flash("")
}
type progressBar struct {
mutex sync.Mutex
cur int64
max int64
working bool
name string
anim_len int
backup *loading_backup
}
var ProgressBar = new(progressBar)
// Produces progress bar for information on update.
func (p *progressBar) draw() string {
cur := atomic.LoadInt64(&p.cur)
max := atomic.LoadInt64(&p.max)
return DrawProgressBar(27-p.anim_len, cur, max, fmt.Sprintf("%d/%d %s.", cur, max, p.name))
}
func (p *progressBar) updateMessage() string {
return p.draw()
}
// Updates loading to be a progress bar.
func (p *progressBar) New(name string, max int) {
p.mutex.Lock()
defer p.mutex.Unlock()
if p.working {
return
}
p.cur = 0
p.max = int64(max)
p.name = name
p.backup = PleaseWait.Backup()
PleaseWait.Set(p.updateMessage, PleaseWait.anim_1)
p.anim_len = len(PleaseWait.anim_1)
p.working = true
}
// Adds to progress bar.
func (p *progressBar) Add(num int) {
atomic.StoreInt64(&p.cur, atomic.LoadInt64(&p.cur)+int64(num))
}
// Complete progress bar, return to loading.
func (p *progressBar) Done() {
p.mutex.Lock()
defer p.mutex.Unlock()
if !p.working {
return
}
if p.backup != nil {
p.backup.Restore()
}
p.working = false
}