diff --git a/internal/pomodoro/pomodoro.go b/internal/pomodoro/pomodoro.go index d0a9326..7b18e4b 100644 --- a/internal/pomodoro/pomodoro.go +++ b/internal/pomodoro/pomodoro.go @@ -6,11 +6,8 @@ import ( "time" ) -var pomodoroResetChannel = make(chan bool, 1) -var pomodoroPauseChannel = make(chan bool, 1) -var pomodoroResumeChannel = make(chan bool, 1) - var mu sync.Mutex // to synchronize access to shared state +var timer Timer // RunPomodoro iterates the Pomodoro work/break sessions. func RunPomodoro() { @@ -22,26 +19,29 @@ func RunPomodoro() { pomodoroConfig := shared.Message.PomodoroSettings for session := 1; session <= pomodoroConfig.Sessions; session++ { + timer = timer.Init() + shared.Message.Session = session + shared.Message.Mode = "Work" - if !startTimer(pomodoroConfig.Work) { + if !timer.Start(pomodoroConfig.Work) { break } - if session == pomodoroConfig.Sessions { - shared.Message.Mode = "LongBreak" - if !startTimer(pomodoroConfig.LongBreak) { - break - } - } else { - shared.Message.Mode = "ShortBreak" - if !startTimer(pomodoroConfig.ShortBreak) { - break - } - } - shared.Message.Mode = "End" - } - time.Sleep(time.Second) + if session > pomodoroConfig.Sessions { + shared.Message.Mode = "ShortBreak" + if !timer.Start(pomodoroConfig.ShortBreak) { + break + } + } else { // last phase, prepare for finish + shared.Message.Mode = "LongBreak" + if !timer.Start(pomodoroConfig.LongBreak) { + break + } + shared.Message.Mode = "End" + time.Sleep(time.Second) + } + } mu.Lock() shared.Message.Ongoing = false @@ -53,12 +53,8 @@ func RunPomodoro() { shared.Message.TimeLeft = shared.Message.PomodoroSettings.Work } -// Stops and resets the running Pomodoro func ResetPomodoro() { - shared.Message.Mode = "Idle" - shared.Message.Session = 0 - shared.Message.TimeLeft = shared.Message.PomodoroSettings.Work - pomodoroResetChannel <- true + timer.Stop() } func PausePomodoro() { @@ -66,14 +62,14 @@ func PausePomodoro() { shared.Message.Paused = true mu.Unlock() - pomodoroPauseChannel <- true + timer.Pause() } func ResumePomodoro() { mu.Lock() shared.Message.Paused = false mu.Unlock() - pomodoroResumeChannel <- true + timer.Resume() } func IsPomodoroOngoing() bool { diff --git a/internal/pomodoro/timer.go b/internal/pomodoro/timer.go index 4b4c86e..ebd3106 100644 --- a/internal/pomodoro/timer.go +++ b/internal/pomodoro/timer.go @@ -5,28 +5,49 @@ import ( "time" ) -// runs the countdown and updates shared.Message.TimeLeft every second. -func startTimer(remainingSeconds int) bool { - for remainingSeconds > 0 { +type Timer struct { + abort 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), + } +} + +func (t *Timer) Start(duration int) bool { + for timeLeft := duration; timeLeft > 0; { select { - case <-pomodoroResetChannel: + case <-t.abort: return false - case <-pomodoroPauseChannel: - // Nothing to set here, just waiting for the signal - case <-pomodoroResumeChannel: - // Nothing to set here, just waiting for the signal + case <-t.wait: + <-t.resume default: - // Broadcast the current state to all clients - if !IsPomodoroPaused() { - shared.Message.TimeLeft = remainingSeconds - time.Sleep(time.Second) - remainingSeconds-- - } + shared.Message.TimeLeft = timeLeft + time.Sleep(time.Second) + timeLeft-- } } // Final shared.Message when time reaches zero - shared.Message.TimeLeft = remainingSeconds + shared.Message.TimeLeft = 0 return true } + +func (t *Timer) Stop() { + t.resume <- true + t.abort <- true +} + +func (t *Timer) Pause() { + t.wait <- true +} + +func (t *Timer) Resume() { + t.resume <- true +}