-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstate_manager.go
128 lines (106 loc) · 2.4 KB
/
state_manager.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package main
import (
"log/slog"
"time"
"github.com/arevbond/PomoTrack/config"
)
type TimerState int
const (
StatePaused TimerState = iota
StateActive
StateFinished
)
type StateManager struct {
currentState TimerState
focusTimer *Timer
breakTimer *Timer
stateChan chan StateEvent
logger *slog.Logger
timerConfig config.TimerConfig
taskManager taskManager
}
func NewStateManager(l *slog.Logger, focusT *Timer, breakT *Timer,
stateChan chan StateEvent, cfg config.TimerConfig, manager taskManager) *StateManager {
return &StateManager{
logger: l,
currentState: StatePaused,
focusTimer: focusT,
breakTimer: breakT,
stateChan: stateChan,
timerConfig: cfg,
taskManager: manager,
}
}
func (sm *StateManager) CurrentState() TimerState {
return sm.currentState
}
func (sm *StateManager) SetState(state TimerState, timerType TimerType) {
if sm.currentState == state {
return
}
sm.currentState = state
event := StateEvent{
TimerType: timerType,
NewState: state,
}
sm.stateChan <- event
timer := sm.getTimer(timerType)
if nil == timer {
return
}
switch state {
case StateActive:
sm.startTimer(timer)
case StatePaused:
sm.pauseTimer(timer)
case StateFinished:
if timerType == FocusTimer {
sm.completePomodoro()
}
sm.finishTimer(timer)
}
}
func (sm *StateManager) completePomodoro() {
err := sm.taskManager.IncPomodoroActiveTask()
if err != nil {
sm.logger.Error("can't increment pomodoro in active task", slog.Any("error", err))
}
}
func (sm *StateManager) pauseTimer(timer *Timer) {
timer.Stop()
}
func (sm *StateManager) startTimer(timer *Timer) {
finishChan := timer.Run()
go func() {
_, ok := <-finishChan
if ok {
sm.SetState(StateFinished, timer.timerType)
}
}()
}
func (sm *StateManager) finishTimer(timer *Timer) {
timer.Stop()
var duration time.Duration
switch timer.timerType {
case FocusTimer:
duration = sm.timerConfig.FocusDuration
case BreakTimer:
duration = sm.timerConfig.BreakDuration
}
timer.Reset(duration)
}
func (sm *StateManager) getTimer(timerType TimerType) *Timer {
switch timerType {
case FocusTimer:
return sm.focusTimer
case BreakTimer:
return sm.breakTimer
}
return nil
}
func (sm *StateManager) timeToFinish(timerType TimerType) time.Duration {
return sm.getTimer(timerType).timeToFinish
}
func (sm *StateManager) IsFocusTimeHidden() bool {
return sm.timerConfig.HiddenFocusTime
}