Cocos2d-luaでのMac / iOS起動プロセス

Cocos2d-luaでのMac / iOS起動プロセス


序文

詳細なソースコードで、Application、ApplicationProtocol、AppDelegateの3つのクラスの役割とそれらの関係を学び、cocos2d-luaでのmac / iosの起動プロセスを理解します。
AppController—> AppDelegate—> cocos2d :: Application(ios / mac):: run()under ios / mac


ヒント:以下はこの記事の内容であり、以下のケースは参照用です

1.新しいcocos2d-luaプロジェクト

コマンドを使用した新しいプロジェクト

cocos new -l lua -p com.game.myluatest -d ./ MyGameLuaTest

2. xcodeを使用して/MyGameLuaTest.xcodeprojプロジェクトを開きます

xcodeを使用して、MyGameLuaTest / frameworks / runtime-src / proj.ios_mac / MyGameLuaTest.xcodeprojプロジェクトを開きます。左側のプロジェクトコードでは、MyGameLuaTestの下のios / macが、対応するプラットフォームの起動ソースコードです。

1. iOSでのAppController.mmのソースコード:

// cocos2d application instance
static AppDelegate s_sharedApplication;

プログラムが終了するまで、自動的に破棄される静的なグローバルAppDegateオブジェクトを作成します。

2.次に、AppDelegate.hのソースコードを確認します。

class  AppDelegate : private cocos2d::Application
{
    
    
public:
    AppDelegate();
    virtual ~AppDelegate();

    virtual void initGLContextAttrs();

    /**
    @brief    Implement Director and Scene init code here.
    @return true    Initialize success, app continue.
    @return false   Initialize failed, app terminate.
    */
    virtual bool applicationDidFinishLaunching();

    /**
    @brief  The function be called when the application enter background
    @param  the pointer of the application
    */
    virtual void applicationDidEnterBackground();

    /**
    @brief  The function be called when the application enter foreground
    @param  the pointer of the application
    */
    virtual void applicationWillEnterForeground();
};

これは、AppDelegateがApplicationを継承していることを示しています。AppDelegateクラスによって実装される4つのメソッドがあります。これらの4つのメソッドはApplicationProtocolから来ています。

以下は、ApplicationProtocol.hのソースコードです。

    /** 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    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;

ただし、cocos2d :: ApplicationはApplicationProtocolを継承し、AppDelegateには次の4つのメソッドしかありません:
1.initGLContextAttrs:initialize glContext;
2.applicationDidFinishLaunching:appがロードされ、このメソッドはDirectorおよびSceneの初期化を実装します;
3.applicationDidEnterBackground:appは背景に入りますときにコールバックメソッド;
4.applicationWillEnterForeground:アプリがフォアグラウンドに入ったときのコールバックメソッド

Cocos2dxは、アプリプロキシを設定し、AppDelegateのコードを変更するだけでクロスプラットフォーム関数を実装します。つまり、バックグラウンドに戻るときに、使用頻度の低いアーツキャッシュやサイエンスキャッシュをクリアするなど、一部の関数を実装する必要がある場合は、applicationDidEnterBackgroundメソッドを使用するだけです。クロスプラットフォームの効果を実現できます。つまり、すべてのプラットフォーム(ios / mac / android / win32 / winrt / linux)が同時に適用されます。なぜ、次のコードを引き続き見てください。

2.次に、CCApplication.hのソースコードを確認します。

#if CC_TARGET_PLATFORM == CC_PLATFORM_MAC
#include "platform/mac/CCApplication-mac.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_IOS
#include "platform/ios/CCApplication-ios.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include "platform/android/CCApplication-android.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#include "platform/win32/CCApplication-win32.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_WINRT
#include "platform/winrt/CCApplication.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_LINUX
#include "platform/linux/CCApplication-linux.h"
#endif

ヘッダーファイルのソースコードで、異なるプラットフォームで異なるCCApplicationヘッダーファイルを導入する

4.例として、CCApplication-ios.h / CCApplication-ios.mmのソースコードを取り上げます。

CCApplication-ios.hのソースコードは次のとおりです。継承されたApplicationProtocol

//在CCApplication-ios.h文件中
class CC_DLL Application : public ApplicationProtocol
...省略若干
/**
@brief    Run the message loop.
*/
int run();
    
/**
@brief    Get the current application instance.
@return Current application instance pointer.
*/
static Application* getInstance();

protected:
    static Application * sm_pSharedApplication;

CCApplication-ios.mmのソースコードは次のとおりです。

Application* Application::sm_pSharedApplication = 0;

Application::Application()
{
    
    
    CC_ASSERT(! sm_pSharedApplication);
    sm_pSharedApplication = this;
}
/
// static member function
//

Application* Application::getInstance()
{
    
    
    CC_ASSERT(sm_pSharedApplication);
    return sm_pSharedApplication;
}

最初のポイントでAppController.mmのソースコードに戻り、グローバルな静的AppDelegateオブジェクトを初期化します。実際には、親クラスのCCApplicationパラメータなしコンストラクタがデフォルトで呼び出されます。つまり、2番目の例CCApplication-ios.mmの静的メンバー変数sm_pSharedApplicationは、独自のCCApplicationオブジェクトインスタンスへのポインターです。したがって、cocos2d :: Application * app = cocos2d :: Application :: getInstance()は、各プラットフォームでCCApplicationオブジェクトのインスタンスを返します。

AppController.mmソースコード:

// cocos2d application instance
static AppDelegate s_sharedApplication;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    
    
    cocos2d::Application *app = cocos2d::Application::getInstance();
    ...省略若干行代码
    //run the cocos2d-x game scene
    app->run();

    return YES;
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
    
    
    /*
     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
     If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
     */
    cocos2d::Application::getInstance()->applicationDidEnterBackground();
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
    
    
    /*
     Called as part of  transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
     */
    cocos2d::Application::getInstance()->applicationWillEnterForeground();
}

1. appController.mmでapp-> run();メソッドが呼び出されると、CCApplication親クラスApplicationProtocolのapplicationDidFinishLaunchingメソッドが呼び出されますが、実装はAppDelegateファイルにのみあります。
2. ios AppController.mmがapplicationDidEnterBackgroundメソッドに入ると(アプリケーションはバックグラウンドに移動します)、cocos2d :: Application :: getInstance()-> applicationDidEnterBackground();を
呼び出します。3。iosAppControllerがapplicationWillEnterForegroundyに入ると、アプリケーションはフォアグラウンドになります)。 :Application :: getInstance()-> applicationWillEnterForeground();

CCApplication-ios.mmソースコード:

int Application::run()
{
    
    
    if (applicationDidFinishLaunching()) 
    {
    
    
        [[CCDirectorCaller sharedDirectorCaller] startMainLoop];
    }
    return 0;
}

次に、[[CCDirectorCaller sharedDirectorCaller] startMainLoop]を呼び出します。
つまり、CCDirectorCallerのstartMainLoopがiosの画面更新タイマーを開始します。CADisplayLinkは、画面のリフレッシュレートと同じ頻度で画面にコンテンツを描画できるタイマーです。ソースコードで新しいCADisplayLinkオブジェクトを作成し、それをrunloopに追加し、画面が更新されたときに呼び出されるターゲットとセレクターを提供します。画面が更新されるたびに呼び出されます

cocos2d :: Director * director = cocos2d :: Director :: getInstance();
director-> mainLoop(dt)

CCDirectorCaller.mmソースコード:

-(void) startMainLoop
{
    
    
    // Director::setAnimationInterval() is called, we should invalidate it first
    [self stopMainLoop];
    
    displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doCaller:)];
    [displayLink setFrameInterval: self.interval];
    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
-(void) doCaller: (id) sender
{
    
    
    if (isAppActive) {
    
    
        cocos2d::Director* director = cocos2d::Director::getInstance();
        EAGLContext* cocos2dxContext = [(CCEAGLView*)director->getOpenGLView()->getEAGLView() context];
        if (cocos2dxContext != [EAGLContext currentContext])
            glFlush();
        
        [EAGLContext setCurrentContext: cocos2dxContext];

        CFTimeInterval dt = ((CADisplayLink*)displayLink).timestamp - lastDisplayTime;
        lastDisplayTime = ((CADisplayLink*)displayLink).timestamp;
        director->mainLoop(dt);
    }
}

この時点で、正式にCocos2dxメインループに入ります。

CCDirector.cppソースコード:

void Director::mainLoop(float dt)
{
    
    
    _deltaTime = dt;
    _deltaTimePassedByCaller = true;
    mainLoop();
}
void Director::mainLoop()
{
    
    
    if (_purgeDirectorInNextLoop)
    {
    
    
        _purgeDirectorInNextLoop = false;
        purgeDirector();
    }
    else if (_restartDirectorInNextLoop)
    {
    
    
        _restartDirectorInNextLoop = false;
        restartDirector();
    }
    else if (! _invalid)
    {
    
    
        drawScene();
     
        // release the objects
        PoolManager::getInstance()->getCurrentPool()->clear();
    }
}

2. MacでのInfo.plist

総括する

例としてiOS起動プロセスを取り上げます。AppController.mmファイルでAppDelegateオブジェクトを作成し、AppDelegateがCCApplicationを継承し、CCApplicationがApplicationProtocolを継承します。次に、AppController.mmがCCApplicationのrunメソッドを呼び出し、runメソッドがApplicationProtocolのapplicationDidFinishLaunchingメソッドを呼び出します。 (実装メソッドはAppDelegateにあります)、および画面の更新をiosで開くタイマーCADisplayLinkは、画面が更新されるたびにdoCallerメソッドを呼び出し、このメソッドはCCDirectorでmainLoop(dt)メソッドを実行して、Cocos2dxのメインループに入りますの中で。

おすすめ

転載: blog.csdn.net/Suarez1987/article/details/108704233