文章目录
取模
对-1取模是现将-1加上除数的整数倍大于零后再取模。
Timer()
变量
float _elapsed; // 渡过的时间.
bool _runForever; // 状态变量,标记是否永远的运行。
bool _useDelay; // 状态变量,标记是否使用延迟
unsigned int _timesExecuted; // 记录已经执行了多少次。
unsigned int _repeat; // 定义要执行的总次数,0为1次 1为2次 ……
float _delay; // 延迟多少秒,是指在触发之前的延迟,在触发之后叫间隔,使用interval设置
float _interval; // 时间间隔。
_scheduler(nullptr)
, _elapsed(-1)
, _runForever(false)
, _useDelay(false)
, _timesExecuted(0)
, _repeat(0)
, _delay(0.0f)
, _interval(0.0f)
, _aborted(false)
设置定时器Timer()
void Timer::setupTimerWithInterval(float seconds, unsigned int repeat, float delay)
{
_elapsed = -1; //=-1表示是第一次进入函数,后面的再Update函数中会有初始化操作
_interval = seconds;
_delay = delay;
_useDelay = (_delay > 0.0f) ? true : false;
_repeat = repeat;
_runForever = (_repeat == CC_REPEAT_FOREVER) ? true : false; //CC_REPEAT_FOREVER == -1
_timesExecuted = 0;
}
void Timer::update(float dt)
{
if (_elapsed == -1) //表示第一次进入Update方法,进行初始化
{
_elapsed = 0; //已执行时间
_timesExecuted = 0; //执行次数
return;
}
// accumulate elapsed time
_elapsed += dt; //记录累计度过的时间
// deal with delay
if (_useDelay)
{
if (_elapsed < _delay) // 还没有完成延时
{
return;
}
_timesExecuted += 1; // important to increment before call trigger
trigger(_delay); // 【回调函数】
_elapsed = _elapsed - _delay; //此时记录的是开始执行之后度过的时间
_useDelay = false; //延迟结束
// after delay, the rest time should compare with interval
if (isExhausted()) //不永远执行并且已经执行完了重复次数
{
//unschedule timer
cancel();
return;
}
}
// if _interval == 0, should trigger once every frame
float interval = (_interval > 0) ? _interval : _elapsed; //正常来说interval都是大于零的,如果interval小于零,那就使用度过的时间来代替间隔时间
//如果度过的时间比间隔要大才会执行
while ((_elapsed >= interval) && !_aborted)
{
_timesExecuted += 1; // important to increment before call trigger
trigger(interval); // 【回调函数】
_elapsed -= interval; //记录剩余时间
if (isExhausted()) //不永远执行并且已经执行完了重复次数
{
cancel();
break;
}
if (_elapsed <= 0.f) //间隔时间等于度过的时间
{
break;
}
}
}
一些成员函数
bool TimerTargetSelector::initWithSelector(Scheduler* scheduler, SEL_SCHEDULE selector, Ref* target, float seconds, unsigned int repeat, float delay)
{
_scheduler = scheduler;
_target = target;
_selector = selector; //selector没有set方法,通过此方法来初始化
setupTimerWithInterval(seconds, repeat, delay);
return true;
}
void TimerTargetSelector::trigger(float dt) //调用回调函数
{
if (_target && _selector)
{
(_target->*_selector)(dt);
}
}
void TimerTargetSelector::cancel()
{
_scheduler->unschedule(_selector, _target);
}
class CC_DLL TimerTargetCallback : public Timer
{
public:
TimerTargetCallback();
// Initializes a timer with a target, a lambda and an interval in seconds, repeat in number of times to repeat, delay in seconds.
bool initWithCallback(Scheduler* scheduler, const ccSchedulerFunc& callback, void *target, const std::string& key, float seconds, unsigned int repeat, float delay);
const ccSchedulerFunc& getCallback() const {
return _callback; }
const std::string& getKey() const {
return _key; }
virtual void trigger(float dt) override;
virtual void cancel() override;
protected:
void* _target;
ccSchedulerFunc _callback;
std::string _key;
};
//初始化
bool TimerTargetCallback::initWithCallback(Scheduler* scheduler, const ccSchedulerFunc& callback, void *target, const std::string& key, float seconds, unsigned int repeat, float delay)
{
_scheduler = scheduler;
_target = target;
_callback = callback;
_key = key;
setupTimerWithInterval(seconds, repeat, delay);
return true;
}
//调用回调函数
void TimerTargetCallback::trigger(float dt)
{
if (_callback)
{
_callback(dt);
}
}
//
void TimerTargetCallback::cancel()
{
_scheduler->unschedule(_key, _target);
Scheduler()
经常使用的调度器是:
schedulerUpdate()
scheduler(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay)
scheduleOnce(SEL_SCHEDULE selector, float delay)
变量
pause:启用或暂停此方法。暂停(false),启用(true)
interval:每隔“interval”秒调用一次方法,如果为0,则每一帧都调用,当为0时,建议使用schedulerUpdate。
repeat:触发一次事件后还会触发的次数,为0时触发一次
delay:延迟多少秒,是指在触发之前的延迟,在触发之后叫间隔,使用interval设置
key:用于取消定时器
初始化
typedef struct _listEntry
{
struct _listEntry *prev, *next;
ccSchedulerFunc callback;
void *target;
int priority;
bool paused;
bool markedForDeletion; // selector will no longer be called and entry will be removed at end of the next tick
} tListEntry;
//内置的update定时器
typedef struct _hashUpdateEntry
{
tListEntry **list; // Which list does it belong to ?
tListEntry *entry; // entry in the list
void *target;
ccSchedulerFunc callback;
UT_hash_handle hh;
} tHashUpdateEntry;
// 自定义定时器
typedef struct _hashSelectorEntry
{
ccArray *timers;
void