cocos2d 在mac上的运行流程

自己记录一下方便以后查询
1.首先是mac下的main方法

int main(int argc, char *argv[])
{
    AppDelegate app;
    return Application::getInstance()->run();
}

乍一看我AppDelegate app好像没用不急继续往下看

2.

//首先看Application的继承
class CC_DLL Application : public ApplicationProtocol//这个类是纯虚类
{
...
}

//构造函数
Application::Application()
: _animationInterval(1.0f/60.0f*1000.0f)
{
    CCASSERT(! sm_pSharedApplication, "sm_pSharedApplication already exist");
    sm_pSharedApplication = this;
}

//
Application* Application::getInstance()
{
    CCASSERT(sm_pSharedApplication, "sm_pSharedApplication not set");
    return sm_pSharedApplication;
}

//
int Application::run()
{
    initGLContextAttrs();
    if(!applicationDidFinishLaunching())//这里我们知道如果是继承了纯虚
    //类也就是抽象类,子类是必须要实现接口才能实例化对象的,但是在这里为什么
    //用这个方法?当然我是不知道的所以记录一下有知道的大佬可以相告一下谢谢,
    //从里是不是有点像代理?进入这里基本上就是进入我们的代码块了之后就是导演
    //类了
    {
        return 1;
    }

    long lastTime = 0L;
    long curTime = 0L;

    auto director = Director::getInstance();
    auto glview = director->getOpenGLView();

    // Retain glview to avoid glview being released in the while loop
    glview->retain();

    while (!glview->windowShouldClose())
    {
        lastTime = getCurrentMillSecond();

        director->mainLoop();//游戏的主循环
        glview->pollEvents();

        curTime = getCurrentMillSecond();
        if (curTime - lastTime < _animationInterval)
        {
            usleep(static_cast<useconds_t>((_animationInterval - curTime + lastTime)*1000));
        }
    }

    /* Only work on Desktop
    *  Director::mainLoop is really one frame logic
    *  when we want to close the window, we should call Director::end();
    *  then call Director::mainLoop to do release of internal resources
    */
    if (glview->isOpenGLReady())
    {
        director->end();
        director->mainLoop();
    }

    glview->release();

    return 0;
}

3.现在我们看一下导演类

//具体很复杂我是看不懂

class CC_DLL Director : public Ref
{
...
    virtual void mainLoop() = 0;
...
}
也是抽象类

//继续看
class DisplayLinkDirector : public Director
{
public:
    DisplayLinkDirector() 
        : _invalid(false)
    {}
    virtual ~DisplayLinkDirector(){}

    //
    // Overrides
    //
    virtual void mainLoop() override;
    virtual void setAnimationInterval(float value) override;
    virtual void startAnimation() override;
    virtual void stopAnimation() override;

protected:
    bool _invalid;
};
这些个纯虚方法由这个类来实现,在看看这个类的mainLoop()

void DisplayLinkDirector::mainLoop()
{
    if (_purgeDirectorInNextLoop)
    {
        _purgeDirectorInNextLoop = false;
        purgeDirector();
    }
    else if (_restartDirectorInNextLoop)
    {
        _restartDirectorInNextLoop = false;
        restartDirector();
    }
    else if (! _invalid)
    {
        drawScene();//渲染场景,后期有时间在补上这里

        // release the objects
        PoolManager::getInstance()->getCurrentPool()->clear();//这个就是引用计数具体需要到里面看看了
    }
}

//
void AutoreleasePool::clear()
{
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
    _isClearing = true;
#endif
    std::vector<Ref*> releasings;//局部变量
    releasings.swap(_managedObjectArray);//可以百度一下这个,就是这个泛
    //型方法可以创建零时对象,而零时对象又会在出函数的时候会自动销毁并调用析构
    //函数,其实智能指针也是类似这种方法的用一个对象去包裹一个指针,这样可以让
    //指针能够正确的释放,还有很多这样的用法。。。

    //循环调用在引用池中的对象的release()方法,然后引用计数会 -1,记住并不是
    //每次循环都会 -1,只是创建的时候被放入计数池然后加入父节点中引用计数会 +1
    //如果没加入父节点,就会在一帧之后会调用release(),然后引用计数会变为0,
    //之后就会释放该对象
    for (const auto &obj : releasings)
    {
        obj->release();
    }
#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
    _isClearing = false;
#endif
}

//
void Ref::release()
{
    CCASSERT(_referenceCount > 0, "reference count should be greater than 0");
    --_referenceCount;

    if (_referenceCount == 0)
    {
        ...
        delete this;
    }
}
//

猜你喜欢

转载自blog.csdn.net/qq_36104832/article/details/78356769
今日推荐