Compare commits

..

No commits in common. "636f8c2feb277d71f89387673abacbd0a09caae2" and "d256235c1b927e1f873fc45c1bf5d50d6ee449df" have entirely different histories.

4 changed files with 43 additions and 83 deletions

View file

@ -1,3 +1,3 @@
package metadata package metadata
const GoTomatoVersion = "v0.0.3" // The GoTomato Version const GoTomatoVersion = "v0.0.2" // The GoTomato Version

View file

@ -6,21 +6,11 @@ import (
"time" "time"
) )
var mu sync.Mutex // to synchronize access to shared state var pomodoroResetChannel = make(chan bool, 1)
var timer Timer var pomodoroPauseChannel = make(chan bool, 1)
var pomodoroResumeChannel = make(chan bool, 1)
func waitForTimer(t Timer) bool { var mu sync.Mutex // to synchronize access to shared state
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. // RunPomodoro iterates the Pomodoro work/break sessions.
func RunPomodoro() { func RunPomodoro() {
@ -32,32 +22,26 @@ func RunPomodoro() {
pomodoroConfig := shared.Message.PomodoroSettings pomodoroConfig := shared.Message.PomodoroSettings
for session := 1; session <= pomodoroConfig.Sessions; session++ { for session := 1; session <= pomodoroConfig.Sessions; session++ {
timer = timer.Init()
shared.Message.Session = session shared.Message.Session = session
shared.Message.Mode = "Work" shared.Message.Mode = "Work"
go timer.Start(pomodoroConfig.Work) if !startTimer(pomodoroConfig.Work) {
if !waitForTimer(timer) {
break break
} }
if session == pomodoroConfig.Sessions {
if session < pomodoroConfig.Sessions {
shared.Message.Mode = "ShortBreak"
go timer.Start(pomodoroConfig.ShortBreak)
if !waitForTimer(timer) {
break
}
} else { // last phase, prepare for finish
shared.Message.Mode = "LongBreak" shared.Message.Mode = "LongBreak"
go timer.Start(pomodoroConfig.LongBreak) if !startTimer(pomodoroConfig.LongBreak) {
if !waitForTimer(timer) {
break break
} }
} else {
shared.Message.Mode = "ShortBreak"
if !startTimer(pomodoroConfig.ShortBreak) {
break
}
}
shared.Message.Mode = "End" shared.Message.Mode = "End"
}
time.Sleep(time.Second) time.Sleep(time.Second)
}
}
mu.Lock() mu.Lock()
shared.Message.Ongoing = false shared.Message.Ongoing = false
@ -69,8 +53,12 @@ func RunPomodoro() {
shared.Message.TimeLeft = shared.Message.PomodoroSettings.Work shared.Message.TimeLeft = shared.Message.PomodoroSettings.Work
} }
// Stops and resets the running Pomodoro
func ResetPomodoro() { func ResetPomodoro() {
timer.Stop() shared.Message.Mode = "Idle"
shared.Message.Session = 0
shared.Message.TimeLeft = shared.Message.PomodoroSettings.Work
pomodoroResetChannel <- true
} }
func PausePomodoro() { func PausePomodoro() {
@ -78,14 +66,14 @@ func PausePomodoro() {
shared.Message.Paused = true shared.Message.Paused = true
mu.Unlock() mu.Unlock()
timer.Pause() pomodoroPauseChannel <- true
} }
func ResumePomodoro() { func ResumePomodoro() {
mu.Lock() mu.Lock()
shared.Message.Paused = false shared.Message.Paused = false
mu.Unlock() mu.Unlock()
timer.Resume() pomodoroResumeChannel <- true
} }
func IsPomodoroOngoing() bool { func IsPomodoroOngoing() bool {

View file

@ -1,59 +1,32 @@
package pomodoro package pomodoro
import ( import (
"git.smsvc.net/pomodoro/GoTomato/internal/shared"
"time" "time"
) )
type Timer struct { // runs the countdown and updates shared.Message.TimeLeft every second.
TimeLeft chan int // time left func startTimer(remainingSeconds int) bool {
End chan bool // signal on successful end for remainingSeconds > 0 {
Abort chan bool // signal on premature end
stop chan bool
wait chan bool
resume chan bool
}
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),
}
}
func (t *Timer) Start(duration int) {
tick := time.NewTicker(time.Second)
for timeLeft := duration; timeLeft > 0; {
select { select {
case <-t.stop: case <-pomodoroResetChannel:
t.Abort <- true return false
return case <-pomodoroPauseChannel:
case <-t.wait: // Nothing to set here, just waiting for the signal
<-t.resume case <-pomodoroResumeChannel:
continue // Nothing to set here, just waiting for the signal
case <-tick.C:
timeLeft--
default: default:
t.TimeLeft <- timeLeft // Broadcast the current state to all clients
if !IsPomodoroPaused() {
shared.Message.TimeLeft = remainingSeconds
time.Sleep(time.Second)
remainingSeconds--
} }
} }
t.TimeLeft <- 0
t.End <- true
} }
func (t *Timer) Stop() { // Final shared.Message when time reaches zero
t.resume <- true shared.Message.TimeLeft = remainingSeconds
t.stop <- true
}
func (t *Timer) Pause() { return true
t.wait <- true
}
func (t *Timer) Resume() {
t.resume <- true
} }

View file

@ -10,7 +10,6 @@ import (
// sends continous messages to all connected WebSocket clients. // sends continous messages to all connected WebSocket clients.
func SendPermanentBroadCastMessage() { func SendPermanentBroadCastMessage() {
tick := time.NewTicker(time.Second)
for { for {
// Marshal the message into JSON format // Marshal the message into JSON format
jsonMessage, err := json.Marshal(shared.Message) jsonMessage, err := json.Marshal(shared.Message)
@ -26,6 +25,6 @@ func SendPermanentBroadCastMessage() {
// The client is responsible for closing itself on error // The client is responsible for closing itself on error
} }
} }
<-tick.C time.Sleep(time.Second)
} }
} }