diff --git a/internal/pomodoro/pomodoro.go b/internal/pomodoro/pomodoro.go index 7b18e4b..5f0af99 100644 --- a/internal/pomodoro/pomodoro.go +++ b/internal/pomodoro/pomodoro.go @@ -9,6 +9,19 @@ import ( var mu sync.Mutex // to synchronize access to shared state var timer Timer +func waitForTimer(t Timer) bool { + for { + select { + case <-t.End: + return true + case <-t.Abort: + return false + case shared.Message.TimeLeft = <-t.TimeLeft: + // do nothing, just let the timer update the message + } + } +} + // RunPomodoro iterates the Pomodoro work/break sessions. func RunPomodoro() { mu.Lock() @@ -24,18 +37,21 @@ func RunPomodoro() { shared.Message.Session = session shared.Message.Mode = "Work" - if !timer.Start(pomodoroConfig.Work) { + go timer.Start(pomodoroConfig.Work) + if !waitForTimer(timer) { break } - if session > pomodoroConfig.Sessions { + if session < pomodoroConfig.Sessions { shared.Message.Mode = "ShortBreak" - if !timer.Start(pomodoroConfig.ShortBreak) { + go timer.Start(pomodoroConfig.ShortBreak) + if !waitForTimer(timer) { break } } else { // last phase, prepare for finish shared.Message.Mode = "LongBreak" - if !timer.Start(pomodoroConfig.LongBreak) { + go timer.Start(pomodoroConfig.LongBreak) + if !waitForTimer(timer) { break } shared.Message.Mode = "End" diff --git a/internal/pomodoro/timer.go b/internal/pomodoro/timer.go index ebd3106..55cb654 100644 --- a/internal/pomodoro/timer.go +++ b/internal/pomodoro/timer.go @@ -1,47 +1,53 @@ package pomodoro import ( - "git.smsvc.net/pomodoro/GoTomato/internal/shared" "time" ) type Timer struct { - abort chan bool - wait chan bool - resume chan bool + TimeLeft chan int // time left + End chan bool // signal on successful end + Abort chan bool // signal on premature end + stop chan bool + wait chan bool + resume chan bool } func (t Timer) Init() Timer { return Timer{ - abort: make(chan bool, 1), - wait: make(chan bool, 1), - resume: make(chan bool, 1), + 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), } } -func (t *Timer) Start(duration int) bool { +func (t *Timer) Start(duration int) { + tick := time.NewTicker(time.Second) for timeLeft := duration; timeLeft > 0; { select { - case <-t.abort: - return false + case <-t.stop: + t.Abort <- true + return case <-t.wait: <-t.resume - default: - shared.Message.TimeLeft = timeLeft - time.Sleep(time.Second) + continue + case <-tick.C: timeLeft-- + default: + t.TimeLeft <- timeLeft } } + t.TimeLeft <- 0 - // Final shared.Message when time reaches zero - shared.Message.TimeLeft = 0 - - return true + t.End <- true } func (t *Timer) Stop() { t.resume <- true - t.abort <- true + t.stop <- true } func (t *Timer) Pause() {