VTrain/tools/rtsp_server/net/Timer.h

114 lines
2.0 KiB
C++

// PHZ
// 2018-5-15
#ifndef _XOP_TIMER_H
#define _XOP_TIMER_H
#include <map>
#include <unordered_map>
#include <chrono>
#include <functional>
#include <cstdint>
#include <chrono>
#include <memory>
#include <mutex>
#include <thread>
namespace xop
{
typedef std::function<bool(void)> TimerEvent;
typedef uint32_t TimerId;
class Timer
{
public:
Timer(const TimerEvent& event, uint32_t msec)
: event_callback_(event)
, interval_(msec)
{
if (interval_ == 0) {
interval_ = 1;
}
}
static void Sleep(uint32_t msec)
{
std::this_thread::sleep_for(std::chrono::milliseconds(msec));
}
void SetEventCallback(const TimerEvent& event)
{
event_callback_ = event;
}
void Start(int64_t microseconds, bool repeat = false)
{
is_repeat_ = repeat;
auto time_begin = std::chrono::high_resolution_clock::now();
int64_t elapsed = 0;
do
{
std::this_thread::sleep_for(std::chrono::microseconds(microseconds - elapsed));
time_begin = std::chrono::high_resolution_clock::now();
if (event_callback_) {
event_callback_();
}
elapsed = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - time_begin).count();
if (elapsed < 0) {
elapsed = 0;
}
} while (is_repeat_);
}
void Stop()
{
is_repeat_ = false;
}
private:
friend class TimerQueue;
void SetNextTimeout(int64_t time_point)
{
next_timeout_ = time_point + interval_;
}
int64_t getNextTimeout() const
{
return next_timeout_;
}
bool is_repeat_ = false;
TimerEvent event_callback_ = [] { return false; };
uint32_t interval_ = 0;
int64_t next_timeout_ = 0;
};
class TimerQueue
{
public:
TimerId AddTimer(const TimerEvent& event, uint32_t msec);
void RemoveTimer(TimerId timerId);
int64_t GetTimeRemaining();
void HandleTimerEvent();
private:
int64_t GetTimeNow();
std::mutex mutex_;
std::unordered_map<TimerId, std::shared_ptr<Timer>> timers_;
std::map<std::pair<int64_t, TimerId>, std::shared_ptr<Timer>> events_;
uint32_t last_timer_id_ = 0;
};
}
#endif