⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timerengine.cpp

📁 游戏框架
💻 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 + -