2024-10-10 20:40:29 +00:00
|
|
|
package debouncer
|
|
|
|
|
|
|
|
import "time"
|
|
|
|
|
|
|
|
type Debouncer struct {
|
|
|
|
input <-chan bool
|
|
|
|
C <-chan bool
|
|
|
|
}
|
|
|
|
|
2024-10-10 21:13:00 +00:00
|
|
|
func New(ch <-chan bool, window time.Duration) *Debouncer {
|
2024-10-10 20:40:29 +00:00
|
|
|
output := make(chan bool)
|
|
|
|
var currentState bool
|
|
|
|
var lastState bool
|
|
|
|
falseTimer := time.NewTimer(0)
|
|
|
|
falseTimer.Stop()
|
|
|
|
go func() {
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-falseTimer.C:
|
|
|
|
if !currentState && lastState {
|
|
|
|
output <- false
|
|
|
|
lastState = false
|
|
|
|
} else {
|
2024-10-10 21:13:00 +00:00
|
|
|
falseTimer.Reset(window)
|
2024-10-10 20:40:29 +00:00
|
|
|
}
|
|
|
|
case v, ok := <-ch:
|
|
|
|
if !ok {
|
2024-10-10 21:13:00 +00:00
|
|
|
falseTimer.Reset(window)
|
2024-10-10 20:40:29 +00:00
|
|
|
<-falseTimer.C
|
|
|
|
output <- false
|
|
|
|
close(output)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if v {
|
|
|
|
if !lastState {
|
|
|
|
output <- true
|
|
|
|
lastState = true
|
2024-10-10 21:13:00 +00:00
|
|
|
falseTimer.Reset(window)
|
2024-10-10 20:40:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
currentState = true
|
|
|
|
} else {
|
2024-10-10 21:13:00 +00:00
|
|
|
falseTimer.Reset(window)
|
2024-10-10 20:40:29 +00:00
|
|
|
|
|
|
|
currentState = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
d := &Debouncer{input: ch, C: output}
|
|
|
|
|
|
|
|
return d
|
|
|
|
}
|