Cocos2d-x 调度器 Scheduler

 

Cocos2d-x 调度器 Scheduler

Coscos中的scheduler与节点有关,可以为每一个节点增加或删除scheduler,节点可以控制scheduler的开关。当节点不可见或者被一出时,节点上的scheduler也会停止。当cocos引擎暂停时,所有节点的scheduler也会暂停,cocos重新运行时scheduler也会重新运行。也可通过节点的成员函数Node::resume/ Node::pause暂停/恢复单个节点的Scheduler.

Scheduler类型

Cocos2d-x支持三种类型的Scheduler

每帧都调用的默认调度器Scheduler,schedulerUpdate(),调用节点的虚函数Update。

自定义调度器Scheduler,schedule(…),可以自定义调用函数,调用间隔,次数等等。

单次调度器scheduleOnce(…),可以自定义调用函数。

 

默认调度器schedulerUpdate()

通过函数void Node::scheduleUpdate()打开

通过函数void Node::unscheduleUpdate()关闭

通过scheduleUpdate打开默认调度器后节点在每帧绘制前,都会调用下面虚函数

virtual void Node::update(floatf Delta)

所以如果节点要使用默认调度器,需要重写update函数。

 

自定义调度器Scheduler

可以通过以下节点Node类的成员函数设置自定义调度器

void schedule(SEL_SCHEDULE selector, float interval,unsigned int repeat,float delay);

void schedule(SEL_SCHEDULE selector, floatinterval);

void schedule(SEL_SCHEDULE selector);

void schedule(const std::function<void(float)>&callback,const std::string&key);

void schedule(const std::function<void(float)>&callback,float interval,const std::string &key);

void schedule(const std::function<void(float)>&callback,float interval,unsigned int repeatfloat delay,const std::string &key);

自定义调度器支持两种形式的回调函数:

SEL_SCHEDULE为函数指针

const std::function<void(float)> &callback为C++11新特性Lambda表达式(匿名函数)

参数interval设为0,则代表每帧都调用

参数repeat设置为CC_REPEAT_FOREVER,则可以将调度器设为一直循环调用。

参数key,可以用于删除调度器,如果设置调度器时已经存在一共同名的key,则只会更新调度器的间隔时间,调度次数和回调函数不会更新。

 

可以通过以下节点Node类的成员函数删除自定义调度器

void unschedule(SEL_SCHEDULE selector);

void unschedule(const std::string &key);

void unschedule All Callbacks();

 

单次调度器scheduleOnce

可以通过以下节点Node类的成员函数设置单次调度器

void scheduleOnce(SEL_SCHEDULE selector, float delay);

void scheduleOnce(conststd::function<void(float)> &callback,float delay,const std::string &key);

delay为设置后调用的时间。

单次调度器实际上就是特殊的自定义调度器,以下式Node节点中设置单次调度器的代码:

void Node::scheduleOnce(SEL_SCHEDULE selector,float delay)

{

    this->schedule(selector, 0.0f,0, delay);//调用Node设置自定义调度器函数

}

 

void Node::scheduleOnce(const std::function<void(float)>&callback, float delay,const std::string &key)

{

    //调用Node设置自定义调度器函数

    _scheduler->schedule(callback, this,0, 0, delay, !_running,key);

}

 

调度器源码分析

所有节点的调度器都是由导演类Director中的变量Scheduler*  Director:: _scheduler管理,schedulerDirector::init中被初始。在Director::drawScene函数中_scheduler->update(_deltaTime)会被调用。Scheduler::update(float dt)函数会处理每个节点设置的调度器。

 

 

默认调度器schedulerUpdate

在Scheduler类里面由三个成员变量

    struct _listEntry*_updatesNegList;        // listof priority < 0

    struct _listEntry*_updates0List;            // listpriority == 0

    struct _listEntry*_updatesPosList;        // listpriority > 0

当Node节点调用scheduleUpdateWithPriority(int priority)函数时,则会根据priority把节点的加入到相应的队列中,scheduleUpdate实际上是已priority = 0参数调用scheduleUpdateWithPriority

 

Scheduler::update(float dt)中依次遍历_updatesNegList_updates0List_updatesPosList链表,在遍历过程中会调用相应节点的update函数。

 

自定义调度器Scheduler

Scheduler类内部由一个Timer类的队列_hashForTimers,当Node类设置自定义调度器时,都会向Timer类里面添加一共Timer类型的对象。Timer类是一个接口类,实际添加的是TimerTargetSelector类或TimerTargetCallback类,这个两个类分别对应函数指针类型调度器和匿名函数(lambda表达式)类型的调度器。在Scheduler::update(float dt)中会遍历这个队列,并调用注册的函数。

他们之前的关系图如下:

 

 Cocos2d-x 调度器 Scheduler_第1张图片

你可能感兴趣的:(Cocos2d-x)