首页 技术 正文
技术 2022年11月14日
0 收藏 431 点赞 2,876 浏览 7505 个字

  任何程序都有入口,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() = ; /**
* @brief This function will be called when the application enters background.
* @js NA
* @lua NA
*/
virtual void applicationDidEnterBackground() = ; /**
* @brief This function will be called when the application enters foreground.
* @js NA
* @lua NA
*/
virtual void applicationWillEnterForeground() = ; /**
* @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) = ;
virtual void setAnimationInterval(float interval, SetIntervalReason reason) = ; /** 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() = ; /**
@brief Get current language iso 639-1 code.
@return Current language iso 639-1 code.
* @js NA
* @lua NA
*/
virtual const char * getCurrentLanguageCode() = ; /**
@brief Get target platform.
* @js NA
* @lua NA
*/
virtual Platform getTargetPlatform() = ; /**
@brief Get application version.
* @js NA
* @lua NA
*/
virtual std::string getVersion() = ; /**
@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) = ;
};// 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_BEGINclass 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毫秒的目标分辨率
TIMECAPS tc;
UINT wTimerRes = ;
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 ;
}

初始化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 != )
{
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 这几个类,他们之间存在这层级关系,之后可以一级一级的去看。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,487
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,903
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,736
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,486
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,126
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,289