Lua и расписание
Напомню, что в предыдущих частях мы построили приложение, способное отсчитывать временные интервалы и оповещать пользователя в нужный момент. Ясно, что параметров, на которые пользователь хотел бы влиять, довольно много. Это значки и текст в оповещении, распределение времени, учет повторяющихся временных блоков и т.д.. Кроме того, хотелось бы иметь возможность вести статистику и менять формат её ведения при желании. В таких условиях целесообразно возложить задачу настройки и построения сценария работы на внешний скрипт. Для этого будем использовать lua.
О Lua
Так как наше приложение написано на C++, а библиотека lua рассчитана на работу с языком C, следует скачать и добавить в проект файл luawrapper.hpp. Делается это для того, чтобы создать прототипы функций и структур приложения для скриптов lua.
Makefile
TARGET = mySchedule
CC = g++
LIBS = -lnotify -llua5.1
CFLAGS = -std=c++11 `pkg-config gtk+-2.0 --cflags`
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}
По сравнению с предыдущей версией makefile-а, добавилась запись -llua5.1. Версия данной библиотеки может отличаться, но во многих репозиториях она присутствует. В переменной TARGET можно указать любое имя, которое вы хотите дать приложению.
Расписание и временные промежутки
Отрезок времени можно описать по разному. В системах на подобие pomodoro не столь важно — когда мы начали работу и когда закончили, а сколько времени было потрачено. Поэтому главной характеристикой временного промежутка будет его длительность. Также важно каким-то образом реагировать на окончание временного промежутка и его начало. Кроме того, полезно дать промежутку определенное имя («Работа», «Перерыв», «Большой перерыв» и т.д.). Собственно, на этом описание можно завершить.
struct TimeStamp {
char* name;
char* onStart;
char* onEnd;
double duration;
};
Здесь duration — длительность в секундах (доли секунд тоже учитываются, поэтому тип — double). name — имя интервала. onStart и onEnd — имена функций в скрипте lua, которые будут вызваны в начале и конце временного промежутка соответственно.
Мы предполагаем, что каждый интервал является частью некоторой схемы или расписания. «Работа» — 25 минут, затем «Перерыв» — 5 минут и т.д.. Следовательно, расписание (схема) — это упорядоченный набор временных интервалов. Схема тоже может иметь своё имя. Например, «Усиленный режим работы» или «Стандартный режим».
struct TimeScheme {
char* name;
std::vector<TimeStamp> st;
};
Что должен уметь скрипт?
- Создавать схему
- Добавлять в схему (или расписание) временной промежуток
- Выводить оповещение с нужным текстом и иконкой
- Воспроизводить схему
- Использовать диалоговое сообщение о продолжении или окончании работы
Как мы знаем из предыдущей статьи, систему оповещения notify нужно инициализировать перед использованием. Для этого, как и для действий, указанных выше, следует определить функцию. К тому же, в ходе инициализации можно указать имя приложения.
Определим функцию инициализации в основном исходнике:
void initNotify(const char* nname) {
notify_init(nname);
hNotification = notify_notification_new("", "", "dialog-information");
notify_notification_set_timeout(hNotification, 1);
};
nname в данном случае — имя приложения (или группы оповещений). На данном этапе не важно — какие параметры мы передаем в функцию notify_notification_new, так как при каждом показе оповещения они будут меняться.
А теперь создадим соответствующий прототип функции initNotify для lua. Определим функцию в коде приложения, которую будет вызывать скрипт:
static int l_initNotify(lua_State* L) {
const char* name = lua_tostring(L, 1);
initNotify(name);
return 0;
};
В первую очередь мы получаем первый аргумент, переданный из скрипта (считая, что это строка), затем вызываем нашу основную функцию с этим же аргументом. Параметр 0 — это количество возвращаемых в скрипт значений.
Последний этап — регистрация прототипа:
lua_pushcfunction(L, l_initNotify);
lua_setglobal(L, "initNotify");
Таким образом, если в скрипте встретиться функция с именем «initNotify«, lua вызовет соответствующую C-функцию.
Итоги
Все остальные функции из списка выше «экспортированы» в lua аналогичным образом. Кроме того, я посчитал целесообразным добавить функции воспроизведения звука на основе OpenAL. С примером программы и соответствующим скриптом можно ознакомиться здесь.
Добавить комментарий