首页 > 代码库 > cocos2d-x 3.1.1源码阅读过程的注释

cocos2d-x 3.1.1源码阅读过程的注释

cocos2d-x 3.1.1源码阅读过程的注释
印象笔记链接:http://app.yinxiang.com/l/AAU8F1mKiN9BIqFopReAU3ZbTcgGOULycQo/
Ref
每个类的基类是Ref   也就是2.0的CCObject 调用继承下来的下面的那个函数

class CC_DLL Ref
{
public:
   /**
引用计数+1
     */
    void retain();
{
    CCASSERT(_referenceCount > 0, "reference count should greater than 0" );
    ++_referenceCount;
}
    /**
引用计数-1
     */
    void release();
{
    CCASSERT(_referenceCount > 0, "reference count should greater than 0" );
    --_referenceCount;
    if (_referenceCount == 0)
    {
#if defined (COCOS2D_DEBUG) && ( COCOS2D_DEBUG > 0)
        auto poolManager = PoolManager ::getInstance();
        if (!poolManager->getCurrentPool()->isClearing() && poolManager->isObjectInPools( this))
        {
            // 错误实例1: 
            // auto obj = Node::create();  
            // obj->autorelease(); 
            //create函数里面封装了 autorelease
       
            // 错误实例2:
            // auto obj = Node::create();
            // obj->release();   // Wrong: obj is an autorelease Ref, it will be released when clearing current pool.

            CCASSERT(false , "The reference shouldn‘t be 0 because it is still in autorelease pool.");
        }
#endif

#if CC_USE_MEM_LEAK_DETECTION
        untrackRef( this);
#endif
        delete this ;
    }
    /**
     * 自动释放  也就是当前的AutoReleasePool被调用了析构函数之后  引擎全局有一个AutoReleasePool
     */
    Ref* autorelease();
{
    PoolManager::getInstance()->getCurrentPool()->addObject( this);
    return this;
}
    /**
     * 返回引用数量
     */
    unsigned int getReferenceCount() const ;

protected:
    /**
     * 在构造了之后引用计数是1!!!!!
     */
    Ref()
: _referenceCount(1) // when the Ref is created, the reference count of it is 1
{
#if CC_ENABLE_SCRIPT_BINDING
    static unsigned int uObjectCount = 0;
    _luaID = 0;
    _ID = ++uObjectCount;
#endif
#if CC_USE_MEM_LEAK_DETECTION
    trackRef(this);
#endif
}

public:
    virtual ~Ref();
protected:
    /// count of references
    unsigned int _referenceCount;
    friend class AutoreleasePool ;
#if CC_ENABLE_SCRIPT_BINDING
public:
    /// object id, ScriptSupport need public _ID
    unsigned int        _ID;
    /// Lua reference id
    int                 _luaID;
#endif
#if CC_USE_MEM_LEAK_DETECTION
public:
    static void printLeaks();
#endif
};






PoolManager类的解析:
class CC_DLL PoolManager
{
public:
     //这个是表示这个接口以后要丢弃
    CC_DEPRECATED_ATTRIBUTE static PoolManager * sharedPoolManager() { return getInstance(); }

  /**
   这里也是十分重要的  整个程序只有一个单例的PoolManager   PoolManager初始化的时候就添加了一个AutoreleasePool 
     */
    static PoolManager* getInstance();
{
    if (s_singleInstance == nullptr)
    {
        s_singleInstance = new PoolManager ();
        // Add the first auto release pool
        s_singleInstance->_curReleasePool = new AutoreleasePool ("cocos2d autorelease pool");
        s_singleInstance->_releasePoolStack.push_back(s_singleInstance->_curReleasePool);
    }
    return s_singleInstance;
}






    CC_DEPRECATED_ATTRIBUTE static void purgePoolManager() { destroyInstance(); }
    static void destroyInstance();
   
    /**
     * 获得现在的释放池, 引擎自己创建了一个autoreleasePool
     * 你可以创建自己的释放池 会放进自动释放池的盏变量里面
     */
    AutoreleasePool *getCurrentPool() const;
{
    return _curReleasePool;
}
    bool isObjectInPools( Ref* obj) const ;

    friend class AutoreleasePool ;
private:
    PoolManager();
    ~PoolManager();
    void push( AutoreleasePool *pool);
{
    _releasePoolStack.push_back( pool);
    _curReleasePool = pool;
}
    void pop();
{
    // 如果是弹出第一个
    CC_ASSERT(_releasePoolStack.size() >= 1);
   
    _releasePoolStack.pop_back();
   
    // 应该更新_curReleasePool 
    if (_releasePoolStack.size() > 1)
    {
        _curReleasePool = _releasePoolStack.back();
    }
}

    static PoolManager* s_singleInstance;//单例模式
    std::deque< AutoreleasePool*> _releasePoolStack;//管理用户创建的自动释放池用的盏
    AutoreleasePool *_curReleasePool;//现在的自动释放池
};

AutoreleasePool
class CC_DLL AutoreleasePool
{
public:
    /**
     * 提示:自动释放池对象要创建在栈里面  不能再堆里面
     * 创建的时候就自动push进PoolManager里面
     */
    AutoreleasePool();
{
    _managedObjectArray.reserve(150);//vector扩大容量
    PoolManager::getInstance()->push( this);
}
    /**
     * 用引用来创建  是为了调试
     */
    AutoreleasePool( const std::string &name);
   {
    _managedObjectArray.reserve(150);
    PoolManager::getInstance()->push( this);
}

// 枚举每一个加进对象池的obj去调用release  并且清空
    ~AutoreleasePool();
{
    CCLOGINFO( "deallocing AutoreleasePool: %p" , this);
    clear();//
    PoolManager::getInstance()->pop();
}
    /**
     * 添加对象到对象池中
     * 对象池销毁的时候会调用
     */
    void addObject( Ref *object);
{
    _managedObjectArray.push_back( object);
}

    /**
    清理对象池   析构函数调用
     */
    void clear();
   {
#if defined (COCOS2D_DEBUG) && ( COCOS2D_DEBUG > 0)
    _isClearing = true;
#endif
    for (const auto &obj : _managedObjectArray)
    {
          //枚举每一个加进对象池的obj去调用release
        obj->release();
    }

     //把vector清空
     _managedObjectArray.clear();
#if defined (COCOS2D_DEBUG) && ( COCOS2D_DEBUG > 0)
    _isClearing = false;
#endif
}



#if defined (COCOS2D_DEBUG) && ( COCOS2D_DEBUG > 0)
    /**
     * Whether the pool is doing `clear` operation.
     */
    bool isClearing() const { return _isClearing; };
#endif
   
    /**
     * 检查是否包含
     * 枚举一遍这个vector
     */
    bool contains( Ref* object) const ;
{
    for (const auto& obj : _managedObjectArray)
    {
        if (obj == object )
            return true ;
    }
    return false;
}


    /**
     * 用来调试
     *
     */
    void dump();
   {
    CCLOG("autorelease pool: %s, number of managed object %d\n", _name.c_str(), static_cast<int >(_managedObjectArray.size()));
    CCLOG("%20s%20s%20s", "Object pointer", "Object id" , "reference count");
    for (const auto &obj : _managedObjectArray)
    {
        CC_UNUSED_PARAM(obj);
        CCLOG("%20p%20u\n" , obj, obj->getReferenceCount());
    }
}


private:
    /**
     * The underlying array of object managed by the pool.
     *
     * Although Array retains the object once when an object is added, proper
     * Ref::release() is called outside the array to make sure that the pool
     * does not affect the managed object‘s reference count. So an object can
     * be destructed properly by calling Ref::release() even if the object
     * is in the pool.
     */
    std::vector< Ref*> _managedObjectArray;
    std::string _name;
   
#if defined (COCOS2D_DEBUG) && ( COCOS2D_DEBUG > 0)
    /**
     *  The flag for checking whether the pool is doing `clear` operation.
     */
    bool _isClearing;
#endif
};



下面这张图是网上找的类图继承图:














cocos2d-x 3.1.1源码阅读过程的注释