Cocos2dx 追踪cpp-tests运行流程(1)


开始阅读Cocos2dx给的示例cpp-tests。本文将从追踪程序直到点开一个示例,了解cocos在期间干了些什么。

首先,依旧是程序入口main.cpp:

#include "main.h"
#include "AppDelegate.h"

USING_NS_CC;

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // create the application instance
    AppDelegate app;
    return Application::getInstance()->run();
}

win32平台的入口函数。初始化了Application类,如上篇所述,这是个单例类,由语句AppDelegate app;进行了初始化。定位过去

AppDelegate::AppDelegate()
: _testController(nullptr)
{
}
AppDelegate 做了额外的初始化,初始化了_testController,这个是cpp-tests中定义的单例类TestController,用来控制cpp-tests中很多例子的执行。

由类的继承关系,我们可以得知Application本身也得到了初始化。

Application::Application()
: _instance(nullptr)
, _accelTable(nullptr)
{
    _instance    = GetModuleHandle(nullptr);
    _animationInterval.QuadPart = 0;
    CC_ASSERT(! sm_pSharedApplication);
    sm_pSharedApplication = this;
}

初始化了一些句柄_instance,_accelTable,以及指向本身的指针sm_pSharedApplication。_animationInterval和设置帧率有关,这个之后再说。

之后进入Application::getInstance()->run();追踪进去,代码如下:

<pre name="code" class="cpp">int Application::run()
{
    PVRFrameEnableControlWindow(false);//将程序的一些信息写入注册表

    // Main message loop:
    LARGE_INTEGER nLast; //用来存储时间
    LARGE_INTEGER nNow;

    QueryPerformanceCounter(&nLast);  //得到当前时间并存储到nLast中

    initGLContextAttrs();//初始化GL的属性

    // Initialize instance and cocos2d.
    if (!applicationDidFinishLaunching())//程序运行前所做的准备工作
    {
        return 1;
    }

    auto director = Director::getInstance();//导演 cocos中所初始化的导演类是DisplayLinkDirector子类 Director本身是个抽象类
											//DisplayLinkDirector初始化只做了 : _invalid(false),用来控制mainloop循环执行的内容
											//getInstance()中初始化了很多cocos中需要用的单例类
    auto glview = director->getOpenGLView();//获取gl对象 在applicationDidFinishLaunching()中已经进行了初始化

    // Retain glview to avoid glview being released in the while loop
    glview->retain();//由于glview是个自动释放的对象,在进入mainloop()之前务必要retain 因为gl是个需要一直用的东西 不能被release掉
					//自动释放池的内容以后再说吧 不能太混乱了

    while(!glview->windowShouldClose())//屏幕关闭问题 和平台有关 可以进行修改 游戏不断进行循环 这就是游戏的主循环
    {
        QueryPerformanceCounter(&nNow);//计算当前时间
        if (nNow.QuadPart - nLast.QuadPart > _animationInterval.QuadPart)//新老时间差满足帧率要求则运行 否则sleep(1),直到条件满足,这个是为了满足帧率
        {
            nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % _animationInterval.QuadPart);
            
            director->mainLoop();//进入主循环 处理游戏绘图和游戏逻辑
            glview->pollEvents();//处理游戏交互
        }
        else
        {
            Sleep(1);
        }
    }

    // Director should still do a cleanup if the window was closed manually.
    if (glview->isOpenGLReady())	//关闭程序后while循环结束 若opengl打开过 则进行收尾工作
    {
        director->end();//  执行了这么一句  _purgeDirectorInNextLoop = true; 之后再mainloop中就会执行第一种选择
        director->mainLoop();//执行其中的第一种选择        执行purgeDirector(); 对资源进行释放 包括OpenGL view _runningScene 字体 缓存 等等 详细可以自己追踪进去看看
        director = nullptr;
    }
    glview->release();//因为是自动释放对象 调用了retain 所以要release掉
    return 0;
}


 

详细信息我都写了注释,其中有几个内容我再追踪进去看一下,1是 auto director = Director::getInstance();

Director* Director::getInstance()
{
    if (!s_SharedDirector)
    {
        s_SharedDirector = new (std::nothrow) DisplayLinkDirector();
        CCASSERT(s_SharedDirector, "FATAL: Not enough memory");
        s_SharedDirector->init();
    }

    return s_SharedDirector;
}

可以看到如果Director尚未创建的话,新建DisplayLinkDirector类,并执行s_SharedDirector->init();

init函数就执行了下面这些初始化。

bool Director::init(void)
{
    setDefaultValues();

    // scenes
    _runningScene = nullptr;
    _nextScene = nullptr;

    _notificationNode = nullptr;

    _scenesStack.reserve(15);

    // FPS
    _accumDt = 0.0f;
    _frameRate = 0.0f;
    _FPSLabel = _drawnBatchesLabel = _drawnVerticesLabel = nullptr;
    _totalFrames = 0;
    _lastUpdate = new struct timeval;
    _secondsPerFrame = 1.0f;

    // paused ?
    _paused = false;

    // purge ?
    _purgeDirectorInNextLoop = false;
    
    // restart ?
    _restartDirectorInNextLoop = false;

    _winSizeInPoints = Size::ZERO;

    _openGLView = nullptr;

    _contentScaleFactor = 1.0f;

    _console = new (std::nothrow) Console;//控制台 可用于远程调试 tcp连接

    // scheduler
    _scheduler = new (std::nothrow) Scheduler();//定时器
    // action manager
    _actionManager = new (std::nothrow) ActionManager();//动作管理器
    _scheduler->scheduleUpdate(_actionManager, Scheduler::PRIORITY_SYSTEM, false);//设置动作管理器随时间更新

    _eventDispatcher = new (std::nothrow) EventDispatcher();//事件分发器
    _eventAfterDraw = new (std::nothrow) EventCustom(EVENT_AFTER_DRAW);	//事件分发器相关配置
    _eventAfterDraw->setUserData(this);
    _eventAfterVisit = new (std::nothrow) EventCustom(EVENT_AFTER_VISIT);
    _eventAfterVisit->setUserData(this);
    _eventAfterUpdate = new (std::nothrow) EventCustom(EVENT_AFTER_UPDATE);
    _eventAfterUpdate->setUserData(this);
    _eventProjectionChanged = new (std::nothrow) EventCustom(EVENT_PROJECTION_CHANGED);
    _eventProjectionChanged->setUserData(this);


    //init TextureCache 
    initTextureCache();//初始化纹理缓存
    initMatrixStack();//初始化矩阵

    _renderer = new (std::nothrow) Renderer;//渲染器 和OPENGL渲染相关

    return true;
}

好的,这就是第一部分,run()函数做了什么。接下来会介绍 applicationDidFinishLaunching()的运行及 mainloop()的运行。





 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值