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

};

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

时间: 2024-10-16 14:26:07

cocos2d-x 3.1.1源码阅读过程的注释的相关文章

源码阅读的方法

小弟我入行不久,实打实的菜鸟,最近由于个人兴趣和工作需要,读了一些源码,感觉还不错,谨以此文做个小小的总结以达到抛砖引玉之效,如有错误和不足的地方希望各位补充. 感谢开源,让我这种并没有受过系统的软件开发训练的工程师也能学习到业界一流的代码,并通过源代码和一些顶尖的程序员零距离的对话.源码对于我这种经验算不上丰富的小白来说是恐怖的,但真正开始的时候却也是魅力无限的,当全身心地沉浸在代码中时,专注和兴奋度远大于听一次讲座或者看一本书,但如果方法不对则很有可能刚刚形成的勇气和兴趣会被无情地摧毁. 我

muduo2.0源码阅读记录

花了20天的时间读了陈硕先生的<Linux多线程服务端编程>一书的前8章.当然,每天阅读的时间并不算多,中间有些部分也反反复复看了几遍,最后也算是能勉强接受作者传授的知识.配合书把muduo2.0网络部分的代码和日志库代码细读了一遍,这也算是个人第一次较为深入地去读取一个开源项目源码.通过书和源码的阅读,确实是对不少东西加深了理解. 本来想按自己的理解来写源码阅读笔记的,但考虑到网上关于muduo代码的解析文章已经很多并且写的很好了,就放弃了这个想法.摘录几个自己在源码阅读过程中参考的网页:

源码阅读心得

一.看源码的正确方法 改页面.看源码一定记得debugger,在debugger的过程一个个函数跳进去看,然后看每跳过一个每个函数对应页面效果的变化,这样才能快速看懂不同函数的功能. 1.1 利用身边好工具 双屏模式下秒用控制台窗口,第一个会把控制台和页面分成2个页面,双屏很方便. 1.2 分块看 1.2.1 如上面的页面,就分为左.中.右三部分去深入细节看. 1.2.2 在控制台中找要看的功能对应的关键词class或者id:编译器中全局搜索这个关键词,以这个为入口延伸拓展着去看一系列相关的函数

CI框架源码阅读笔记3 全局函数Common.php

从本篇开始,将深入CI框架的内部,一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说,全局函数具有最高的加载优先权,因此大多数的框架中BootStrap引导文件都会最先引入全局函数,以便于之后的处理工作). 打开Common.php中,第一行代码就非常诡异: if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 上一篇(CI框架源码阅读笔记2 一切的入口 index

淘宝数据库OceanBase SQL编译器部分 源码阅读--生成逻辑计划

body, td { font-family: tahoma; font-size: 10pt; } 淘宝数据库OceanBase SQL编译器部分 源码阅读--生成逻辑计划 SQL编译解析三部曲分为:构建语法树,生成逻辑计划,指定物理执行计划.第一步骤,在我的上一篇博客淘宝数据库OceanBase SQL编译器部分 源码阅读--解析SQL语法树里做了介绍,这篇博客主要研究第二步,生成逻辑计划. 一. 什么是逻辑计划?我们已经知道,语法树就是一个树状的结构组织,每个节点代表一种类型的语法含义.如

JDK部分源码阅读与理解

本文为博主原创,允许转载,但请声明原文地址:http://www.coselding.cn/article/2016/05/31/JDK部分源码阅读与理解/ 不喜欢重复造轮子,不喜欢贴各种东西.JDK代码什么的,让整篇文章很乱...JDK源码谁都有,没什么好贴的...如果你没看过JDK源码,建议打开Eclipse边看源码边看这篇文章,看过的可以把这篇文章当成是知识点备忘录... JDK容器类中有大量的空指针.数组越界.状态异常等异常处理,这些不是重点,我们关注的应该是它的一些底层的具体实现,这篇

如何阅读Java源码 阅读java的真实体会

刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心. 说到技术基础,我打个比方吧,如果你从来没有学过Java,或是任何一门编程语言如C++,一开始去啃<Core Java>,你是很难从中吸收到营养的,特别是<深入Java虚拟机>这类书,别人觉得好,未必适合现在的你. 虽然Tomcat的源码很漂亮,但我绝不建议你一开始就读它.我文中会专门谈到这个,暂时不展开. 强烈

Memcache-Java-Client-Release源码阅读(之七)

一.主要内容 本章节的主要内容是介绍Memcache Client的Native,Old_Compat,New_Compat三个Hash算法的应用及实现. 二.准备工作 1.服务器启动192.168.0.106:11211,192.168.0.106:11212两个服务端实例. 2.示例代码: String[] servers = { "192.168.0.106:11211", "192.168.0.106:11212" }; SockIOPool pool =

源码阅读笔记 - 1 MSVC2015中的std::sort

大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格式化,去掉或者展开用于条件编译或者debug检查的宏,依重要程度重新排序函数,但是不会改变命名方式(虽然MSVC的STL命名实在是我不能接受的那种),对于代码块的解释会在代码块前(上面)用注释标明. template<class _RanIt, class _Diff, class _Pr> in