Cocos2d-x源码啃食第一谈
2015-10-10 10:25
363 查看
第一篇博客,先鼓个掌纪念一下,啪啪啪啪。。。
正文开始。
从 CCRef.h 开始
关于开始的 CC_DLL,f12并没有查到定义,后来到论坛,具体解释http://www.ziliao1.com/Article/Show/716662CB4AD94EB2D020C3E74EA62A4C.html
在cpp文件中为
在cpp文件中为
还有一个getReferenceCount函数,用于返回计数,代码就不贴了。
看看构造和析构。
首先是构造
_ID 和_luaID
析构
手贱对removeScriptObjectByObject多摁了几次f12
最后还有一段
第一次写博客,主要是为了记录学习过程,做个笔记。要是哪位大神看见了有什么不对的地方还望指出。
正文开始。
从 CCRef.h 开始
/** Interface that defines how to clone an Ref */ class CC_DLL Clonable { public: /** returns a copy of the Ref 返回一个Ref的拷贝*/ virtual Clonable* clone() const = 0; /** * @js NA * @lua NA */ virtual ~Clonable() {}; /** returns a copy of the Ref. @deprecated Use clone() instead */ CC_DEPRECATED_ATTRIBUTE Ref* copy() const { // use "clone" instead CC_ASSERT(false); return nullptr; } };
关于开始的 CC_DLL,f12并没有查到定义,后来到论坛,具体解释http://www.ziliao1.com/Article/Show/716662CB4AD94EB2D020C3E74EA62A4C.html
class CC_DLL Ref { public: /** * Retains the ownership.保持所有权 * * This increases the Ref's reference count.增加计数引用 * * @see release, autorelease * @js NA */ void retain();
在cpp文件中为
void Ref::retain() { CCASSERT(_referenceCount > 0, "reference count should greater than 0"); ++_referenceCount; }
/** * Release the ownership immediately.立即释放所有权 * * This decrements the Ref's reference count.缩减计数 * * If the reference count reaches 0 after the descrement, this Ref is * destructed.如果释放后为0,将自毁 * * @see retain, autorelease * @js NA */ void release();
在cpp文件中为
void Ref::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)) { // Trigger an assert if the reference count is 0 but the Ref is still in autorelease pool. // This happens when 'autorelease/release' were not used in pairs with 'new/retain'. // // Wrong usage (1): // // auto obj = Node::create(); // Ref = 1, but it's an autorelease Ref which means it was in the autorelease pool. // obj->autorelease(); // Wrong: If you wish to invoke autorelease several times, you should retain `obj` first. // // Wrong usage (2): // // auto obj = Node::create(); // obj->release(); // Wrong: obj is an autorelease Ref, it will be released when clearing current pool. // // Correct usage (1): // // auto obj = Node::create(); // |- new Node(); // `new` is the pair of the `autorelease` of next line // |- autorelease(); // The pair of `new Node`. // // obj->retain(); // obj->autorelease(); // This `autorelease` is the pair of `retain` of previous line. // // Correct usage (2): // // auto obj = Node::create(); // obj->retain(); // obj->release(); // This `release` is the pair of `retain` of previous line. CCASSERT(false, "The reference shouldn't be 0 because it is still in autorelease pool."); } #endif delete this; } }
/** * Release the ownership sometime soon automatically.自动释放 * * This descrements the Ref's reference count at the end of current在流的末尾自动测量计数 * autorelease pool block. * * If the reference count reaches 0 after the descrement, this Ref is * destructed. * * @returns The Ref itself. * * @see AutoreleasePool, retain, release * @js NA * @lua NA */ Ref* autorelease();
Ref* Ref::autorelease() { PoolManager::getInstance()->getCurrentPool()->addObject(this);//PoolManager用于‘池’管理,获取这个Ref对象后,通过<span style="font-family: Arial, Helvetica, sans-serif;">getCurrentPool加入自动释放池</span> return this; }
还有一个getReferenceCount函数,用于返回计数,代码就不贴了。
看看构造和析构。
首先是构造
Ref::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 }
_ID 和_luaID
public: /// object id, ScriptSupport need public _ID unsigned int _ID; /// Lua reference id int _luaID;
析构
Ref::~Ref() { #if CC_ENABLE_SCRIPT_BINDING // if the object is referenced by Lua engine, remove it if (_luaID) { ScriptEngineManager::getInstance()->getScriptEngine()->removeScriptObjectByObject(this); } else { ScriptEngineProtocol* pEngine = ScriptEngineManager::getInstance()->getScriptEngine(); if (pEngine != NULL && pEngine->getScriptType() == kScriptTypeJavascript) { pEngine->removeScriptObjectByObject(this); } } #endif }
手贱对removeScriptObjectByObject多摁了几次f12
void LuaEngine::removeScriptObjectByObject(Ref* pObj) { _stack-><span style="color:#ff0000;"><strong>removeScriptObjectByObject</strong></span>(pObj); ScriptHandlerMgr::getInstance()-><strong><span style="color:#33ccff;">removeObjectAllHandlers</span></strong>(pObj); }
void LuaStack::<strong><span style="color:#ff0000;">removeScriptObjectByObject</span></strong>(Ref* pObj) { <span style="color:#ff0000;"><strong>toluafix_remove_ccobject_by_refid</strong></span>(_state, pObj->_luaID); }
TOLUA_API int <span style="color:#ff0000;"><strong>toluafix_remove_ccobject_by_refid</strong></span>(lua_State* L, int refid) { void* ptr = NULL; const char* type = NULL; void** ud = NULL; if (refid == 0) return -1; // get ptr from tolua_refid_ptr_mapping lua_pushstring(L, TOLUA_REFID_PTR_MAPPING); lua_rawget(L, LUA_REGISTRYINDEX); /* stack: refid_ptr */ lua_pushinteger(L, refid); /* stack: refid_ptr refid */ lua_rawget(L, -2); /* stack: refid_ptr ptr */ ptr = lua_touserdata(L, -1); lua_pop(L, 1); /* stack: refid_ptr */ if (ptr == NULL) { lua_pop(L, 1); // Lua stack has closed, C++ object not in Lua. // printf("[LUA ERROR] remove CCObject with NULL ptr, refid: %d\n", refid); return -2; } // remove ptr from tolua_refid_ptr_mapping lua_pushinteger(L, refid); /* stack: refid_ptr refid */ lua_pushnil(L); /* stack: refid_ptr refid nil */ lua_rawset(L, -3); /* delete refid_ptr[refid], stack: refid_ptr */ lua_pop(L, 1); /* stack: - */ // get type from tolua_refid_type_mapping lua_pushstring(L, TOLUA_REFID_TYPE_MAPPING); lua_rawget(L, LUA_REGISTRYINDEX); /* stack: refid_type */ lua_pushinteger(L, refid); /* stack: refid_type refid */ lua_rawget(L, -2); /* stack: refid_type type */ if (lua_isnil(L, -1)) { lua_pop(L, 2); printf("[LUA ERROR] remove CCObject with NULL type, refid: %d, ptr: %p\n", refid, ptr); return -1; } type = lua_tostring(L, -1); lua_pop(L, 1); /* stack: refid_type */ // remove type from tolua_refid_type_mapping lua_pushinteger(L, refid); /* stack: refid_type refid */ lua_pushnil(L); /* stack: refid_type refid nil */ lua_rawset(L, -3); /* delete refid_type[refid], stack: refid_type */ lua_pop(L, 1); /* stack: - */ // get ubox luaL_getmetatable(L, type); /* stack: mt */ lua_pushstring(L, "tolua_ubox"); /* stack: mt key */ lua_rawget(L, -2); /* stack: mt ubox */ if (lua_isnil(L, -1)) { // use global ubox lua_pop(L, 1); /* stack: mt */ lua_pushstring(L, "tolua_ubox"); /* stack: mt key */ lua_rawget(L, LUA_REGISTRYINDEX); /* stack: mt ubox */ }; // cleanup root tolua_remove_value_from_root(L, ptr); lua_pushlightuserdata(L, ptr); /* stack: mt ubox ptr */ lua_rawget(L,-2); /* stack: mt ubox ud */ if (lua_isnil(L, -1)) { // Lua object has released (GC), C++ object not in ubox. //printf("[LUA ERROR] remove CCObject with NULL ubox, refid: %d, ptr: %x, type: %s\n", refid, (int)ptr, type); lua_pop(L, 3); return -3; } // cleanup peertable lua_pushvalue(L, LUA_REGISTRYINDEX); lua_setfenv(L, -2); ud = (void**)lua_touserdata(L, -1); lua_pop(L, 1); /* stack: mt ubox */ if (ud == NULL) { printf("[LUA ERROR] remove CCObject with NULL userdata, refid: %d, ptr: %p, type: %s\n", refid, ptr, type); lua_pop(L, 2); return -1; } // clean userdata *ud = NULL; lua_pushlightuserdata(L, ptr); /* stack: mt ubox ptr */ lua_pushnil(L); /* stack: mt ubox ptr nil */ lua_rawset(L, -3); /* ubox[ptr] = nil, stack: mt ubox */ lua_pop(L, 2); //printf("[LUA] remove CCObject, refid: %d, ptr: %x, type: %s\n", refid, (int)ptr, type); return 0; }
void ScriptHandlerMgr::<span style="color:#00cccc;"><strong>removeObjectAllHandlers</strong></span>(void* object) { if (NULL == object || _mapObjectHandlers.empty()) return; auto iter = _mapObjectHandlers.find(object); if (_mapObjectHandlers.end() != iter) { if (!iter->second.empty()) { auto iterVec = iter->second.begin(); for (; iterVec != iter->second.end(); ++iterVec) { LuaEngine::getInstance()->removeScriptHandle<span style="color:#ffffff;">r</span>(iterVec->second); } (iter->second).clear(); } _mapObjectHandlers.erase(iter); } }
最后还有一段
typedef void (Ref::*SEL_CallFunc)(); typedef void (Ref::*SEL_CallFuncN)(Node*); typedef void (Ref::*SEL_CallFuncND)(Node*, void*); typedef void (Ref::*SEL_CallFuncO)(Ref*); typedef void (Ref::*SEL_MenuHandler)(Ref*); typedef void (Ref::*SEL_SCHEDULE)(float); #define callfunc_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFunc>(&_SELECTOR) #define callfuncN_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFuncN>(&_SELECTOR) #define callfuncND_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFuncND>(&_SELECTOR) #define callfuncO_selector(_SELECTOR) static_cast<cocos2d::SEL_CallFuncO>(&_SELECTOR) #define menu_selector(_SELECTOR) static_cast<cocos2d::SEL_MenuHandler>(&_SELECTOR) #define schedule_selector(_SELECTOR) static_cast<cocos2d::SEL_SCHEDULE>(&_SELECTOR)
第一次写博客,主要是为了记录学习过程,做个笔记。要是哪位大神看见了有什么不对的地方还望指出。
相关文章推荐
- cocos2dx3.8 android打包脚本编写
- quick-cocos2dx3.5 mac模拟器改进
- 火云开发课堂 - 《使用Cocos2d-x 开发3D游戏》系列 第二十三节:3D物理引擎刚体碰撞
- cocos2d-x 3.x 将事件监听添加在层上的具体实现
- cocos代码研究(26)Widget子类RichView学习笔记
- cocos代码研究(25)Widget子类PageView学习笔记
- cocos代码研究(24)Widget子类PageView学习笔记
- 【转载】cocos2d-x2.2.3和android的平台环境
- cocos2d 改掉游戏的图标和开始图片
- Photoshop脚本代码一键生成所有cocos2d项目下的IOS图标
- cocos代码研究(23)Widget子类ScrollView学习笔记
- 【cocos2dx 加载资源目录】
- cocos2d CascadeOpacity 小坑
- 【cocos2dx】卡牌记忆游戏(3)——优化杂谈
- 【cocos2dx】卡牌记忆游戏(2)——游戏场景
- 【cocos2dx】卡牌记忆游戏(1)——卡牌类
- cocos2dx3.3+vs2012 创建项目
- cocos2d js键盘按键相关
- cocos2d-js 入门之碰撞
- Cocos2d-x 3.0 事件系统【转】