pominal/pominal.go
Dan Anglin f0b46ed8b7
refactor: code refactoring to improve stability.
This commit removes the need to calculate the time remaining in a
session and instead introduces a countdown counter which decrements at
each one second 'tick'. This stabilizes the interface where it appeared
that he timer was randomly pausing or skipping time.

A summary of changes made in this commit includes:

- Updated the command line flags so that they are easier to remember.
- The work, short break and long break session times are now parsed and
converted to type float64. These times represent the total amount of
seconds.
- Removal of timer and finish from Pominal.
- The method that calculates the time remaining is removed.
- A countdown counter is added to the Pominal type.
- Updated alert message for the desktop notification.
- Simplified the Run method by moving the logic to chosse the next session
in a separate method.
2019-09-18 09:08:12 +01:00

135 lines
3.2 KiB
Go

/*
Pominal
Copyright (C) 2019 Daniel Anglin
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
"time"
)
type Pominal struct {
// workSession is a counter for work sessions.
workSession int
// maxWorkSessions sets the number of work sessions to complete
// before running the countdown timer for each long break.
maxWorkSessions int
// cycle represents a Pominal cycle. A Pominal cycle increments after
// every long break.
cycle int
// countdown is the decrementing counter for Pominal.
countdown float64
// work is the time (represented in seconds) for the work sessions.
work float64
// shortBreak is the time (represented in seconds) for the short break sessions.
shortBreak float64
// longBreak is the time (represented in seconds) for the long break sessions.
longBreak float64
// label labels Pominal based on the session.
label string
}
// NewPominal creates a new pominal instance
func NewPominal(w, s, l float64, m int) Pominal {
return Pominal{
workSession: 1,
maxWorkSessions: m,
cycle: 1,
work: w,
shortBreak: s,
longBreak: l,
}
}
// Run Pominal
func (p *Pominal) Run() {
s := make(chan os.Signal, 1)
signal.Notify(s, syscall.SIGINT, syscall.SIGTERM)
p.UpdateSession()
t := time.NewTicker(1 * time.Second)
infinite:
for {
select {
case sig := <-s:
fmt.Printf("\n\nReceived signal '%s'. Closing Pominal.\n", sig)
t.Stop()
break infinite
case <-t.C:
p.countdown--
if p.countdown < 0 {
fmt.Printf("\n%s session has finished.\n", p.label)
t.Stop()
p.UpdateSession()
time.Sleep(1 * time.Second)
t = time.NewTicker(1 * time.Second)
} else {
printScreen(p.countdown,
p.cycle,
p.workSession,
p.maxWorkSessions,
p.label,
)
}
}
}
}
// UpdateSession resets Pominal's countdown
// based on the next session. If a 'short break'
// session is over the work session counter is incremented.
// If a 'long break' session is over then the Pominal cycle
// is incremented and the work session counter is reset
// to 1.
func (p *Pominal) UpdateSession() {
switch p.label {
case workTimerLabel:
if p.workSession >= p.maxWorkSessions {
p.countdown = p.longBreak
p.label = longBreakTimerLabel
} else {
p.countdown = p.shortBreak
p.label = shortBreakTimerLabel
}
case shortBreakTimerLabel:
p.workSession++
p.countdown = p.work
p.label = workTimerLabel
case longBreakTimerLabel:
p.cycle++
p.workSession = 1
p.countdown = p.work
p.label = workTimerLabel
default:
p.countdown = p.work
p.label = workTimerLabel
}
alert(p.label)
}