#include "StdAfx.h" #include "TimerEngine.h" CAutoLock::CAutoLock(LPCRITICAL_SECTION lpCriticalSetion) { EnterCriticalSection(lpCriticalSetion); m_lpCriticalSetion = lpCriticalSetion; } CAutoLock::~CAutoLock() { LeaveCriticalSection(m_lpCriticalSetion); } ////////////////////////////////////////////////////////////////////////////////// void WINAPI onTimeFunc(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { CTimerEngine* pThis1 = (CTimerEngine*)dwUser; pThis1->OnTimerThreadSink(); return; } ////////////////////////////////////////////////////////////////////////////////// // 构造函数 CTimerEngine::CTimerEngine() { // 状态变量 m_bService = false; // 配置变量 m_dwTimerSpace = 30; InitializeCriticalSection(&m_CriticalSection); StartService(); return; } // 析构函数 CTimerEngine::~CTimerEngine() { // 停止服务 ConcludeService(); DeleteCriticalSection(&m_CriticalSection); // 清理内存 m_TimerItemFree.clear(); m_TimerItemActive.clear(); return; } // 设置定时器 bool CTimerEngine::SetTimer(ITimerCallBack* p, DWORD dwTimerID, DWORD dwElapse, DWORD dwRepeat, WPARAM dwBindParameter) { // 锁定资源 CAutoLock ThreadLock(&m_CriticalSection); // 效验参数 ASSERT(dwRepeat > 0L); if (dwRepeat == 0) return false; dwElapse = (dwElapse + m_dwTimerSpace - 1) / m_dwTimerSpace*m_dwTimerSpace; // 查找定时器 bool bTimerExist = false; std::shared_ptr pTimerItem = NULL; for(auto & it: m_TimerItemActive) { if (it->pCallBack == p && it->dwTimerID == dwTimerID) { bTimerExist = true; pTimerItem = it; break; } } // 创建定时器 if (bTimerExist == false) { //使用空闲定时器 if (!m_TimerItemFree.empty()) { pTimerItem = *m_TimerItemFree.begin(); m_TimerItemFree.erase(m_TimerItemFree.begin()); } //没有空闲定时器 else { try { pTimerItem = std::shared_ptr(new tagTimerItem); ASSERT(pTimerItem != NULL); if (pTimerItem == NULL) return false; } catch (...) { return false; } } } // 设置参数 ASSERT(pTimerItem != NULL); pTimerItem->pCallBack = p; pTimerItem->dwElapse = dwElapse; pTimerItem->dwTimerID = dwTimerID; pTimerItem->dwRepeatTimes = dwRepeat; pTimerItem->dwBindParameter = dwBindParameter; pTimerItem->dwTimeLeave = dwElapse; // 激活定时器 if (bTimerExist == false) m_TimerItemActive.emplace_back(pTimerItem); return false; } // 删除定时器 bool CTimerEngine::KillTimer(ITimerCallBack* p, DWORD dwTimerID) { // 锁定资源 CAutoLock ThreadLock(&m_CriticalSection); // 查找定时器 for(auto it = m_TimerItemActive.begin(); it != m_TimerItemActive.end(); it++) { // 获取对象 if ((*it)->pCallBack != p || (*it)->dwTimerID != dwTimerID) continue; m_TimerItemFree.push_back(*it); // 设置对象 m_TimerItemActive.erase(it); return true; } return false; } // 删除定时器 bool CTimerEngine::KillAllTimer() { // 锁定资源 CAutoLock ThreadLock(&m_CriticalSection); // 删除定时器 m_TimerItemFree.splice(m_TimerItemFree.end(), m_TimerItemActive); m_TimerItemActive.clear(); //其实也没有数据了 return true; } // 开始服务 bool CTimerEngine::StartService() { // 状态效验 ASSERT(m_bService == false); if (m_bService == true) return false; // 启动服务 m_timerId = timeSetEvent(m_dwTimerSpace, m_dwTimerSpace, &onTimeFunc, DWORD_PTR(this), TIME_PERIODIC); // 设置变量 m_bService = true; return true; } // 停止服务 bool CTimerEngine::ConcludeService() { // 设置变量 m_bService = false; //关闭定时器 timeKillEvent(m_timerId); // 删除定时器 KillAllTimer(); return true; } // 定时器通知 VOID CTimerEngine::OnTimerThreadSink() { // 锁定资源 CAutoLock ThreadLock(&m_CriticalSection); // 倒计时间 if (m_TimerItemActive.empty()) { return; } // 变量定义 bool bKillTimer = false; // 时间搜索 for (auto it = m_TimerItemActive.begin(); it != m_TimerItemActive.end(); ) { // 获取对象 std::shared_ptr pTimerItem = *it; // 设置变量 bKillTimer = false; if (pTimerItem->dwTimeLeave <= m_dwTimerSpace) { pTimerItem->dwTimeLeave = 0; } else pTimerItem->dwTimeLeave -= m_dwTimerSpace; // 通知判断 if (pTimerItem->dwTimeLeave == 0L) { // 发送通知 ASSERT(pTimerItem->pCallBack != NULL); pTimerItem->pCallBack->TimerCallBack(pTimerItem->dwTimerID, pTimerItem->dwBindParameter); // 设置次数 if (pTimerItem->dwRepeatTimes != TIMES_INFINITY) { if (pTimerItem->dwRepeatTimes == 1L) { bKillTimer = true; m_TimerItemFree.push_back(*it); it = m_TimerItemActive.erase(it); } else pTimerItem->dwRepeatTimes--; } // 设置时间 if (bKillTimer == false) pTimerItem->dwTimeLeave = pTimerItem->dwElapse; } // 增加索引 if (bKillTimer == false) { it++; } } return; } CTimerEngine* CTimerEngine::GetInstance() { static CTimerEngine g_TimerInstance; return &g_TimerInstance; } //////////////////////////////////////////////////////////////////////////////////