Commit
+165 -165 +/-4 browse
1 | diff --git a/runner.go b/runner.go |
2 | new file mode 100644 |
3 | index 0000000..9823484 |
4 | --- /dev/null |
5 | +++ b/runner.go |
6 | @@ -0,0 +1,129 @@ |
7 | + package main |
8 | + |
9 | + import ( |
10 | + "time" |
11 | + ) |
12 | + |
13 | + type TaskRunner struct { |
14 | + count int |
15 | + taskID int |
16 | + taskMessage string |
17 | + nPomodoros int |
18 | + origDuration time.Duration |
19 | + state State |
20 | + store *Store |
21 | + started time.Time |
22 | + pause chan bool |
23 | + toggle chan bool |
24 | + notifier Notifier |
25 | + duration time.Duration |
26 | + } |
27 | + |
28 | + func NewTaskRunner(task *Task, store *Store, notifier Notifier) (*TaskRunner, error) { |
29 | + taskID, err := store.CreateTask(*task) |
30 | + if err != nil { |
31 | + return nil, err |
32 | + } |
33 | + tr := &TaskRunner{ |
34 | + taskID: taskID, |
35 | + taskMessage: task.Message, |
36 | + nPomodoros: task.NPomodoros, |
37 | + origDuration: task.Duration, |
38 | + store: store, |
39 | + state: State(0), |
40 | + pause: make(chan bool), |
41 | + toggle: make(chan bool), |
42 | + notifier: notifier, |
43 | + duration: task.Duration, |
44 | + } |
45 | + return tr, nil |
46 | + } |
47 | + |
48 | + func (t *TaskRunner) Start() { |
49 | + go t.run() |
50 | + } |
51 | + |
52 | + func (t *TaskRunner) TimeRemaining() time.Duration { |
53 | + return (t.duration - time.Since(t.started)).Truncate(time.Second) |
54 | + } |
55 | + |
56 | + func (t *TaskRunner) run() error { |
57 | + for t.count < t.nPomodoros { |
58 | + // Create a new pomodoro where we |
59 | + // track the start / end time of |
60 | + // of this session. |
61 | + pomodoro := &Pomodoro{} |
62 | + // Start this pomodoro |
63 | + pomodoro.Start = time.Now() |
64 | + // Set state to RUNNING |
65 | + t.state = RUNNING |
66 | + // Create a new timer |
67 | + timer := time.NewTimer(t.duration) |
68 | + // Record our started time |
69 | + t.started = pomodoro.Start |
70 | + loop: |
71 | + select { |
72 | + case <-timer.C: |
73 | + t.state = BREAKING |
74 | + t.count++ |
75 | + case <-t.toggle: |
76 | + // Catch any toggles when we |
77 | + // are not expecting them |
78 | + goto loop |
79 | + case <-t.pause: |
80 | + timer.Stop() |
81 | + // Record the remaining time of the current pomodoro |
82 | + remaining := t.TimeRemaining() |
83 | + // Change state to PAUSED |
84 | + t.state = PAUSED |
85 | + // Wait for the user to press [p] |
86 | + <-t.pause |
87 | + // Resume the timer with previous |
88 | + // remaining time |
89 | + timer.Reset(remaining) |
90 | + // Change duration |
91 | + t.started = time.Now() |
92 | + t.duration = remaining |
93 | + // Restore state to RUNNING |
94 | + t.state = RUNNING |
95 | + goto loop |
96 | + } |
97 | + pomodoro.End = time.Now() |
98 | + err := t.store.CreatePomodoro(t.taskID, *pomodoro) |
99 | + if err != nil { |
100 | + return err |
101 | + } |
102 | + // All pomodoros completed |
103 | + if t.count == t.nPomodoros { |
104 | + break |
105 | + } |
106 | + |
107 | + t.notifier.Notify("Pomo", "It is time to take a break!") |
108 | + // Reset the duration incase it |
109 | + // was paused. |
110 | + t.duration = t.origDuration |
111 | + // User concludes the break |
112 | + <-t.toggle |
113 | + |
114 | + } |
115 | + t.notifier.Notify("Pomo", "Pomo session has completed!") |
116 | + t.state = COMPLETE |
117 | + return nil |
118 | + } |
119 | + |
120 | + func (t *TaskRunner) Toggle() { |
121 | + t.toggle <- true |
122 | + } |
123 | + |
124 | + func (t *TaskRunner) Pause() { |
125 | + t.pause <- true |
126 | + } |
127 | + |
128 | + func (t *TaskRunner) Status() *Status { |
129 | + return &Status{ |
130 | + State: t.state, |
131 | + Count: t.count, |
132 | + NPomodoros: t.nPomodoros, |
133 | + Remaining: t.TimeRemaining(), |
134 | + } |
135 | + } |
136 | diff --git a/runner_test.go b/runner_test.go |
137 | new file mode 100644 |
138 | index 0000000..8c35da7 |
139 | --- /dev/null |
140 | +++ b/runner_test.go |
141 | @@ -0,0 +1,36 @@ |
142 | + package main |
143 | + |
144 | + import ( |
145 | + "fmt" |
146 | + "io/ioutil" |
147 | + "testing" |
148 | + "time" |
149 | + ) |
150 | + |
151 | + func TestTaskRunner(t *testing.T) { |
152 | + path, _ := ioutil.TempDir("/tmp", "") |
153 | + store, err := NewStore(path) |
154 | + if err != nil { |
155 | + t.Error(err) |
156 | + } |
157 | + err = initDB(store) |
158 | + if err != nil { |
159 | + t.Error(err) |
160 | + } |
161 | + runner, err := NewTaskRunner(&Task{ |
162 | + Duration: time.Second * 2, |
163 | + NPomodoros: 2, |
164 | + Message: fmt.Sprint("Test Task"), |
165 | + }, store, NoopNotifier{}) |
166 | + if err != nil { |
167 | + t.Error(err) |
168 | + } |
169 | + |
170 | + runner.Start() |
171 | + |
172 | + runner.Toggle() |
173 | + runner.Toggle() |
174 | + |
175 | + runner.Toggle() |
176 | + runner.Toggle() |
177 | + } |
178 | diff --git a/task.go b/task.go |
179 | deleted file mode 100644 |
180 | index 9823484..0000000 |
181 | --- a/task.go |
182 | +++ /dev/null |
183 | @@ -1,129 +0,0 @@ |
184 | - package main |
185 | - |
186 | - import ( |
187 | - "time" |
188 | - ) |
189 | - |
190 | - type TaskRunner struct { |
191 | - count int |
192 | - taskID int |
193 | - taskMessage string |
194 | - nPomodoros int |
195 | - origDuration time.Duration |
196 | - state State |
197 | - store *Store |
198 | - started time.Time |
199 | - pause chan bool |
200 | - toggle chan bool |
201 | - notifier Notifier |
202 | - duration time.Duration |
203 | - } |
204 | - |
205 | - func NewTaskRunner(task *Task, store *Store, notifier Notifier) (*TaskRunner, error) { |
206 | - taskID, err := store.CreateTask(*task) |
207 | - if err != nil { |
208 | - return nil, err |
209 | - } |
210 | - tr := &TaskRunner{ |
211 | - taskID: taskID, |
212 | - taskMessage: task.Message, |
213 | - nPomodoros: task.NPomodoros, |
214 | - origDuration: task.Duration, |
215 | - store: store, |
216 | - state: State(0), |
217 | - pause: make(chan bool), |
218 | - toggle: make(chan bool), |
219 | - notifier: notifier, |
220 | - duration: task.Duration, |
221 | - } |
222 | - return tr, nil |
223 | - } |
224 | - |
225 | - func (t *TaskRunner) Start() { |
226 | - go t.run() |
227 | - } |
228 | - |
229 | - func (t *TaskRunner) TimeRemaining() time.Duration { |
230 | - return (t.duration - time.Since(t.started)).Truncate(time.Second) |
231 | - } |
232 | - |
233 | - func (t *TaskRunner) run() error { |
234 | - for t.count < t.nPomodoros { |
235 | - // Create a new pomodoro where we |
236 | - // track the start / end time of |
237 | - // of this session. |
238 | - pomodoro := &Pomodoro{} |
239 | - // Start this pomodoro |
240 | - pomodoro.Start = time.Now() |
241 | - // Set state to RUNNING |
242 | - t.state = RUNNING |
243 | - // Create a new timer |
244 | - timer := time.NewTimer(t.duration) |
245 | - // Record our started time |
246 | - t.started = pomodoro.Start |
247 | - loop: |
248 | - select { |
249 | - case <-timer.C: |
250 | - t.state = BREAKING |
251 | - t.count++ |
252 | - case <-t.toggle: |
253 | - // Catch any toggles when we |
254 | - // are not expecting them |
255 | - goto loop |
256 | - case <-t.pause: |
257 | - timer.Stop() |
258 | - // Record the remaining time of the current pomodoro |
259 | - remaining := t.TimeRemaining() |
260 | - // Change state to PAUSED |
261 | - t.state = PAUSED |
262 | - // Wait for the user to press [p] |
263 | - <-t.pause |
264 | - // Resume the timer with previous |
265 | - // remaining time |
266 | - timer.Reset(remaining) |
267 | - // Change duration |
268 | - t.started = time.Now() |
269 | - t.duration = remaining |
270 | - // Restore state to RUNNING |
271 | - t.state = RUNNING |
272 | - goto loop |
273 | - } |
274 | - pomodoro.End = time.Now() |
275 | - err := t.store.CreatePomodoro(t.taskID, *pomodoro) |
276 | - if err != nil { |
277 | - return err |
278 | - } |
279 | - // All pomodoros completed |
280 | - if t.count == t.nPomodoros { |
281 | - break |
282 | - } |
283 | - |
284 | - t.notifier.Notify("Pomo", "It is time to take a break!") |
285 | - // Reset the duration incase it |
286 | - // was paused. |
287 | - t.duration = t.origDuration |
288 | - // User concludes the break |
289 | - <-t.toggle |
290 | - |
291 | - } |
292 | - t.notifier.Notify("Pomo", "Pomo session has completed!") |
293 | - t.state = COMPLETE |
294 | - return nil |
295 | - } |
296 | - |
297 | - func (t *TaskRunner) Toggle() { |
298 | - t.toggle <- true |
299 | - } |
300 | - |
301 | - func (t *TaskRunner) Pause() { |
302 | - t.pause <- true |
303 | - } |
304 | - |
305 | - func (t *TaskRunner) Status() *Status { |
306 | - return &Status{ |
307 | - State: t.state, |
308 | - Count: t.count, |
309 | - NPomodoros: t.nPomodoros, |
310 | - Remaining: t.TimeRemaining(), |
311 | - } |
312 | - } |
313 | diff --git a/task_test.go b/task_test.go |
314 | deleted file mode 100644 |
315 | index 8c35da7..0000000 |
316 | --- a/task_test.go |
317 | +++ /dev/null |
318 | @@ -1,36 +0,0 @@ |
319 | - package main |
320 | - |
321 | - import ( |
322 | - "fmt" |
323 | - "io/ioutil" |
324 | - "testing" |
325 | - "time" |
326 | - ) |
327 | - |
328 | - func TestTaskRunner(t *testing.T) { |
329 | - path, _ := ioutil.TempDir("/tmp", "") |
330 | - store, err := NewStore(path) |
331 | - if err != nil { |
332 | - t.Error(err) |
333 | - } |
334 | - err = initDB(store) |
335 | - if err != nil { |
336 | - t.Error(err) |
337 | - } |
338 | - runner, err := NewTaskRunner(&Task{ |
339 | - Duration: time.Second * 2, |
340 | - NPomodoros: 2, |
341 | - Message: fmt.Sprint("Test Task"), |
342 | - }, store, NoopNotifier{}) |
343 | - if err != nil { |
344 | - t.Error(err) |
345 | - } |
346 | - |
347 | - runner.Start() |
348 | - |
349 | - runner.Toggle() |
350 | - runner.Toggle() |
351 | - |
352 | - runner.Toggle() |
353 | - runner.Toggle() |
354 | - } |