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

📄 timer.h

📁 C++ patterns设计模式
💻 H
字号:
////////////////////////////////////////////////////////////////////////////////
// 定时器
////////////////////////////////////////////////////////////////////////////////
// Author      : 黎达文                                                        
// Description : 
//
// Version     : 2.0
//
// Standard include files : 
//
// Start Date  : 2003年12月4日
//
// Change Log  : 2003年12月4日 by 黎达文 -- Created
////////////////////////////////////////////////////////////////////////////////

#ifndef INCLUDED_TIMER_H
#define INCLUDED_TIMER_H

#if defined(HAS_PRAGMA_ONCE)
#pragma PRAGMA_ONCE_DECLARE
#endif

namespace kernel
{
    //the task base class
    class TimerTask
    {
    public:
        virtual void onTimer(unsigned int userdata) = 0;
    };

    //timer function type
    typedef void (*TimerProc)(unsigned int userdata);

    enum OwnerType{ OT_TASK, OT_FUNCTION } ;

    // 实现定时器算法逻辑,本身不带定时驱动器
    // ************************************************************************
    // 算法描述:
    // TimerLogic实现了一个模拟的时钟,这个时钟的最上一层(类似秒针)是一个256个刻度的盘子,
    // 下面四层(类似分钟,时针)有刻度是64的小盘子,上层转一圈之后下一层的刻度就走一个刻度。
    // 指示当前盘子走到那个刻度是TimerVec(或TimerVecRoot)的index。
    // 添加定时器的时候根据定时的时间将定时器数据(TimerList)放在恰当的盘子的恰当刻度中。
    // 时钟开始运转之后每一个滴答就检查第一个盘子的当前刻度是否有数据,如果有则触发该定时器
    // 当第一个盘子走完一圈之后就意味着下一个盘子的当前刻度的定时器(如果有)
    // 应该转移到第一个盘子上面来了,这时候将下一个盘子的当前刻度定时器全部重新插入第一个盘子
    // 然后依次检查第三、第四、第五个盘子是否也要将当前刻度的定时器重新插入上层。
    // 检查的依据就是上一层是否已经运转一圈了。
    //************************************************************************
    struct TimerList
    {
        TimerList       *next;         //the next must at first
        TimerList       *prev;
        unsigned int    expires;       //expire time
        OwnerType       owner_type;    //
        TimerTask       *task;         //the owner is base on TimerTask
        TimerProc       function;      //the owner is a function
        unsigned int    userdata;      //user private data
        TimerList()
            : next(NULL)
            , prev(NULL)
        {}
    };

    // the timer list
    typedef TimerList *TimerID;

    class TimerLogic
    {
    public:
		enum { NOOF_TVECS   = 5 };
		enum { TVN_BITS     = 6 };
		enum { TVR_BITS     = 8 };
		enum { TVN_SIZE     = (1 << TVN_BITS)	};
		enum { TVR_SIZE     = (1 << TVR_BITS)	};
		enum { TVN_MASK     = (TVN_SIZE - 1)	};
		enum { TVR_MASK     = (TVR_SIZE - 1)	};
        struct TimerVec                //small circle
        {
            int         index;
            TimerList  *vec[TVN_SIZE];
        };  
        struct TimerVecRoot           //big circle
        {
            int          index;
            TimerList  *vec[TVR_SIZE];
        };
        /////////////////////////////////////////////////////////////////////////////////
        TimerLogic();
        bool    insert (TimerList *timer);
        void    erase  (TimerList *curr);
        void    cascade(TimerVec  *tv);
    protected:
        unsigned int  tickCount;
        // 定时器有一个大盘和四个小盘
        TimerVec      *tvecs[NOOF_TVECS];
        TimerVecRoot  tv1;
        TimerVec      tv2, tv3, tv4, tv5;
    };

    // 定时驱动器,驱动tickCount往前进行。
    // 并负责派送消息到TimerTask
    // 使用TimerList对象的地址作为定时器的ID
    class GeneralTimer : public TimerLogic, public CTThreadExtend
    {
    public:
		enum {	MIN_TIMESLICE    = 10 };       // ms
		enum { DEFAULT_TIMESLICE = 50 };       // ms

        GeneralTimer(unsigned int timerslice = DEFAULT_TIMESLICE);
        ~GeneralTimer();

        // 设置一个定时器,定时长度为expires,定时器到达通知owner,通知的时候带回userdata
        TimerID set(TimerTask *owner, unsigned int expires, unsigned int userdata);
        // 设置一个定时器,定时长度为expires,定时器到达调用function,参数传递userdata
        TimerID set(TimerProc function, unsigned int expires, unsigned int userdata);
        // 删除一个定时器
        void    unset(TimerID timerid);

    private:
        void threadProcess();

    private:        
        volatile bool m_exit_signaled;
        unsigned int  m_timeslice;                       //precision of tick
    };

    // set method will remember the timerid 
    // and unset method will check the timerid at first
    class HashTimer : public GeneralTimer
    {
    public:
        unsigned int     set(TimerTask *owner, unsigned int expires, unsigned int userdata);
        unsigned int     set(TimerProc function, unsigned int expires, unsigned int userdata);
        void             unset(unsigned int id);
    protected:
        unsigned int     nextid();
    private:
        typedef std::map<unsigned int, TimerID> IDTYPE;
        IDTYPE                           m_idmap;
        CTCriticalSection                m_cs;
        unsigned int                     m_id;
		enum { MIN_ID     = 0		};
		enum { MAX_ID     = 0xFFFF	};
		enum { INVALID_ID = ~0		};
    };

    // 全局方法
    unsigned int  SetTimer(TimerTask *owner, unsigned int expires, unsigned int userdata);
    unsigned int  SetTimer(TimerProc function, unsigned int expires, unsigned int userdata);
    void KillTimer(unsigned int id);
};


#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -