程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> c++寫的通用計時器工具

c++寫的通用計時器工具

編輯:C++入門知識

先上代碼,本身沒有任何高科技的東西,不過很好用和方便。 [cpp]  #pragma once      #include "CommandQueue.h"   #include "GlobalFunction.h"      //   // 計時器回調函數.   //   typedef function<void(int)> TimerCallback;      class Timer   {   public:       Timer(int timerId, int ms, bool isLoop, const TimerCallback& func);       virtual ~Timer() {};       int getId() const       {           return m_timerId;       }              // return true if need remove       bool process();   private:       int m_timerId;       bool m_isLoop;       unsigned int m_startTime;       unsigned int m_delayTime;       TimerCallback m_function;   };      #ifdef USE_FOR_COCOS2D   class TimerObject : public Timer   {   public:       TimerObject(int timerId, int ms, bool isLoop, const TimerCallback& func, CCObject* target);       virtual ~TimerObject();   private:       CCObject* m_target;   };   #endif      class TimerMgr : public MySingleton<TimerMgr>   {   public:       TimerMgr()        {           m_currentTimerId = 0;       };          ~TimerMgr() {};          int addTimer(int ms, bool loop, TimerCallback func)       {           Timer* timer = new Timer(++m_currentTimerId, ms, loop, func);                      m_allTimers.push_back(std::move(timer));           return m_currentTimerId;       }      #ifdef USE_FOR_COCOS2D       int addTimerObject(int ms, bool loop, TimerCallback func, CCObject* target)       {           TimerObject* timer = new TimerObject(++m_currentTimerId, ms, loop, func, target);              m_allTimers.push_back(timer);           return m_currentTimerId;       }   #endif          void deleteTimer(int timerId)       {           auto itr = std::find_if(m_allTimers.begin(), m_allTimers.end(), [timerId](Timer* timer){               return (timer && timer->getId() == timerId);           });           delete *itr;           m_allTimers.erase(itr);       }          void processTimer();   private:       unsigned int m_currentTimerId;       unsigned int m_timerMgrStart;          std::vector<Timer*> m_allTimers;   };      inline int delay_call(int ms, const TimerCallback& func, bool isLoop = false)   {       return TimerMgr::getSingleton().addTimer(ms, isLoop, func);   }      inline int delay_call(CCObject* target, int ms, const TimerCallback& func, bool isLoop = false)   {       return TimerMgr::getSingleton().addTimerObject(ms, isLoop, func, target);   }      #ifdef USE_FOR_COCOS2D      // 用法PERFORM_SELECTOR(延遲時間毫秒, 回調函數, 參數),有幾個參數調用PERFORM_SELECTORn   #define PERFORM_SELECTOR(ms, func, ...) delay_call(this, static_cast<int>(ms), bind(&func, this, ##__VA_ARGS__))   #endif      inline void remove_timer(int timerId)   {       TimerMgr::getSingleton().deleteTimer(timerId);   }     [cpp]   #include "stdafx.h"   #include "TimerUtil.h"      TimerObject::TimerObject(int timerId, int ms, bool isLoop, const TimerCallback& func, CCObject* target):Timer(timerId, ms, isLoop, func)   {       m_target = target;       m_target->retain();   }      TimerObject::~TimerObject()   {        if (m_target) {           m_target->release();           m_target = NULL;       }   }         Timer::Timer(int timerId, int ms, bool isLoop, const TimerCallback& func)   {       m_timerId = timerId;       m_isLoop = isLoop;          // 可以循環,第一次直接調用       if (isLoop) {           m_startTime = 0;       } else {           m_startTime = TimeGet();       }       m_delayTime = ms;       m_function = std::move(func);   }      bool Timer::process()   {       if (TimeGet() < m_startTime + m_delayTime) {           return false;       }          m_function(m_timerId);          if (m_isLoop) {           m_startTime = TimeGet();           return false;       } else {           return true;       }   }                     void TimerMgr::processTimer()   {       for (int i = 0; i < (int)m_allTimers.size(); ++i) {           Timer* timer = m_allTimers[i];           if (timer && timer->process()) {               delete timer;               m_allTimers[i] = NULL;           }       }          for (auto itr = m_allTimers.begin(); itr != m_allTimers.end();) {           if (*itr == NULL) {               itr = m_allTimers.erase(itr);           } else {               ++itr;           }       }   }         計時器說簡單也很簡單,就是紀錄開始時間,每桢監測,如果到延遲時間了則執行對應的回調函數。  算是游戲中非常基礎的工具類。這裡借助function和bind實現了更加靈活的回調綁定。  回調函數沒有任何限制,也不需要回調者繼承任何東西。比如我們有一個戰斗管理者,開始戰斗的時候播放一個特效,延時1秒開始戰斗流程。那麼就可以這麼寫。 [cpp]   class FightMgr   {   public:       void play()       {           // play effect here           delay_call(1000, bind(&FightMgr::startFight, this, param1, param2), false);       }       void startFight(int playerId, int data)       {       }   }     計時器delay_call第二個參數是一個function,通過bind可以綁定任意函數,甚至可以傳lambda。   這個計時器並不是多線程異步操作的,需要游戲每桢運行的時候調用TimerMgr::getSingleton().process();  這樣的好處是我們寫代碼的時候不需要考慮線程同步,雖然我延時執行某些函數,但是都是在主線程完成的調用,也不用擔心opengl的content失效等問題。 沒有其他需要特意說明的了,最後再次感歎一下function的無窮魅力,還在用函數指針的同學要補充一下新工具了。 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved