package pomodoro import "time" // Represents a timer type Timer struct { TimeLeft chan int // signals time left on every second End chan bool // signal on successful end Abort chan bool // signal on premature end stop chan bool // internal channel wait chan bool // internal channel resume chan bool // internal channel } // Initializes a new timer with fresh channels func (t Timer) Init() Timer { return Timer{ TimeLeft: make(chan int), End: make(chan bool, 1), Abort: make(chan bool, 1), stop: make(chan bool, 1), wait: make(chan bool, 1), resume: make(chan bool, 1), } } // Start the timer (goroutine) func (t *Timer) StartAsync(duration int) { go t.Start(duration) } // Start the timer (blocking) func (t *Timer) Start(duration int) { tick := time.NewTicker(time.Second) for timeLeft := duration; timeLeft > 0; { select { case <-t.stop: t.Abort <- true return case <-t.wait: <-t.resume continue case <-tick.C: timeLeft-- default: t.TimeLeft <- timeLeft } } t.TimeLeft <- 0 t.End <- true } func (t *Timer) Stop() { t.resume <- true t.stop <- true } func (t *Timer) Pause() { t.wait <- true } func (t *Timer) Resume() { t.resume <- true }