| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- #ifndef __TIMER_H__
- #define __TIMER_H__
- #include "basic/basic.h"
- #include <functional>
- class Timer
- {
- public:
- ~Timer() { Stop(); }
- // interval 为 0 表示时刻执行
- template<typename Func>
- void Start(int fps, Func&& func)
- {
- static_assert(std::is_convertible_v<Func, std::function<void()>>,
- "func need to be std::function<void()>");
- _fps = fps;
- _tickCnt = 0;
- _isOverload = false;
- if (_isRunning) {
- // Already running, ignore Start call
- return;
- }
- using namespace std::chrono;
- _isRunning = true;
- _beginTime = high_resolution_clock::now();
- if (_fps > 0) {
- auto task = [this, func = std::forward<Func>(func)]() mutable {
- while (_isRunning) {
- // 这里不能直接使用整数除法
- // 因为整数除法有截断,导致最终睡眠的时间少一些
- uint64_t goalTime = int((double(1000.0) / _fps * _tickCnt) + 0.5);
- ++_tickCnt;
- auto nowTime = high_resolution_clock::now();
- auto duration = duration_cast<milliseconds>(nowTime - _beginTime).count();
- int64_t sleepTime = goalTime - duration;
- if (sleepTime > 0) {
- SleepMs(sleepTime);
- }
- #ifdef __AVDEBUG
- // else if (sleepTime < 0) {
- // printf("Time out : %lld\n", -sleepTime);
- // }
- #endif
- _isOverload = -sleepTime > 1000; // 捕获的过载时间设置为 1s
- func();
- }
- };
- _thread = new std::thread(std::move(task));
- // timeBeginPeriod(1);
- return;
- }
- auto task = [this, func = std::forward<Func>(func)]() mutable {
- while (_isRunning) {
- func();
- }
- };
- _thread = new std::thread(std::move(task));
- }
- void Stop()
- {
- _isRunning = false;
- if (_thread == nullptr) {
- return;
- }
- // if (_fps > 0) {
- // timeEndPeriod(1);
- // }
- _thread->join();
- delete _thread;
- _thread = nullptr;
- }
- bool IsOverload() const { return _isOverload; }
- private:
- int _fps = 100;
- int _isRunning = false;
- int _isOverload = false;
- std::vector<int> vec;
- std::chrono::time_point<std::chrono::high_resolution_clock> _beginTime;
- std::thread* _thread = nullptr;
- uint64_t _tickCnt = 0;
- };
- #endif
|