void DisplayLinkDirector::mainLoop()
{
// 这个标志在调用end()方法会设置为true
if (_purgeDirectorInNextLoop)
{
<span style="font-family:Consolas, Courier New, Courier, mono, serif;"><span style="line-height: 18px;">//只有一种情况会调用到这里来,就是导演类调用end函数</span></span>
_purgeDirectorInNextLoop = false;
purgeDirector();
}
//<span style="font-family: Arial, Helvetica, sans-serif;">startAnimation 设置为false, </span><span style="font-family: Arial, Helvetica, sans-serif;">stopAnimation 设置为 true</span><span style="font-family: Arial, Helvetica, sans-serif;">
</span> else if (! _invalid)
{
drawScene();
// release the objects
PoolManager::getInstance()->getCurrentPool()->clear();
}
}//
void DisplayLinkDirector::stopAnimation()
{
_invalid = true;
}
// should we implement 4 types of director ??
// I think DisplayLinkDirector is enough
// so we now only support DisplayLinkDirector
void DisplayLinkDirector::startAnimation()
{
if (gettimeofday(_lastUpdate, nullptr) != 0)
{
CCLOG("cocos2d: DisplayLinkDirector: Error on gettimeofday");
}
_invalid = false;
Application::getInstance()->setAnimationInterval(_animationInterval);
// fix issue #3509, skip one fps to avoid incorrect time calculation.
setNextDeltaTimeZero(true);
}
// Draw the Scene
void Director::drawScene()
{
// calculate "global" dt
calculateDeltaTime();
// skip one flame when _deltaTime equal to zero.
if(_deltaTime < FLT_EPSILON)
{
return;
}
if (_openGLView)
{
_openGLView->pollInputEvents();
}
//tick before glClear: issue #533
if (! _paused)
{
_scheduler->update(_deltaTime);
_eventDispatcher->dispatchEvent(_eventAfterUpdate);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* to avoid flickr, nextScene MUST be here: after tick and before draw.
XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */
if (_nextScene)
{
setNextScene();
}
pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
// draw the scene
if (_runningScene)
{
_runningScene->visit(_renderer, Mat4::IDENTITY, false);
_eventDispatcher->dispatchEvent(_eventAfterVisit);
}
// draw the notifications node
if (_notificationNode)
{
_notificationNode->visit(_renderer, Mat4::IDENTITY, false);
}
if (_displayStats)
{
showStats();
}
_renderer->render();
_eventDispatcher->dispatchEvent(_eventAfterDraw);
popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
_totalFrames++;
// swap buffers
if (_openGLView)
{
_openGLView->swapBuffers();
}
if (_displayStats)
{
calculateMPF();
}
}
void Director::calculateDeltaTime()
{
//大概是表示时间struct
struct timeval now;
//使用C语言编写程序需要获得当前精确时间(1970年1月1日到现在的时间)
//<span style="font-family: Arial, Helvetica, sans-serif;">其参数</span><span style="font-family: Arial, Helvetica, sans-serif;">now</span><span style="font-family: Arial, Helvetica, sans-serif;">是保存获取时间结果的结构体,第二个参数用于保存时区结果:可以传null</span><span style="font-family: Arial, Helvetica, sans-serif;">
</span> if (gettimeofday(&now, nullptr) != 0)
{
CCLOG("error in gettimeofday");
//记录 自mainloop上次tick过去了多少时间
_deltaTime = 0;
return;
}
// new delta time. Re-fixed issue #1277
//是否下一个增量时间(<span style="font-family: Arial, Helvetica, sans-serif;">_deltaTime</span><span style="font-family: Arial, Helvetica, sans-serif;">)将是零</span>
if (_nextDeltaTimeZero)
{
_deltaTime = 0;
_nextDeltaTimeZero = false;
}
else
{
//计算过去了的时间,后面的微秒 <span style="font-family: Arial, Helvetica, sans-serif;">/ 1000000.0f</span>
_deltaTime = (now.tv_sec - _lastUpdate->tv_sec) + (now.tv_usec - _lastUpdate->tv_usec) / 1000000.0f;
_deltaTime = MAX(0, _deltaTime);
}
#if COCOS2D_DEBUG
// If we are debugging our code, prevent big delta time
if (_deltaTime > 0.2f)
{
_deltaTime = 1 / 60.0f;
}
#endif
//最后一次更新的时间
*_lastUpdate = now;
}
摘自于百度 http://baike.baidu.com/view/2982901.htm?fr=aladdin
#include <sys/time.h>
int gettimeofday(struct timeval*tv, struct timezone *tz);
其参数tv是保存获取时间结果的结构体,参数tz用于保存时区结果:
struct timezone{
int tz_minuteswest;/*格林威治时间往西方的时差*/
int tz_dsttime;/*DST 时间的修正方式*/
}
timezone 参数若不使用则传入NULL即可。
而结构体timeval的定义为:
struct timeval{
long int tv_sec; // 秒数
long int tv_usec; // 微秒数
}
它获得的时间精确到微秒(1e-6 s)量级。在一段代码前后分别使用gettimeofday可以计算代码执行时间:
struct timeval tv_begin, tv_end;
gettimeofday(&tv_begin, NULL);
foo();
gettimeofday(&tv_end, NULL);