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

cocos2d-x 3.1.1源码阅读过程的注释
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
};



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

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...