recator: use timer signals instead of shared.Message.TimeLeft
- remove shared.Message.TimeLeft - modify Timer struct - add TimeLeft signal - add End and Abort signals - add syncronised ticker - update RunPomodoro to use goroutines for timer starts - add waitForTimer function
This commit is contained in:
parent
aa5c24f06d
commit
3eae584d6d
2 changed files with 44 additions and 22 deletions
|
@ -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"
|
||||
|
|
|
@ -1,47 +1,53 @@
|
|||
package pomodoro
|
||||
|
||||
import (
|
||||
"git.smsvc.net/pomodoro/GoTomato/internal/shared"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Timer struct {
|
||||
abort 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),
|
||||
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() {
|
||||
|
|
Loading…
Reference in a new issue