diff options
Diffstat (limited to 'timer.c')
| -rw-r--r-- | timer.c | 95 |
1 files changed, 95 insertions, 0 deletions
@@ -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); + } + } +} |
