Pomodoro и chrono. Часть 1
Вопрос управления временем так или иначе волнует каждого работающего человека. Многие знакомы с методом помидора. Если коротко, его суть заключается в специфическом чередовании фиксированных периодов работы и отдыха с учетом отвлекающих факторов. Существует множество приложений, реализующих данную систему. В качестве своеобразного упражнения построим собственное приложение для управления временем.
Задача
Для начала создадим консольное приложение, которое способно с удовлетворительной точностью отсчитывать временные интервалы.
В ранее опубликованной статье для этой задачи использовалась функция time() из ctime. Но так как данная функция может вести себя по разному в зависимости от операционной системы, рекомендуется использовать chrono (для C++). На данной библиотеке и остановимся.
Существует хороший ресурс — https://pomodoro-tracker.com. Всё, что нужно для учета времени по системе pomodoro, там есть. В частности по умолчанию используется схема 25 5 15 4. Это значит, что период работы — 25 минут, перерыв — 5 минут, а после 4-х «помидоров» ( 25 — 5 ) будет «помидор» с перерывом в 15 минут (25 — 15).
Данную схему мы реализуем в своем первом приложении.
Makefile
Назовем программу myPomodoro, в качестве компилятора используем g++, основной исходник — main.cpp.
TARGET = myPomodoro
CC = g++
LIBS =
CFLAGS = -std=c++11
OBJ = main.o
app: ${OBJ}
${CC} ${CFLAGS} ${OBJ} ${LIBS} -o ${TARGET}
main.o: main.cpp
${CC} ${CFLAGS} -c main.cpp
clean:
rm -rf *.o ${TARGET}
«Пустые» переменные нам понадобятся в дальнейшем.
chrono
Для замеров временных промежутков нам нужно знать следующее: состояние таймера в начале отсчета, текущее состояние таймера. Далее остается сравнить количество прошедшего времени с целевым временным интервалом.
Таким образом, используем следующие переменные:
high_resolution_clock::time_point t1;
high_resolution_clock::time_point t2;
Получение текущего момента времени:
t1 = high_resolution_clock::now();
Расчет временного промежутка:
t2 = high_resolution_clock::now();
duration<double> timeSpan = duration_cast<duration<double>>(t2 - t1);
double d = timeSpan.count();
С данного момента в переменной d будет храниться длительность временного интервала в секундах.
Ещё одна необходимая деталь — пауза в 1 секунду:
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
Далее остается организовать переключение интервалов «работа-отдых».
main.cpp
#include <iostream>
#include <chrono>
#include <stdio.h>
#include <thread>
using namespace std;
using namespace std::chrono;
int main(int argc, char* argv[]) {
high_resolution_clock::time_point t1;
high_resolution_clock::time_point t2;
double intervals[] = {25*60, 5*60, 15*60};
const char* names[] = {"Working", "Break", "Long break"};
char buf[10] = {0};
int curInt = 0;
int count = 4;
bool timerOn = false;
while(true) {
if(timerOn) {
t2 = high_resolution_clock::now();
duration<double> timeSpan = duration_cast<duration<double>>(t2 - t1);
double d = timeSpan.count();
int timeLeft = (int)(intervals[curInt] - d);
printf("\r%02d:%02d %s ", timeLeft/60, timeLeft % 60, names[curInt]);
fflush(stdout);
if(d >= intervals[curInt]) {
timerOn = false;
curInt++;
} else
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
} else {
if(curInt == 1) {
if(count <= 0) {
curInt = 2;
count = 4;
};
} else if(curInt == 2 || curInt == 3) {
while(buf[0] != 'n' && buf[0] != 'y') {
printf(" \r");
printf("Start work? [y/n]");
scanf("%9s", buf);
};
if(buf[0] == 'n') break;
buf[0] = 0;
curInt = 0;
count--;
};
t1 = high_resolution_clock::now();
timerOn = true;
};
};
return 0;
};
Заключение
Среди недостатков программы следует отметить отсутствие оповещения пользователя о начале и окончании временного интервала. Но об этом в следующей части.
Добавить комментарий