Files
pip/libs/main/thread/pitimer.h
peri4 e6c8714857 version 4.1.0
maybe fix hang on PIEthernet::interrupt()
replace piLetobe with piChangeEndian:
 * piChangeEndianBinary
 * piChangeBinary
 * piChangedBinary
PIDiagnostics::start now accept PISystemTime instead of number
add PITimer::start(PISystemTime, std::function<void()>) overload
2024-08-28 11:56:36 +03:00

214 lines
7.4 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*! \file pitimer.h
* \ingroup Thread
* \~\brief
* \~english Timer
* \~russian Таймер
*/
/*
PIP - Platform Independent Primitives
Timer
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PITIMER_H
#define PITIMER_H
#include "piconditionvar.h"
#include "piobject.h"
#include "pisystemtime.h"
class PIThread;
class PIP_EXPORT PITimer: public PIObject {
PIOBJECT_SUBCLASS(PITimer, PIObject);
public:
NO_COPY_CLASS(PITimer);
//! \~english Constructs timer
//! \~russian Создает таймер
explicit PITimer();
//! \~english Constructs timer with method void(int)
//! \~russian Создает таймер с функцией void(int)
explicit PITimer(std::function<void(int)> func);
//! \~english Constructs timer with method void()
//! \~russian Создает таймер с функцией void()
explicit PITimer(std::function<void()> func);
virtual ~PITimer();
//! \~english Returns timer loop delay
//! \~russian Возвращает задержку цикла таймера
PISystemTime interval() const;
//! \~english Set timer loop delay
//! \~russian Установить интервал таймера
void setInterval(PISystemTime interval);
//! \~english Returns if timer is started
//! \~russian Возвращает работает ли таймер
bool isRunning() const;
//! \~english Return if timer is stopping
//! \~russian Возвращает останавливается ли таймер
bool isStopping() const;
//! \~english Wait for timer stop
//! \~russian Ожидает остановки таймера
bool waitForFinish(PISystemTime timeout = {});
//! \~english Start timer with "interval" loop delay
//! \~russian Запустить таймер с интервалом "interval"
bool start(PISystemTime interval);
//! \~english Start timer with "interval" loop delay and tick function "func"
//! \~russian Запустить таймер с интервалом "interval" и вызываевымым методом "func"
bool start(PISystemTime interval, std::function<void()> func);
bool start(double interval_ms) DEPRECATEDM("use start(PISystemTime)") { return start(PISystemTime::fromMilliseconds(interval_ms)); }
EVENT_HANDLER0(bool, start);
EVENT_HANDLER0(bool, restart);
EVENT_HANDLER0(void, stop);
//! \~english Stop timer and wait for finish.
//! \~russian Останавливает таймер и ожидает завершения.
void stopAndWait(int timeout_ms) { stopAndWait(PISystemTime::fromMilliseconds(timeout_ms)); }
//! \~english Stop timer and wait for finish.
//! \~russian Останавливает таймер и ожидает завершения.
void stopAndWait(PISystemTime timeout = {});
//! \~english Set timer tick function
//! \~russian Установить вызываемый метод
void setSlot(std::function<void()> func) {
ret_func = [func](int) { func(); };
}
//! \~english Set timer tick function
//! \~russian Установить вызываемый метод
void setSlot(std::function<void(int)> func) { ret_func = func; }
void needLockRun(bool need) { lockRun = need; }
EVENT_HANDLER0(void, lock) { mutex_.lock(); }
EVENT_HANDLER0(void, unlock) { mutex_.unlock(); }
//! \~english Returns if timer should exec \a maybeCallQueuedEvents() at every tick. By default \b true
//! \~russian Возвращает должен ли таймер вызывать \a maybeCallQueuedEvents() каждый тик. По умолчанию \b true
bool isCallQueuedEvents() const { return callEvents; }
//! \~english Set timer exec \a maybeCallQueuedEvents() at every tick
//! \~russian Установает должен ли таймер вызывать \a maybeCallQueuedEvents() каждый тик
void setCallQueuedEvents(bool yes) { callEvents = yes; }
//! \~english Add frequency delimiter "delim" with optional delimiter slot "slot"
//! \~russian Добавляет делитель частоты "delim" с необязательным методом "slot"
void addDelimiter(int delim, std::function<void(int)> func = nullptr);
//! \~english Add frequency delimiter "delim" with optional delimiter slot "slot"
//! \~russian Добавляет делитель частоты "delim" с необязательным методом "slot"
void addDelimiter(int delim, std::function<void()> func);
//! \~english Add frequency delimiter "delim" with optional delimiter slot "slot"
//! \~russian Добавляет делитель частоты "delim" с необязательным методом "slot"
void addDelimiter(int delim, std::function<void(void *)> slot);
//! \~english Remove all frequency delimiters "delim"
//! \~russian Удаляет все делители частоты "delim"
void removeDelimiter(int delim);
EVENT_HANDLER0(void, clearDelimiters) { delims.clear(); }
EVENT1(tickEvent, int, delimiter);
//! \handlers
//! \{
//! \fn bool start()
//! \brief
//! \~english Start timer with \a interval() loop delay
//! \~russian Запустить таймер с интервалом \a interval()
//! \fn bool restart()
//! \brief
//! \~english Stop and start timer with \a interval() loop delay
//! \~russian Остановить и запустить таймер с интервалом \a interval()
//! \fn bool stop()
//! \brief
//! \~english Stop timer (don`t wait for finish)
//! \~russian Остановить таймер (не дожидается остановки)
//! \fn void clearDelimiters()
//! \brief
//! \~english Remove all frequency delimiters
//! \~russian Удаляет все делители частоты
//! \}
//! \events
//! \{
//! \fn void tickEvent(int delimiter)
//! \brief
//! \~english Raise on timer tick
//! \~russian Вызывается каждый тик таймера
//! \~\details
//! \~english
//! "delimiter" is frequency delimiter, 1 for main loop.
//! \~russian
//! "delimiter" - делитель частоты, 1 для основного цикла
//! \}
protected:
struct PIP_EXPORT Delimiter {
Delimiter(std::function<void(int)> func_ = nullptr, int delim_ = 1) {
func = func_;
delim = delim_;
}
std::function<void(int)> func;
int delim = 0;
int tick = 0;
};
void initFirst();
void init() const;
void threadFunc();
void adjustTimes();
void execTick();
//! Timer execution function, similar to "slot" or event \a timeout(). By default does nothing
virtual void tick(int delimiter) {}
PIThread * thread = nullptr;
std::atomic_bool lockRun = {false}, callEvents = {true};
PIMutex mutex_;
PISystemTime m_interval, m_interval_x5;
PISystemTime m_time_next;
std::function<void(int)> ret_func = nullptr;
PIVector<Delimiter> delims;
PIConditionVariable event;
};
#endif // PITIMER_H