package ticker
import (
"sync"
"sync/atomic"
"time"
)
type Force struct {
isActive uint32
Force chan time.Time
ticker <-chan time.Time
skip chan struct{}
wg sync.WaitGroup
quit chan struct{}
}
var _ Ticker = (*Force)(nil)
func NewForce(interval time.Duration) *Force {
m := &Force{
ticker: time.NewTicker(interval).C,
Force: make(chan time.Time),
skip: make(chan struct{}),
quit: make(chan struct{}),
}
m.wg.Add(1)
go func() {
defer m.wg.Done()
for {
select {
case t := <-m.ticker:
if atomic.LoadUint32(&m.isActive) == 0 {
continue
}
select {
case m.Force <- t:
case <-m.skip:
case <-m.quit:
return
}
case <-m.quit:
return
}
}
}()
return m
}
func (m *Force) Ticks() <-chan time.Time {
return m.Force
}
func (m *Force) Resume() {
atomic.StoreUint32(&m.isActive, 1)
}
func (m *Force) Pause() {
atomic.StoreUint32(&m.isActive, 0)
select {
case m.skip <- struct{}{}:
default:
}
}
func (m *Force) Stop() {
m.Pause()
close(m.quit)
m.wg.Wait()
}