// // Created by YY on 2021/3/16. // #include "apptimer.h" #include "../jni_log.h" #include #include #include #include #include #include #include #include #include #include #include #define DEBUG(fmt, args...) LOGD(" <%s>: " fmt, __func__, ##args) std::mutex mtx; std::map TimerList; static void RemoveTimerList(const CTimer *p); CTimer::CTimer() { flag = 0; var.var_ptr = nullptr; var.var1 = var.var2 = var.var_length = 0; pthread = nullptr; } CTimer::~CTimer() { if (pthread != nullptr) { delete pthread; } if (var.var_ptr != nullptr) { delete var.var_ptr; } } bool CTimer::_updateStatus(CTimer *timer) { if (timer->flag == 0) { return false; } else { return true; //cancel } } void CTimer::_do_task_func(uint32_t msec, CTimer *timer, std::function callback) { std::unique_lock lk(timer->cv_mtx); auto now = std::chrono::steady_clock::now(); if (timer->cv.wait_until(lk, now + std::chrono::milliseconds(msec), std::bind(_updateStatus, timer)) == false) { RemoveTimerList(timer); // 从列表中删除索引 if (timer->flag == 0) { callback(timer->var); } } else { // LOGD("Cancel %d", static_cast(timer->flag)); RemoveTimerList(timer); } //delete timer; lk.unlock(); std::thread(clear, timer).detach(); } void CTimer::copy(int value1, int value2, const void *data, int length) { this->var.var1 = value1; this->var.var2 = value2; this->var.var_length = length; if (length > 0 && data != nullptr) { this->var.var_ptr = new uint8_t[length]; memcpy(this->var.var_ptr, data, length); } else { this->var.var_ptr = nullptr; } } void CTimer::clear(CTimer *timer) { if (timer != nullptr) { delete timer; } } bool CTimer::start(uint32_t msec, std::function callback) { if (pthread == nullptr) { try { pthread = new std::thread(_do_task_func, msec, this, callback); pthread->detach(); } catch (std::exception &ex) { DEBUG("%s", ex.what()); return false; } // this->callbackThread = std::thread(_do_task_func, msec, this, callback); // this->callbackThread.detach(); } return true; } void CTimer::stop() { std::unique_lock lk(this->cv_mtx); this->flag = 1; this->cv.notify_one(); } void AppTimer_init(void) { TimerList.clear(); } void AppTimer_add(void(*cb)(apptimer_var_t), uint32_t msec) { CTimer *cTimer = new CTimer(); cTimer->copy(0, 0, nullptr, 0); std::lock_guard lock(mtx); TimerList.insert(std::pair(cb, cTimer)); if (cTimer->start(msec, cb) == false) { auto it = TimerList.find(cb); if (it != TimerList.end()) { CTimer *ptr = it->second; TimerList.erase(it); } delete cTimer; } } void AppTimer_add(void(*cb)(apptimer_var_t), uint32_t msec, int value1, int value2) { CTimer *cTimer = new CTimer(); cTimer->copy(value1, value2, nullptr, 0); std::lock_guard lock(mtx); TimerList.insert(std::pair(cb, cTimer)); if (cTimer->start(msec, cb) == false) { LOGD("建立失败"); auto it = TimerList.find(cb); if (it != TimerList.end()) { CTimer *ptr = it->second; TimerList.erase(it); } delete cTimer; } } void AppTimer_add(void(*cb)(apptimer_var_t), uint32_t msec, void *data, int lenght) { CTimer *cTimer = new CTimer(); cTimer->copy(0, 0, data, lenght); std::lock_guard lock(mtx); TimerList.insert(std::pair(cb, cTimer)); if (cTimer->start(msec, cb) == false) { auto it = TimerList.find(cb); if (it != TimerList.end()) { CTimer *ptr = it->second; TimerList.erase(it); } delete cTimer; } } void AppTimer_delete(void(*cb)(apptimer_var_t)) { std::lock_guard lock(mtx); auto it = TimerList.find(cb); if (it != TimerList.end()) { CTimer *ptr = it->second; TimerList.erase(it); ptr->stop(); } } static void RemoveTimerList(const CTimer *p) { std::lock_guard lock(mtx); for (auto it = TimerList.begin(); it != TimerList.end(); ++it) { CTimer *ptr = it->second; if (ptr == p) { TimerList.erase(it); break; } } } uint32_t AppTimer_GetTickCount(void) { std::chrono::milliseconds as = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()); return as.count(); } uint64_t AppTimer_GetGmtTickCount(void) { std::chrono::seconds as = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); return as.count(); } std::string FormatTime(const char *fmt = "%Y-%m-%d %H:%M:%S") { auto now = std::chrono::system_clock::now(); auto timet = std::chrono::system_clock::to_time_t(now); auto localTime = *std::localtime(&timet); std::stringstream ss; std::string str; ss << std::put_time(&localTime, "%Y-%m-%d %H:%M:%S"); str = ss.str(); return str; } std::time_t MktimeString(const char *str, const char *fmt) { struct std::tm dt; std::istringstream ss(str); ss >> std::get_time(&dt, fmt); std::stringstream out; out << std::put_time(&dt, "%Y-%m-%d %H:%M:%S"); // DEBUG("%s, %ld", out.str().c_str(), std::mktime(&dt)); time_t utc = std::mktime(&dt); return utc; } time_t TimeStamp(int year, int mon, int day, int hour, int min, int sec) { // YYHHDDhhmmss(GMT+8) struct tm test_tm; struct timeval tv; struct timezone tz; gettimeofday(&tv,&tz); memset(&test_tm, 0, sizeof(test_tm)); test_tm.tm_year = year - 1900; test_tm.tm_mon = mon - 1; test_tm.tm_mday = day; test_tm.tm_hour = hour; test_tm.tm_min = min; test_tm.tm_sec = sec; return mktime(&test_tm) - tz.tz_minuteswest*60; }