• cocso引擎整体流程


      任何程序都有入口,mian.cpp; Cocos2d也不免俗,在win32平台下,有一个mian.cpp 入口,从这里进入cocos的世界。

    #ifndef __MAIN_H__
    #define __MAIN_H__
    
    //WIN32_LEAN_AND_MEAN 是WINDOWS API用于屏蔽一些不常用的API(优化应用程序)才用的。
    #define WIN32_LEAN_AND_MEAN             // 从Windows头文件中排除不常用的内容
    
    // Windows 头文件:
    #include <windows.h>
    #include <tchar.h>
    
    // C 运行时的头文件:
    #include "platform/CCStdC.h"
    
    #endif    // __MAIN_H__
    main.h
    #include "main.h"
    #include "../Classes/AppDelegate.h"
    
    USING_NS_CC;
    
    int WINAPI _tWinMain(HINSTANCE hInstance,
                           HINSTANCE hPrevInstance,
                           LPTSTR    lpCmdLine,          
                           int       nCmdShow)
    {
    //以上参数为windows的Api 日后再说
    //我们从 UNREFERENCED_PARAMETER 开始吧。这个宏在 winnt.h 中定义如下:
    //#define UNREFERENCED_PARAMETER(P) (P)
    //换句话说 UNREFERENCED_PARAMETER 展开传递的参数或表达式,其目的是避免编译器关于未引用参数的警告
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
    
        //创建新的App实例
        AppDelegate app;
        //getInstance 单实例模式 获取其实例 运行 由此进入 AppDelegate类
        return Application::getInstance()->run();
    }

      在main.cpp中我们可以看到仅仅声明了AppDelegate.h,却使用了run()方法,于是进入AppDelegate.h类中:

    class  AppDelegate : private cocos2d::Application

    发现其继承于Application,全局搜索Application,在libcocos2d/win32/CCApplication-win32.h 找到了它,查看它的头文件:

    class CC_DLL Application : public ApplicationProtocol

    发现继承于ApplicationProtocol,再次进入ApplicationProtocol类中查看,

    #ifndef __CC_APPLICATION_PROTOCOL_H__
    #define __CC_APPLICATION_PROTOCOL_H__
    
    #include "platform/CCPlatformMacros.h"
    #include "base/CCAutoreleasePool.h"
    #include "base/ccTypes.h"
    
    NS_CC_BEGIN
    
    /**
     * @addtogroup platform
     * @{
     */
    
    class CC_DLL ApplicationProtocol
    {
    public:
    
        /** Since WINDOWS and ANDROID are defined as macros, we could not just use these keywords in enumeration(Platform).
         *  Therefore, 'OS_' prefix is added to avoid conflicts with the definitions of system macros.
         */
        enum class Platform
        {
            OS_WINDOWS,     /**< Windows */
            OS_LINUX,       /**< Linux */
            OS_MAC,         /**< Mac OS X*/
            OS_ANDROID,     /**< Android */
            OS_IPHONE,      /**< iPhone */
            OS_IPAD,        /**< iPad */
            OS_BLACKBERRY,  /**< BlackBerry */
            OS_NACL,        /**< Native Client in Chrome */
            OS_EMSCRIPTEN,  /**< Emscripten */
            OS_TIZEN,       /**< Tizen */
            OS_WINRT,       /**< Windows Runtime Applications */
            OS_WP8          /**< Windows Phone 8 Applications */
        };
    
        /**
         * @js NA
         * @lua NA
         */
        virtual ~ApplicationProtocol(){
            /** clean auto release pool. */
            PoolManager::destroyInstance();
        }
    
        /**
        * @brief    Implement Director and Scene init code here.
        * @return true    Initialize success, app continue.
        * @return false   Initialize failed, app terminate.
        * @js NA
        * @lua NA
        */
        virtual bool applicationDidFinishLaunching() = 0;
    
        /**
        * @brief  This function will be called when the application enters background.
        * @js NA
        * @lua NA
        */
        virtual void applicationDidEnterBackground() = 0;
    
        /**
        * @brief  This function will be called when the application enters foreground.
        * @js NA
        * @lua NA
        */
        virtual void applicationWillEnterForeground() = 0;
    
        /**
        * @brief    Callback by Director for limit FPS.
        * @param interval The time, expressed in seconds, between current frame and next.
        * @js NA
        * @lua NA
        */
        virtual void setAnimationInterval(float interval) = 0;
        virtual void setAnimationInterval(float interval, SetIntervalReason reason) = 0;
    
        /** Subclass override the function to set OpenGL context attribution instead of use default value.
        * And now can only set six attributions:redBits,greenBits,blueBits,alphaBits,depthBits,stencilBits.
        * Default value are(5,6,5,0,16,0), usually use as follows:
        * void AppDelegate::initGLContextAttrs(){
        *     GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};
        *     GLView::setGLContextAttrs(glContextAttrs);
        * }
        */
        virtual void initGLContextAttrs() {}
    
        /**
        @brief Get current language config.
        @return Current language config.
        * @js NA
        * @lua NA
        */
        virtual LanguageType getCurrentLanguage() = 0;
        
        /**
         @brief Get current language iso 639-1 code.
         @return Current language iso 639-1 code.
         * @js NA
         * @lua NA
         */
        virtual const char * getCurrentLanguageCode() = 0;
        
        /**
         @brief Get target platform.
         * @js NA
         * @lua NA
         */
        virtual Platform getTargetPlatform() = 0;
        
        /**
         @brief Get application version.
         * @js NA
         * @lua NA
         */
        virtual std::string getVersion() = 0;
        
        /**
         @brief Open url in default browser.
         @param String with url to open.
         @return True if the resource located by the URL was successfully opened; otherwise false.
         * @js NA
         * @lua NA
         */
        virtual bool openURL(const std::string &url) = 0;
    };
    
    // end of platform group
    /** @} */
    
    NS_CC_END
    
    #endif    // __CC_APPLICATION_PROTOCOL_H__

       在这个类中,首先是定义了各个平台的枚举变量,其他的都是虚函数,在不同平台下,不同的类继承这些接口实现跨平台,来到了父类,接下来去实现这些虚方法的win32子类去看一下,在头文件中看它的一些方法声明:

    #ifndef __CC_APPLICATION_WIN32_H__
    #define __CC_APPLICATION_WIN32_H__
    
    #include "platform/CCPlatformConfig.h"
    #if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
    
    #include "platform/CCStdC.h"
    #include "platform/CCCommon.h"
    #include "platform/CCApplicationProtocol.h"
    #include <string>
    
    NS_CC_BEGIN
    
    class Rect;
    
    class CC_DLL Application : public ApplicationProtocol
    {
    public:
        /**
         * @js ctor
         */
        Application();
        /**
         * @js NA
         * @lua NA
         */
        virtual ~Application();
    
        /**
        @brief    Run the message loop.
        */
        int run();
    
        /**
        @brief获取当前的应用程序实例。
        @return当前应用程序实例指针。
        */
        static Application* getInstance();
    
        /** @deprecated Use getInstance() instead */
        CC_DEPRECATED_ATTRIBUTE static Application* sharedApplication();
        
        /* override functions */
        virtual void setAnimationInterval(float interval) override;
        virtual void setAnimationInterval(float interval, SetIntervalReason reason) override;
    
        virtual LanguageType getCurrentLanguage();
    
        virtual const char * getCurrentLanguageCode();
        
        /**
         @brief Get target platform
         */
        virtual Platform getTargetPlatform();
        
        /**
        @brief Get application version
        */
        virtual std::string getVersion() override;
    
        /**
        @brief在默认浏览器中打开网址
        @param打开url的字符串。
        如果成功打开了URL所在的资源,则@return为true;否则是假的。
         */
        virtual bool openURL(const std::string &url);
    
        /**
        *设置资源根路径。
        * @deprecated请改用FileUtils :: getInstance() - > setSearchPaths()。
         */
        CC_DEPRECATED_ATTRIBUTE void setResourceRootPath(const std::string& rootResDir);
    
        /** 
         *  Gets the Resource root path.
         *  @deprecated Please use FileUtils::getInstance()->getSearchPaths() instead. 
         */
        CC_DEPRECATED_ATTRIBUTE const std::string& getResourceRootPath(void);
    
        void setStartupScriptFilename(const std::string& startupScriptFile);
    
        const std::string& getStartupScriptFilename(void)
        {
            return _startupScriptFilename;
        }
    
    protected:
        HINSTANCE           _instance;
        HACCEL              _accelTable;
        LARGE_INTEGER       _animationInterval;
        std::string         _resourceRootPath;
        std::string         _startupScriptFilename;
    
        static Application * sm_pSharedApplication;
    };
    
    NS_CC_END
    
    #endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
    
    #endif    // __CC_APPLICATION_WIN32_H__

      从上往下看,第一个函数是:

        int run();

    它的注释仅仅是:运行消息循环。  进入这个函数发现它做的事情不简单,代码如下:

        UINT TARGET_RESOLUTION = 1; //     1毫秒的目标分辨率
        TIMECAPS tc;
        UINT wTimerRes = 0;
        if (TIMERR_NOERROR == timeGetDevCaps(&tc, sizeof(TIMECAPS)))
        {
            wTimerRes = std::min(std::max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax);
            timeBeginPeriod(wTimerRes);
        }

    经过查阅资料,弄明白这段首先是更改了window下的计时器的精度,调整为1毫秒;

    initGLContextAttrs();

    初始化OpenGL属性;

        if (!applicationDidFinishLaunching())
        {
            return 1;
        }

    初始化cocos实例,成功继续,不成功返回1;

        while(!glview->windowShouldClose())
        {
            QueryPerformanceCounter(&nNow);
            interval = nNow.QuadPart - nLast.QuadPart;
            if (interval >= _animationInterval.QuadPart)
            {
                nLast.QuadPart = nNow.QuadPart;
                director->mainLoop();
                glview->pollEvents();
            }
            else
            {
                waitMS = (_animationInterval.QuadPart - interval) * 1000LL / freq.QuadPart - 1L;
                if (waitMS > 1L)
                    Sleep(waitMS);
            }
        }

    这一段所做的事情,就是一个死循环,不停的调用  director->mainLoop();  glview->pollEvents(); 看了注释,和之后的代码,就是不停的刷新,并且在win平台上加了个保护,因为win平台的调度器精度缺失,放在下一帧给cpu处理;

        if (glview->isOpenGLReady())
        {
            director->end();
            director->mainLoop();
            director = nullptr;
        }
        glview->release();
        if (wTimerRes != 0)
        {
            timeEndPeriod(wTimerRes);
        }

    这两个就是关闭显示和主循环,win调度器。

      看完run()函数,接下来一看就是个单实例模式:

        static Application* getInstance();

    在实现中也是获取Application的唯一实例;

        virtual void setAnimationInterval(float interval) override;
        virtual void setAnimationInterval(float interval, SetIntervalReason reason) override;

    这两个是FPS的函数;紧接着几个获取当前语言类型,平台类型,当前版本,打开网址链接的函数

        CC_DEPRECATED_ATTRIBUTE void setResourceRootPath(const std::string& rootResDir);

    设置根资源路径,我们在代码中使用FileUtils :: getInstance()->setSearchPaths()代替,就是搜索你的代码和资源的路径;

        CC_DEPRECATED_ATTRIBUTE const std::string& getResourceRootPath(void);

    获取路径;

        void setStartupScriptFilename(const std::string& startupScriptFile);

    设置开始脚本名字,这个由于没有使用脚本文件,没有仔细去看;

      整个循环到这里也差不多了,进入后台,和进入前台代码并没有分析,在上一节的目录结构就能发现,每一个平台都有一个自己对应的工程,现在发现了一个ApplicationProtocol的父类,每个平台有自己不同的Application来实现对应的方法驱动整个程序,在其中调用run()方法实现启动,在这个引擎中最重要的 Director  Layer  Scene  Sprite 这几个类,他们之间存在这层级关系,之后可以一级一级的去看。

  • 相关阅读:
    实验二 用机器指令和汇编指令编程
    实验1查看CPU和内存,用机器指令和汇编语言指令编程
    汇编第9~15章——汇编基础知识梳理与总结
    汇编第5~8章——基础知识梳理与总结
    实验9 根据材料编程
    实验5 编写、调试具有多个段的程序
    实验4 [BX]和loop指令
    实验3 编程、编译、连接、跟踪
    实验2 用机器指令和汇编指令编程
    实验1 查看CPU和内存,用机器指令和汇编指令编程
  • 原文地址:https://www.cnblogs.com/zhangthree/p/10494382.html
Copyright © 2020-2023  润新知