CCScheduler调度器调度规则心得

最近在学习cocos2d-x引擎,看完源码之后有一些心得体会,在此与大家分享交流:)

版本:2.0.4


scheduler的调度模式:scheduler的调度模式分为两种,一种是按照优先级来调度的,在cocos2d-x中优先级分为三部分,小于零,大于零,等于零,在更新节点的时候按照优先级由小至大的顺序来进行更新,更新的操作则为直接调用节点自身的update()函数。至于为什么分开成为三个链表其实我也不太清楚,如果有了解的朋友的话欢迎留下你的看法~ 下面我们来看一下三个调度队列的命名以及其中的元素组成,这里面引用了一个哈希表来进行存储,至于具体的哈希表实现等,可以参照这个博客的内容

http://blog.csdn.net/llaisi530/article/details/8893657


 struct _listEntry *m_pUpdatesNegList;        // list of priority < 0
    struct _listEntry *m_pUpdates0List;            // list priority == 0
    struct _listEntry *m_pUpdatesPosList;        // list priority > 0


typedef struct _listEntry
{
    struct    _listEntry    *prev, *next;
    CCObject    *target;        // not retained (retained by hashUpdateEntry)
    int                    priority; //优先级
    bool                paused;//用于记录节点是否需要更新
    bool                markedForDeletion; // selector will no longer be called and entry will be removed at end of the next tick 这个用处在后面会再讲
    
} tListEntry;

有的朋友可能会发现,在三个链表下面,还有另外一个链表,但这个列表准确来说并不用于调度,只用于快速查询(找出某个节点位于哪个调度队列)

struct _hashUpdateEntry *m_pHashForUpdates; // hash used to fetch quickly the list entries for pause,delete,etc

typedef struct _hashUpdateEntry
{
    tListEntry            **list;        // Which list does it belong to ?
    tListEntry            *entry;        // entry in the list
    CCObject    *target;        // hash key (retained)
    UT_hash_handle        hh;
} tHashUpdateEntry;

讲完第一种调度方式,接下来就是第二种调度方式 按照自定义定时器来进行调度,在这种调度里面,不再是直接调用节点自身的update()函数而是设定一个或多个回调函数,下面就是保存定时器的链表声明,存储的结构体信息以及CCTIMER的内部成员。

struct _hashSelectorEntry *m_pHashForSelectors;

typedef struct _hashSelectorEntry
{
    ccArray                      *timers; //ccArray数组用于保存所有的自定义定时器,即一个节点能够拥有多个定时器
    CCObject            *target;    // hash key (retained) //执行更新的目标节点
    unsigned int                timerIndex;
    CCTimer                        *currentTimer;
    bool                        currentTimerSalvaged;
    bool                        paused; //是否暂停该节点的更新动作
    UT_hash_handle                hh;
} tHashSelectorEntry;

CCTimer类的内部成员
public:
    SEL_SCHEDULE m_pfnSelector; //自定义的回调函数
    float m_fInterval;         //回调函数可以有自身的执行时间

protected:
    CCObject *m_pTarget;  //执行回调函数的目标节点
    float m_fElapsed;     //等待时间
    bool m_bRunForever;  //是否每次都更新,如果是的话就可以无视等待时间每帧更新
    bool m_bUseDelay;    //是否有延时,有延时的话就会在第一次执行时延时执行
    unsigned int m_nTimesExecuted; //记录执行更新的次数
    unsigned int m_nRepeat; //0 = once, 1 is 2 x executed
    float m_fDelay;      //延迟时间

    int m_nScriptHandler;//这个本人也没太弄明白,如果有大神看到的话请指点,谢谢^^

看完这些的时候,再看回CCScheduler里面的update函数,便十分清晰明了了,可以看到,里面先从优先级调度开始执行,就是从negList开始,依次执行里面各个节点自身的update()函数。然后再到0List,再到posList(),之后再到自定义的定时器,在自定义的定时器里面,又遍历了每个目标节点中的timers数组,以遍历它的所有自定义定时器。而最后呢,则执行删除操作,也就是对链表中markForDeletion的节点进行清理。

这样一个流程下来,便结束了CCScheduler的调度了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值