/// <summary> /// 设置一个定时器 /// </summary> /// <param name="nID">定时器ID</param> /// <param name="fTime">定时器调用间隔</param> /// <param name="handler">处理接口</param> /// <param name="callTimes">调用次数,默认调用无穷次</param> /// <param name="debugInfo">调试信息</param> /// <returns>成功/失败</returns> public bool AddTimer(int nID, float fTime, ITimerHandler handler, int nCallTimes, string szLog) { if (handler == null) { return(false); } // 进行最小时间安全判断 if (fTime < CTimerAxis.CHECK_FREQUENCY / 1000.0f) { fTime = CTimerAxis.CHECK_FREQUENCY / 1000.0f; } // 诞生结构体 sTimer timer = new sTimer(); timer.dwTimerID = nID; timer.handler = handler; timer.dnDuration = (int)(fTime * 1000); timer.dwCallTimes = nCallTimes; timer.dwLastCallTick = m_dwLastCheckTick; timer.debugInfo = szLog; // 检查相同的回调函数 是否已经有TimerList 了, 如果没有创建一个新的 , 如果已经有了在旧的上面进行添加 List <sTimer> list = null; if (false == m_DicTimer.TryGetValue(handler, out list)) { list = new List <sTimer>(); m_DicTimer.Add(handler, list); } // 进行查重 foreach (var node in list) { if (node.dwTimerID == timer.dwTimerID) { return(false); } } list.Add(timer); // 将节点插入到时间轴上 timer.dwGridIndex = ((timer.dwLastCallTick + timer.dnDuration) / CTimerAxis.TIME_GRID) % CTimerAxis.ARRAY_LENGTH; LinkedList <sTimer> GridPos = m_TimerAxis[timer.dwGridIndex]; /*注意这里的计算方法 ,如果开始为0 1s 对应的gridId 为62 ,由于浮点数计算的时候无法精确, 我们hashtable会很大,1/0.016(一帧的时间)也就是说我们运行1s 需要在62帧之后才能运行 */ GridPos.AddFirst(timer); return(true); }
/// <summary> /// 检测时间 /// </summary> public void UpdateTimers(float fDt) { m_dwCurTime += (int)(fDt * 1000); // 时间小于最小精度 则返回 if (m_dwCurTime - m_dwLastCheckTick < CTimerAxis.CHECK_FREQUENCY) { return; } // 计算出开始步长和结束步长 int start_grid = (m_dwLastCheckTick / CTimerAxis.TIME_GRID) % CTimerAxis.ARRAY_LENGTH; int end_grid = (m_dwCurTime / CTimerAxis.TIME_GRID) % CTimerAxis.ARRAY_LENGTH; m_dwLastCheckTick = m_dwCurTime; int i = start_grid; while (i != end_grid) { LinkedList <sTimer> list = m_TimerAxis[i]; LinkedListNode <sTimer> pNode = list.First; while (pNode != null) { sTimer timer = pNode.Value; if (m_dwCurTime - timer.dwLastCallTick >= timer.dnDuration) { try { timer.AddLock(); timer.handler.OnTimer(timer.dwTimerID); timer.SubLock(); } catch (Exception e) { timer.SubLock(); throw e; } LinkedListNode <sTimer> pTempNode = pNode; pNode = pNode.Next; // 如果要执行删除 if (timer.bRemove == true && timer.isLock() == false) { DeleteTimer(timer.dwTimerID, timer.handler); continue; } // 如果调用次数已经用完 执行删除 if (timer.dwCallTimes > 0) { timer.dwCallTimes -= 1; if (timer.dwCallTimes <= 0) { DeleteTimer(timer.dwTimerID, timer.handler); continue; } } // 搬迁到下一次触发的位置 timer.dwLastCallTick = m_dwCurTime; timer.dwGridIndex = ((timer.dwLastCallTick + timer.dnDuration) / CTimerAxis.TIME_GRID) % CTimerAxis.ARRAY_LENGTH; LinkedList <sTimer> GridPos = m_TimerAxis[timer.dwGridIndex]; //GridPos.AddFirst(timer); GridPos.AddLast(timer); list.Remove(pTempNode); } } i = (i + 1) % CTimerAxis.ARRAY_LENGTH; } }