package debouncer import "time" type Debouncer struct { input <-chan bool C <-chan bool } func New(ch <-chan bool, window time.Duration) *Debouncer { 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 { falseTimer.Reset(window) } case v, ok := <-ch: if !ok { falseTimer.Reset(window) <-falseTimer.C output <- false close(output) return } if v { if !lastState { output <- true lastState = true falseTimer.Reset(window) } currentState = true } else { falseTimer.Reset(window) currentState = false } } } }() d := &Debouncer{input: ch, C: output} return d }