-
Notifications
You must be signed in to change notification settings - Fork 107
/
Copy pathactivation.go
110 lines (97 loc) · 2.46 KB
/
activation.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
package main
import (
"time"
)
// ToggleData type
type ToggleData struct {
Mode uint
Data uint
}
// ActivationHandler type
type ActivationHandler struct {
queryChannel chan bool
toggleChannel chan ToggleData
setChannel chan bool
}
func startActivation(actChannel chan *ActivationHandler, quit chan bool, reactivationDelay uint) {
var reactivate time.Time
var reactivatePending bool
a := &ActivationHandler{}
a.queryChannel = make(chan bool)
a.toggleChannel = make(chan ToggleData)
a.setChannel = make(chan bool)
// put the reference to our struct in the channel
// then continue to the loop
actChannel <- a
ticker := time.Tick(1 * time.Second)
var nextToggleTime = time.Now()
forever:
for {
select {
case <-quit:
break forever
case <-a.queryChannel:
a.queryChannel <- grimdActive
case v := <-a.toggleChannel:
// Firefox is sending 2 queries in a row, so debouncing is needed.
if v.Mode == 1 && nextToggleTime.After(time.Now()) {
logger.Warning("Toggle is too close: wait 10 seconds\n")
} else {
if v.Mode == 1 {
grimdActive = !grimdActive
} else {
grimdActive = false
}
nextToggleTime = time.Now().Add(time.Duration(10) * time.Second)
if !grimdActive && reactivationDelay > 0 {
reactivate = time.Now().Add(time.Duration(v.Data) * time.Second)
reactivatePending = true
} else {
reactivatePending = false
}
a.queryChannel <- grimdActive
}
case v := <-a.setChannel:
grimdActive = v
reactivatePending = false
a.setChannel <- grimdActive
case <-ticker:
now := time.Now()
if reactivatePending && now.After(reactivate) {
logger.Notice("Reactivating grimd (timer)")
grimdActive = true
reactivatePending = false
}
}
}
logger.Debugf("Activation goroutine exiting")
quit <- true
}
// Query activation state
func (a ActivationHandler) query() bool {
a.queryChannel <- true
return <-a.queryChannel
}
// Set activation state
func (a ActivationHandler) set(v bool) bool {
a.setChannel <- v
return <-a.setChannel
}
// Toggle activation state on or off
func (a ActivationHandler) toggle(reactivationDelay uint) bool {
data := ToggleData{
Mode: 1,
Data: reactivationDelay,
}
a.toggleChannel <- data
return <-a.queryChannel
}
// Like toggle(), but only from on to off. Toggling when off will restart the
// timer.
func (a ActivationHandler) toggleOff(timeout uint) bool {
a.toggleChannel <- ToggleData{
Mode: 2,
Data: timeout,
}
return <-a.queryChannel
}