📄 timerengine.cpp
字号:
// ***************************************************************
// TimerEngine version: 1.0
// -------------------------------------------------------------
// File Name: TimerEngine.cpp
// Created: 2007/07/18
// Modified: 2007/07/18 16:37
// Author: William.Liang
// Msn: lwq49@msn.com
// Email: lwq49@21cn.com, lwq49@msn.com
// Description:
//
// Purpose:
// -------------------------------------------------------------
// license:
//
// The contents of this file are subject to the Mozilla Public
// License Version 1.1 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy
// of the License at http://www.mozilla.org/MPL/ Software dis-
// tributed under the License is distributed on an "AS IS"
// basis, WITHOUT WARRANTY OF ANY KIND, either express or im-
// plied. See the License for the specific language governing
// rights and limitations under the License.
//
// The Initial Developer of the Original Code is William.Liang .
// Copyright (C) 2007 - All Rights Reserved.
// ***************************************************************
#include "StdAfx.h"
#include "TimerEngine.h"
//#include "EventService.h"
//宏定义
#define NO_TIME_LEFT DWORD(-1) //不响应时间
//////////////////////////////////////////////////////////////////////////
//************************************
// <p>Description: 构造函数</p>
//************************************
CTimerThread::CTimerThread(void)
{
m_dwTimerSpace=0L;
m_pTimerEngine=NULL;
}
//************************************
// <p>Description: 析构函数</p>
//************************************
CTimerThread::~CTimerThread(void)
{
}
//************************************
// <p>Description: 配置函数</p>
// <p>Parameters: </p>
// <p> CTimerEngine * pTimerEngine</p>
// <p> DWORD dwTimerSpace</p>
//
// <p>Returns: bool</p>
//************************************
bool CTimerThread::InitThread(CTimerEngine * pTimerEngine, DWORD dwTimerSpace)
{
//效益参数
_ASSERT(dwTimerSpace>=10L);
_ASSERT(pTimerEngine!=NULL);
if (pTimerEngine==NULL) return false;
//设置变量
m_dwTimerSpace=dwTimerSpace;
m_pTimerEngine=pTimerEngine;
return true;
}
//************************************
// <p>Description: 运行函数</p>
// <p>Parameters: </p>
//
// <p>Returns: bool</p>
//************************************
bool CTimerThread::RepetitionRun()
{
_ASSERT(m_pTimerEngine!=NULL);
Sleep(m_dwTimerSpace);
m_pTimerEngine->OnTimerThreadSink();
return true;
}
//////////////////////////////////////////////////////////////////////////
//************************************
// <p>Description: 构造函数</p>
//************************************
CTimerEngine::CTimerEngine(void)
{
m_bService=false;
m_dwTimePass=0L;
m_dwTimerSpace=50L;
m_dwTimeLeave=NO_TIME_LEFT;
}
//************************************
// <p>Description: 析构函数</p>
//************************************
CTimerEngine::~CTimerEngine(void)
{
//停止服务
StopService();
//清理内存
tagTimerItem * pTimerItem=m_TimerItems.Iterators(true);
while(pTimerItem){
_ASSERT(pTimerItem!=NULL);
SafeDelete(pTimerItem);
pTimerItem=m_TimerItems.Iterators();
}
m_TimerItems.RemoveAll();
return;
}
//************************************
// <p>Description: 接口查询</p>
// <p>Parameters: </p>
// <p> const IID & Guid</p>
// <p> DWORD dwQueryVer</p>
//
// <p>Returns: void * __cdecl</p>
//************************************
void * __cdecl CTimerEngine::QueryInterface(const IID & Guid, DWORD dwQueryVer)
{
QUERYINTERFACE(ITimerEngine,Guid,dwQueryVer);
QUERYINTERFACE(ITimerEngineManager,Guid,dwQueryVer);
QUERYINTERFACE_IUNKNOWNEX(ITimerEngine,Guid,dwQueryVer);
return NULL;
}
//************************************
// <p>Description: 设置定时器</p>
// <p>Parameters: </p>
// <p> WORD wTimerID</p>
// <p> DWORD dwElapse</p>
// <p> DWORD dwRepeat</p>
// <p> WPARAM wParam</p>
//
// <p>Returns: bool __cdecl</p>
//************************************
bool __cdecl CTimerEngine::SetTimer(WORD wTimerID, DWORD dwElapse, DWORD dwRepeat, WPARAM wParam, BOOL bCheckExist)
{
//锁定资源
CThreadLockHandle LockHandle(&m_ThreadLock);
//效验参数
_ASSERT(dwRepeat>0L);
if (dwRepeat==0) return false;
//查找定时器
bool bTimerExist = bCheckExist?(m_TimerItems.GetBy(wTimerID)!=NULL):bCheckExist;
//创建定时器
if (bTimerExist==false)
{
tagTimerItem* pTimerItem;
pTimerItem = new tagTimerItem;
_ASSERT(pTimerItem!=NULL);
if (pTimerItem==NULL) return false;
//取整数
dwElapse=(dwElapse+m_dwTimerSpace-1)/m_dwTimerSpace*m_dwTimerSpace;
pTimerItem->wTimerID=wTimerID;
pTimerItem->wBindParam=wParam;
pTimerItem->dwRepeatTimes=dwRepeat;
pTimerItem->dwElapse=dwElapse; //下一个系统激活间隔(例:25唤醒间隔 100激活一次,则为100)
pTimerItem->dwTimeLeave=dwElapse+m_dwTimePass; //(150)
m_dwTimeLeave=__min(m_dwTimeLeave,dwElapse);
m_TimerItems.Push(pTimerItem, wTimerID);
return true;
}
return false;
}
//************************************
// <p>Description: 删除定时器</p>
// <p>Parameters: </p>
// <p> WORD wTimerID</p>
//
// <p>Returns: bool __cdecl</p>
//************************************
bool __cdecl CTimerEngine::KillTimer(WORD wTimerID)
{
//锁定资源
CThreadLockHandle LockHandle(&m_ThreadLock);
tagTimerItem* pTimerItem = m_TimerItems.GetBy(wTimerID);
if(pTimerItem){
SafeDelete(pTimerItem);
m_TimerItems.RemoveBy(wTimerID);
if(m_TimerItems.GetCount()==0){
m_dwTimePass=0L;
m_dwTimeLeave=NO_TIME_LEFT;
}
return true;
}
return false;
}
//************************************
// <p>Description: 删除定时器</p>
//
// <p>Returns: bool __cdecl</p>
//************************************
bool __cdecl CTimerEngine::KillAllTimer()
{
//锁定资源
CThreadLockHandle LockHandle(&m_ThreadLock);
//删除定时器
tagTimerItem* pTimerItem = m_TimerItems.Iterators(true);
while(pTimerItem){
SafeDelete(pTimerItem);
pTimerItem = m_TimerItems.Iterators();
}
m_TimerItems.RemoveAll();
//设置变量
m_dwTimePass=0L;
m_dwTimeLeave=NO_TIME_LEFT;
return true;
}
//************************************
// <p>Description: 开始服务</p>
//
// <p>Returns: bool __cdecl</p>
//************************************
bool __cdecl CTimerEngine::StartService()
{
//效验状态
//定时器引擎重复启动,启动操作忽略
if (m_bService==true) return true;
//判断绑定
if (m_AttemperEvent.IsValid()==false)
{
//CEventTrace::ShowEventNotify(TEXT("定时器引擎未与触发服务绑定"),Level_Exception);
return false;
}
//设置变量
m_dwTimePass=0L;
m_dwTimeLeave=NO_TIME_LEFT;
if (m_TimerThread.InitThread(this,m_dwTimerSpace)==false)
{
//CEventTrace::ShowEventNotify(TEXT("定时器引擎线程服务初始化失败"),Level_Exception);
return false;
}
//启动服务
if (m_TimerThread.StartThead()==false)
{
//CEventTrace::ShowEventNotify(TEXT("定时器引擎线程服务启动失败"),Level_Exception);
return false;
}
//设置变量
m_bService=true;
return true;
}
//************************************
// <p>Description: 停止服务</p>
//
// <p>Returns: bool __cdecl</p>
//************************************
bool __cdecl CTimerEngine::StopService()
{
//设置变量
m_bService=false;
//停止线程
m_TimerThread.StopThread();
//设置变量
m_dwTimePass=0L;
m_dwTimeLeave=NO_TIME_LEFT;
//删除计时器
KillAllTimer();
return true;
}
//************************************
// <p>Description: 设置接口</p>
// <p>Parameters: </p>
// <p> IUnknownEx * pIUnknownEx</p>
//
// <p>Returns: bool __cdecl</p>
//************************************
bool __cdecl CTimerEngine::SetTimerEngineSink(IUnknownEx * pIUnknownEx)
{
//效验参数
_ASSERT(pIUnknownEx!=NULL);
_ASSERT(m_bService==false);
if (m_bService==true) return false;
if (pIUnknownEx==NULL) return false;
//设置接口
if (m_AttemperEvent.SetQueueService(pIUnknownEx)==false)
{
//CEventTrace::ShowEventNotify(TEXT("定时器引擎与触发服务绑定失败"),Level_Exception);
return false;
}
return true;
}
//************************************
// <p>Description: 定时器通知</p>
// 每次激活时计算下一个被激活的时间间隔(保存在m_dwTimeLeave),
// 每次执行是用m_dwTimeLeave-m_dwTimerSpace(系统唤醒间隔),若
// 结果为0则查询被激活的计时器事件,在每次查询中扣除每个计时器
// 的时间计数器值,并求出下一个最快被激活的计时器间隔
// (重设m_dwTimeLeave)
// <p>Parameters: </p>
//
// <p>Returns: void</p>
//************************************
void CTimerEngine::OnTimerThreadSink()
{
//锁定资源
CThreadLockHandle LockHandle(&m_ThreadLock);
//倒计时间
if (m_dwTimeLeave==NO_TIME_LEFT)
{
//代表没有可计时器事件
return;
}
//减少时间
_ASSERT(m_dwTimeLeave>=m_dwTimerSpace);
m_dwTimeLeave-=m_dwTimerSpace;
m_dwTimePass+=m_dwTimerSpace;
//查询定时器
if (m_dwTimeLeave==0)
{
bool bKillTimer=false;
DWORD dwTimeLeave=NO_TIME_LEFT;
tagTimerItem* pTimerItem = m_TimerItems.Iterators(true);
while(pTimerItem){
//定时器处理
bKillTimer=false;
//每个计时器倒计
pTimerItem->dwTimeLeave-=m_dwTimePass;
if (pTimerItem->dwTimeLeave==0L){
//发送通知
m_AttemperEvent.PostTimerEvent(pTimerItem->wTimerID,pTimerItem->wBindParam);
//设置次数
if (pTimerItem->dwRepeatTimes!=TIMER_REPEAT_TIMER)
{
_ASSERT(pTimerItem->dwRepeatTimes>0);
if (pTimerItem->dwRepeatTimes==1L)
{
//SafeDelete(pTimerItem);
//pTimerItem = NULL;
//后面需要补充将所有pTimerItem为空的项目删除
bKillTimer=true;
}
else pTimerItem->dwRepeatTimes--;
}
//设置时间
if (bKillTimer==false) pTimerItem->dwTimeLeave=pTimerItem->dwElapse;
}
//增加索引
if (bKillTimer==false)
{
//求下一个最快被激活的计时器时间
dwTimeLeave=__min(dwTimeLeave,pTimerItem->dwTimeLeave);
//_ASSERT(dwTimeLeave%m_dwTimerSpace==0);
}
pTimerItem = m_TimerItems.Iterators();
}
if(bKillTimer){
for(INT_PTR i=m_TimerItems.GetCount();i>=1;i--){
pTimerItem = m_TimerItems.Get(i);
if(pTimerItem->dwTimeLeave==0L && pTimerItem->dwRepeatTimes==1){
SafeDelete(pTimerItem);
m_TimerItems.Remove(i);
}
}
}
//设置响应
m_dwTimePass=0L;
m_dwTimeLeave=dwTimeLeave;
}
return;
}
//////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -