42 lines
945 B
Go
42 lines
945 B
Go
package common
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// TickAndDebounce calls function f on trigger channel or with tickTime period (whatever is sooner) with debounce
|
|
func TickAndDebounce(tickTime time.Duration, debounceTime time.Duration, trigger chan struct{}, f func()) {
|
|
timer := time.NewTimer(tickTime)
|
|
var firstDebounce time.Time
|
|
Loop:
|
|
for {
|
|
select {
|
|
case _, ok := <-trigger:
|
|
if !timer.Stop() {
|
|
<-timer.C
|
|
}
|
|
// exit loop on closed input channel
|
|
if !ok {
|
|
break Loop
|
|
}
|
|
if firstDebounce.IsZero() {
|
|
firstDebounce = time.Now()
|
|
}
|
|
// debounce for up to debounceTime period
|
|
// afterwards execute immediately
|
|
if firstDebounce.Add(debounceTime).After(time.Now()) {
|
|
timer.Reset(debounceTime)
|
|
} else {
|
|
timer.Reset(0)
|
|
}
|
|
case <-timer.C:
|
|
// do the action, if not in shutdown, then start the loop again
|
|
if !IsInShutdown() {
|
|
f()
|
|
}
|
|
timer.Reset(tickTime)
|
|
firstDebounce = time.Time{}
|
|
}
|
|
}
|
|
}
|