是cocos2d-x核心的一块,负责调度执行,更新动作等。
如何计时?
Timer保存了调度任务的 时间线 重复次数 事件间隔 延迟等数据。
每帧更新后Timer做事件累加,根据时间线去触发或者取消更新回调。
Scheduler有两种添加更新的机制
-
自定义更新
根据target的不同Ref和void,分为两种。一种是TimerTargetCallback一种是TimerTargetSelector
他们同时继承自Timer,Timer有计时机制,含有触发和取消器。
void schedule(SEL_SCHEDULE selector, Ref *target, float interval, unsigned int repeat, float delay, bool paused);
void schedule(const ccSchedulerFunc& callback, void *target, float interval, bool paused, const std::string& key);
- 每帧更新(带优先级的)
void Scheduler::schedulePerFrame(const ccSchedulerFunc& callback, void *target, int priority, bool paused)
如何保存这些回调更新?
每帧更新每帧更新的回调放在 _hashForUpdates结构中以target作为key,同时根据优先级放在不同的hash表中。
自定义更新更新回调放在_hashForTimers hash表中,以target作为key.
uthash,uthash是Scheduler的核心数据结构。
struct _listEntry * _updatesNegList; // list of priority < 0
struct _listEntry * _updates0List; // list priority == 0
struct _listEntry * _updatesPosList; // list priority > 0
struct _hashUpdateEntry *_hashForUpdates; // hash used to fetch quickly the list entries for pause,delete,etc
struct _hashSelectorEntry *_hashForTimers;
自定义更新的hash表 _hashForTimers以target作为key,hash节点中包含数组数组中包含了Timer.
每帧更新的hash表 则使用_hashForUpdates 其中以target作为key,节点中包含了链表,链表中存储timer.
如何执行调度?
每帧开始绘制之前执行Scheduler::update(float dt)
在里面遍历hash表,执行update更新回调,完成后移出。
按照优先级<0 ==0 >0 自定义更新的顺序遍历执行。
如何取消?
TimerTargetCallback 通过key来取消,因为一个lambada表达式无法比较。
TimerTargetSeletor 通过设置的成员回调函数的指针来移出。
void Scheduler::unschedule(const std::string &key, void *target)
void Scheduler::unschedule(SEL_SCHEDULE selector, Ref *target)