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

来源:互联网 发布:js 遍历json数据 编辑:程序博客网 时间:2024/06/15 00:14

接上文,在进入主循环之前会进行相关初始化。applicationDidFinishLaunching()函数会被执行。本部分详细追踪cpp-tests中该函数。

首先进入applicationDidFinishLaunching()函数.

bool AppDelegate::applicationDidFinishLaunching(){    // As an example, load config file    // FIXME:: This should be loaded before the Director is initialized,    // FIXME:: but at this point, the director is already initialized    Configuration::getInstance()->loadConfigFile("configs/config-example.plist");//加载程序的配置    // initialize director    auto director = Director::getInstance();//导演    auto glview = director->getOpenGLView();//glview    if(!glview) {//若glview未初始化        glview = GLViewImpl::create("Cpp Tests");//初始化glview        director->setOpenGLView(glview);//设置所使用的glview    }    director->setDisplayStats(true);//是否显示帧率    director->setAnimationInterval(1.0 / 60);//设置帧率 60帧    auto screenSize = glview->getFrameSize();//得到的大小    auto designSize = Size(480, 320);//设计大小    auto fileUtils = FileUtils::getInstance();    std::vector<std::string> searchPaths;        if (screenSize.height > 320)//根据界面大小选择资源路径    {        auto resourceSize = Size(960, 640);        searchPaths.push_back("hd");        searchPaths.push_back("ccs-res/hd");        searchPaths.push_back("ccs-res/hd/scenetest");        searchPaths.push_back("ccs-res/hd/scenetest/ArmatureComponentTest");        searchPaths.push_back("ccs-res/hd/scenetest/AttributeComponentTest");        searchPaths.push_back("ccs-res/hd/scenetest/BackgroundComponentTest");        searchPaths.push_back("ccs-res/hd/scenetest/EffectComponentTest");        searchPaths.push_back("ccs-res/hd/scenetest/LoadSceneEdtiorFileTest");        searchPaths.push_back("ccs-res/hd/scenetest/ParticleComponentTest");        searchPaths.push_back("ccs-res/hd/scenetest/SpriteComponentTest");        searchPaths.push_back("ccs-res/hd/scenetest/TmxMapComponentTest");        searchPaths.push_back("ccs-res/hd/scenetest/UIComponentTest");        searchPaths.push_back("ccs-res/hd/scenetest/TriggerTest");        searchPaths.push_back("ccs-res");        searchPaths.push_back("Manifests");        director->setContentScaleFactor(resourceSize.height/designSize.height);                searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UIButton");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UICheckBox");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UIImageView");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UILabel");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UILabelBMFont");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UILayout/BackgroundImage");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UILayout/Color");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UILayout/Layout");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UILayout/Gradient_Color");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UILayout/Scale9_BackgroundImage");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UILayout/LayoutComponent");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UILoadingBar");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UIPageView");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UIScrollView/Both");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UIScrollView/Horizontal");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UIScrollView/Vertical");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UISlider");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UITextField");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UIWidgetAddNode");        searchPaths.push_back("ccs-res/hd/cocosui/UIEditorTest/UIListView/New");                searchPaths.push_back("ccs-res/hd/cocosui/CustomTest/CustomWidgetCallbackBindTest");        searchPaths.push_back("hd/ActionTimeline");        searchPaths.push_back("ccs-res/hd/armature");    }    else    {        searchPaths.push_back("ccs-res");        searchPaths.push_back("ccs-res/scenetest/ArmatureComponentTest");        searchPaths.push_back("ccs-res/scenetest/AttributeComponentTest");        searchPaths.push_back("ccs-res/scenetest/BackgroundComponentTest");        searchPaths.push_back("ccs-res/scenetest/EffectComponentTest");        searchPaths.push_back("ccs-res/scenetest/LoadSceneEdtiorFileTest");        searchPaths.push_back("ccs-res/scenetest/ParticleComponentTest");        searchPaths.push_back("ccs-res/scenetest/SpriteComponentTest");        searchPaths.push_back("ccs-res/scenetest/TmxMapComponentTest");        searchPaths.push_back("ccs-res/scenetest/UIComponentTest");        searchPaths.push_back("ccs-res/scenetest/TriggerTest");                searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UIButton");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UICheckBox");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UIImageView");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UILabel");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UILabelBMFont");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UILayout/BackgroundImage");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UILayout/Color");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UILayout/Layout");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UILayout/Gradient_Color");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UILayout/Scale9_BackgroundImage");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UILayout/LayoutComponent");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UILoadingBar");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UIPageView");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UIScrollView/Both");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UIScrollView/Horizontal");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UIScrollView/Vertical");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UISlider");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UITextField");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UIWidgetAddNode");        searchPaths.push_back("ccs-res/cocosui/UIEditorTest/UIListView/New");                searchPaths.push_back("ccs-res/cocosui/CustomTest/CustomWidgetCallbackBindTest");        searchPaths.push_back("ActionTimeline");        searchPaths.push_back("ccs-res/armature");    }        fileUtils->setSearchPaths(searchPaths);//设置资源查找路径    glview->setDesignResolutionSize(designSize.width, designSize.height, ResolutionPolicy::SHOW_ALL);//设计尺寸 涉及到屏幕适配         // Enable Remote Console    auto console = director->getConsole();//远程调试    console->listenOnTCP(5678);//监听端口5678    _testController = TestController::getInstance();//控制类 控制例子运行        return true;}

详细注释我都写在了代码上。其中有几个函数可以追踪看看到底是如何做的。

追踪一下    Configuration::getInstance()->loadConfigFile("configs/config-example.plist");//加载程序的配置

这可以帮助我们理解Cocos到底是如何进行相关程序配置的。(注:plist文件是xml格式的)

void Configuration::loadConfigFile(const std::string& filename){ValueMap dict = FileUtils::getInstance()->getValueMapFromFile(filename);CCASSERT(!dict.empty(), "cannot create dictionary");// search for metadatabool validMetadata = false;auto metadataIter = dict.find("metadata");if (metadataIter != dict.cend() && metadataIter->second.getType() == Value::Type::MAP)    {        const auto& metadata = metadataIter->second.asValueMap();        auto formatIter = metadata.find("format");        if (formatIter != metadata.cend())        {int format = formatIter->second.asInt();// Support format: 1if (format == 1)            {validMetadata = true;}}}if (! validMetadata)    {CCLOG("Invalid config format for file: %s", filename.c_str());return;}auto dataIter = dict.find("data");if (dataIter == dict.cend() || dataIter->second.getType() != Value::Type::MAP)    {CCLOG("Expected 'data' dict, but not found. Config file: %s", filename.c_str());return;}// Add all keys in the existing dictionary    const auto& dataMap = dataIter->second.asValueMap();    for (auto dataMapIter = dataMap.cbegin(); dataMapIter != dataMap.cend(); ++dataMapIter)    {        if (_valueDict.find(dataMapIter->first) == _valueDict.cend())            _valueDict[dataMapIter->first] = dataMapIter->second;        else            CCLOG("Key already present. Ignoring '%s'",dataMapIter->first.c_str());    }        //light info    std::string name = "cocos2d.x.3d.max_dir_light_in_shader";if (_valueDict.find(name) != _valueDict.end())        _maxDirLightInShader = _valueDict[name].asInt();    else        _valueDict[name] = Value(_maxDirLightInShader);        name = "cocos2d.x.3d.max_point_light_in_shader";if (_valueDict.find(name) != _valueDict.end())        _maxPointLightInShader = _valueDict[name].asInt();    else        _valueDict[name] = Value(_maxPointLightInShader);        name = "cocos2d.x.3d.max_spot_light_in_shader";if (_valueDict.find(name) != _valueDict.end())        _maxSpotLightInShader = _valueDict[name].asInt();    else        _valueDict[name] = Value(_maxSpotLightInShader);        name = "cocos2d.x.3d.animate_quality";    if (_valueDict.find(name) != _valueDict.end())        _animate3DQuality = (Animate3DQuality)_valueDict[name].asInt();    else        _valueDict[name] = Value((int)_animate3DQuality);}

 FileUtils::getInstance()->getValueMapFromFile(filename);该句将xml格式的plist文件处理成ValueMap。

 ValueMap的格式是std::unordered_map<std::string, Value>,Value保存的类型可以是以下格式

   enum class Type    {        /// no value is wrapped, an empty Value        NONE = 0,        /// wrap byte        BYTE,        /// wrap integer        INTEGER,        /// wrap float        FLOAT,        /// wrap double        DOUBLE,        /// wrap bool        BOOLEAN,        /// wrap string        STRING,        /// wrap vector        VECTOR,        /// wrap ValueMap        MAP,        /// wrap ValueMapIntKey        INT_KEY_MAP    };

把plist文件打开。其中保存的都是配置信息。

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict><key>data</key><dict><key>cocos2d.x.fps</key><integer>60</integer><key>cocos2d.x.display_fps</key><true/><key>cocos2d.x.gl.projection</key><string>3d</string><key>cocos2d.x.texture.pixel_format_for_png</key><string>rgba8888</string><key>cocos2d.x.texture.pvrv2_has_alpha_premultiplied</key><false/><key>cocos2d.x.testcpp.autorun</key><false/><key>cocos2d.x.3d.max_dir_light_in_shader</key><integer>1</integer><key>cocos2d.x.3d.max_point_light_in_shader</key><integer>1</integer><key>cocos2d.x.3d.max_spot_light_in_shader</key><integer>1</integer><key>cocos2d.x.3d.animate_quality</key><integer>2</integer></dict><key>metadata</key><dict><key>format</key><integer>1</integer></dict></dict></plist>

loadConfigFile()最终将配置信息都存在了_valueDict中,_valueDict是ValueMap的实例。

这里保存的配置只是保存到了Configuration(单例)的实例中,并没有成功写入程序配置,写入程序配置是在Director的初始化时完成的。

void Director::setDefaultValues(void){    Configuration *conf = Configuration::getInstance();    // default FPS    double fps = conf->getValue("cocos2d.x.fps", Value(kDefaultFPS)).asDouble();    _oldAnimationInterval = _animationInterval = 1.0 / fps;    // Display FPS    _displayStats = conf->getValue("cocos2d.x.display_fps", Value(false)).asBool();    // GL projection    std::string projection = conf->getValue("cocos2d.x.gl.projection", Value("3d")).asString();    if (projection == "3d")        _projection = Projection::_3D;    else if (projection == "2d")        _projection = Projection::_2D;    else if (projection == "custom")        _projection = Projection::CUSTOM;    else        CCASSERT(false, "Invalid projection value");    // Default pixel format for PNG images with alpha    std::string pixel_format = conf->getValue("cocos2d.x.texture.pixel_format_for_png", Value("rgba8888")).asString();    if (pixel_format == "rgba8888")        Texture2D::setDefaultAlphaPixelFormat(Texture2D::PixelFormat::RGBA8888);    else if(pixel_format == "rgba4444")        Texture2D::setDefaultAlphaPixelFormat(Texture2D::PixelFormat::RGBA4444);    else if(pixel_format == "rgba5551")        Texture2D::setDefaultAlphaPixelFormat(Texture2D::PixelFormat::RGB5A1);    // PVR v2 has alpha premultiplied ?    bool pvr_alpha_premultipled = conf->getValue("cocos2d.x.texture.pvrv2_has_alpha_premultiplied", Value(false)).asBool();    Image::setPVRImagesHavePremultipliedAlpha(pvr_alpha_premultipled);}

另外一个关注点:

 glview = GLViewImpl::create("Cpp Tests");//初始化glview

整个cpp-tests到此才真正初始化了glview。

GLViewImpl* GLViewImpl::create(const std::string& viewName){    auto ret = new (std::nothrow) GLViewImpl;    if(ret && ret->initWithRect(viewName, Rect(0, 0, 960, 640), 1)) {        ret->autorelease();        return ret;    }    return nullptr;}
我们可以看到GLViewImpl加入了自动释放池。这就解释了之前对其retain()的操作。在这里还可以更改生成的窗口大小。(在其它地方也能改)


最后一个需要关注的点是:

_testController = TestController::getInstance();//控制类 控制例子运行

这是所有在cpp-tests中进行的例子的控制器。转到该函数

TestController* TestController::getInstance(){    if (s_testController == nullptr)    {        s_testController = new (std::nothrow) TestController;        initCrashCatch();//initCrashCatch();http://blog.csdn.net/starlee/article/details/6613424  目的大概是 让程序在崩溃时体面的退出    }    return s_testController;}

在该函数中进行了TestController的首次初始化。其初始化代码

TestController::TestController(): _stopAutoTest(true), _isRunInBackground(false), _testSuite(nullptr){    _rootTestList = new (std::nothrow) RootTests;  //根界面    _rootTestList->runThisTest();//显示根界面      函数中运行了director->replaceScene(scene);    _director = Director::getInstance();    _touchListener = EventListenerTouchOneByOne::create();//给程序添加触摸回调机制  onebyone代表单点触摸    _touchListener->onTouchBegan = CC_CALLBACK_2(TestController::blockTouchBegan, this);//绑定触摸回调函数    _touchListener->setSwallowTouches(true);//设置触摸不可以向下传 简单点来说,比如有两个sprite ,A 和 B,A在上B在下(位置重叠),触摸A的时候,B不会受到影响    _director->getEventDispatcher()->addEventListenerWithFixedPriority(_touchListener, -200);//触摸添加到监听,优先度 - 200 很高的}


具体内容涉及到contoller.h的内容,较为复杂。在研究完mainloop()之后我会对其进行研究。


0 0
原创粉丝点击