游戏 定时器

常见游戏中高性能定时器,有两种实现:
时间轮定时器
最小堆定时器

时间轮定时器

将定时器的走时假定为一个轮盘,通过合适的算法将每一个定时器都放入到轮盘中,轮盘又分N(最好是2的多少次方)个槽,一个槽对应一个tick,
所以一个轮盘一圈总时间为N*tick。考虑到有些时间长的定时器,可能要转好几圈(rotation)。
#include <functional>
#include "CodeException.h"
#include "ObjectPool.h"
template<typename Player>
struct Timer {
	Timer(int nRotation, int timeSlot):rotation(nRotation), time_slot(timeSlot){}
	int rotation;
	int time_slot;
	std::function<void(const Player)> pf_task_call;
	Player pPlayer;
	Timer<Player>* pNext = nullptr;
};

template<typename Player>
class Timer_Wheel {
	static const int _n_slot_size = 64;//2的6次方
	static const int _n_min_duration = 1;
	Timer<Player>* _p_array_slot[_n_slot_size]{ nullptr };
	int _n_cur_slot = 0;
public:
	Timer_Wheel() {
		ObjectAllocator::getInstance().Init<Timer<Player>>();
	}
	inline Timer<Player>* addTimer(int nDuration) {
		if (nDuration < _n_min_duration) throw CodeExceptionLog("illegal args");
		int time_slot = nDuration % _n_slot_size;
		Timer<Player>* pTimer = ObjectAllocator::getInstance().allocate<Timer<Player>>(nDuration / _n_slot_size, time_slot);
		if (nullptr == _p_array_slot[time_slot])
		{
			_p_array_slot[time_slot] = pTimer;
		}
		else
		{
			pTimer->pNext = _p_array_slot[time_slot];
			_p_array_slot[time_slot] = pTimer;
		}
		return pTimer;
	}

	void tick() {
		Timer<Player>* pTimer = _p_array_slot[_n_cur_slot];
		Timer<Player>* pPreTimer = nullptr;
		while (pTimer)
		{
			if (0 != pTimer->rotation)
			{
				--(pTimer->rotation);
				pPreTimer = pTimer;//设置前置节点
				pTimer = pTimer->pNext;

			}
			else
			{
				pTimer->pf_task_call(pTimer->pPlayer);
				//从_p_array_slot[_n_cur_slot]中删除pTimer
				if (pPreTimer == nullptr)//前置节点为空,第一个节点
				{
					//只有删除第一个才需要修改_p_array_slot[_n_cur_slot]
					_p_array_slot[_n_cur_slot] = pTimer->pNext;
				}
				else
				{
					pPreTimer->pNext = pTimer->pNext;
				}
				Timer<Player>* pTemp = pTimer->pNext;
				ObjectAllocator::getInstance().deletor<Timer<Player>>(pTimer);
				pTimer = pTemp;
			}
		}
		_n_cur_slot = (_n_cur_slot + 1) % _n_slot_size;
	}
};

最小堆定时器

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值