summaryrefslogtreecommitdiff
path: root/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'timer.c')
-rw-r--r--timer.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/timer.c b/timer.c
new file mode 100644
index 0000000..58757d7
--- /dev/null
+++ b/timer.c
@@ -0,0 +1,95 @@
+#include "timer.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/timerfd.h>
+#include <sys/eventfd.h>
+#include <poll.h>
+
+void timer_init(Timer *t, size_t sec) {
+ assert(t != NULL);
+ t->seconds = sec;
+ t->remaining_seconds = sec;
+ t->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
+ if(t->timerfd == -1) {
+ fprintf(stdout, "Error: timerfd could not be created!");
+ exit(1);
+ }
+}
+
+void timer_reset(Timer *t) {
+ assert(t != NULL);
+ struct itimerspec spec = {0};
+ timerfd_settime(t->timerfd, 0, &spec, NULL);
+ t->remaining_seconds = t->seconds;
+ size_t mins = t->remaining_seconds / 60;
+ size_t secs = t->remaining_seconds % 60;
+ fprintf(stdout, "{\"text\": \"Paused %02d:%02d\"}\n", mins, secs);
+ fflush(stdout);
+}
+
+void timer_start(Timer *t) {
+ assert(t != NULL);
+ t->status = T_RUNNING;
+ struct itimerspec spec;
+ spec.it_interval.tv_sec = 1;
+ spec.it_interval.tv_nsec = 0;
+ spec.it_value.tv_sec = 1;
+ spec.it_value.tv_nsec = 0;
+ timerfd_settime(t->timerfd, 0, &spec, NULL);
+}
+
+void timer_stop(Timer *t) {
+ assert(t != NULL);
+ t->status = T_STOPPED;
+ struct itimerspec spec = {0};
+ timerfd_settime(t->timerfd, 0, &spec, NULL);
+}
+
+void timer_toggle_state(Timer *t) {
+ assert(t != NULL);
+ if(t->status == T_RUNNING)
+ timer_stop(t);
+ else if (t->status == T_STOPPED)
+ timer_start(t);
+}
+
+void timer_loop(Timer *t) { // May drift by a couple mili-seconds. However, just a pomodoro app, so that is not important.
+ assert(t != NULL);
+
+ t->remaining_seconds = t->seconds;
+ size_t mins = t->remaining_seconds / 60;
+ size_t secs = t->remaining_seconds % 60;
+ fprintf(stdout, "{\"text\": \"Paused %02d:%02d\"}\n", mins, secs);
+ fflush(stdout);
+
+ struct pollfd fds;
+ fds.fd = t->timerfd;
+ fds.events = POLLIN;
+
+ while (1) {
+ if(poll(&fds, 1, -1) == -1) {
+ printf("Failed to poll events!");
+ exit(1);
+ }
+
+ if(fds.revents & POLLIN) {
+ uint64_t tick;
+ read(t->timerfd, &tick, sizeof(tick));
+ if(t->remaining_seconds == 0) {
+ fprintf(stdout,"{\"text\": \"Completed\"}\n");
+ uint64_t buf;
+ timer_stop(t);
+ } else {
+ t->remaining_seconds--;
+ size_t mins = t->remaining_seconds / 60;
+ size_t secs = t->remaining_seconds % 60;
+ fprintf(stdout,"{\"text\": \"Work %02d:%02d\"}\n", mins, secs);
+ }
+ fflush(stdout);
+ }
+ }
+}