Cocos2d-x 调度器 Scheduler

来源:互联网 发布:粒子滤波算法原理 编辑:程序博客网 时间:2024/06/05 00:44

 

Cocos2d-x调度器 Scheduler

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

Scheduler类型

Cocos2d-x支持三种类型的Scheduler

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

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

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

 

默认调度器schedulerUpdate()

通过函数voidNode::scheduleUpdate()打开

通过函数voidNode::unscheduleUpdate()关闭

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

virtual voidNode::update(floatfDelta)

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

 

自定义调度器Scheduler

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

voidschedule(SEL_SCHEDULEselector,floatinterval,unsignedintrepeat,floatdelay);

voidschedule(SEL_SCHEDULEselector,floatinterval);

voidschedule(SEL_SCHEDULEselector);

voidschedule(conststd::function<void(float)>&callback,conststd::string&key);

voidschedule(conststd::function<void(float)>&callback,floatinterval,conststd::string&key);

voidschedule(conststd::function<void(float)>&callback,floatinterval,unsignedintrepeat,floatdelay,conststd::string&key);

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

SEL_SCHEDULE为函数指针

conststd::function<void(float)>&callbackC++11新特性Lambda表达式(匿名函数)

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

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

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

 

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

voidunschedule(SEL_SCHEDULEselector);

voidunschedule(conststd::string&key);

voidunscheduleAllCallbacks();

 

单次调度器scheduleOnce

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

voidscheduleOnce(SEL_SCHEDULEselector,floatdelay);

voidscheduleOnce(conststd::function<void(float)>&callback,floatdelay,conststd::string&key);

delay为设置后调用的时间。

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

voidNode::scheduleOnce(SEL_SCHEDULEselector,floatdelay)

{

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

}

 

voidNode::scheduleOnce(conststd::function<void(float)>&callback,floatdelay,conststd::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(floatdt)函数会处理每个节点设置的调度器。

 

 

默认调度器schedulerUpdate

Scheduler类里面由三个成员变量

    struct_listEntry*_updatesNegList;       // listof priority < 0

    struct_listEntry*_updates0List;           // listpriority == 0

    struct_listEntry*_updatesPosList;       // listpriority > 0

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

 

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

 

自定义调度器Scheduler

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

他们之前的关系图如下:

 

1 0
原创粉丝点击