最近作一個lua異步加載紋理的功能,在C++回調lua函數時,有時會發生崩潰的狀況,緣由多是我直接使用了lua的api對堆棧操做而致使了數據出錯,其實Cocos2dx已經封裝好了相關的api,因此調用Cocos2dx的api就能夠很方便的調用Lua函數。api
經過查看CCScheduler中的scheduleScriptFunc方法能夠看到在C++代碼中是用unsigned int表示Lua函數的,其實int類型也能夠。異步
AsynResLoader.h函數
#ifndef _ASYNRESLOADER_H_ #define _ASYNRESLOADER_H_ #include "cocos2d.h" USING_NS_CC; //供Lua調用的異步的資源加載器 class AsynResLoader: public CCObject { private: int count; int total; //lua回調方法 int mLuaCallback; public: //建立一個異步資源加載器 static AsynResLoader* create(); //異步加載紋理 void asynLoadTexture(CCArray* paths, int luaCallbck); //加載回調 void callback(CCObject* pSender); }; #endif
#include "AsynResLoader.h" #include "CCLuaEngine.h" //建立一個異步資源加載器 AsynResLoader* AsynResLoader::create(){ AsynResLoader* instance = new AsynResLoader; if (instance) { instance->autorelease(); return instance; } return NULL; } //異步加載紋理 void AsynResLoader::asynLoadTexture(CCArray* paths, int luaCallback){ this->count = 0; this->total = paths->count(); this->mLuaCallback = luaCallback; for(int idx = 0; idx <total; idx++) { const char* path = ((CCString*)paths->objectAtIndex(idx))->getCString(); CCLOG("asynLoadTexture PATH idx=%d : %s",idx,path); CCTextureCache::sharedTextureCache()->addImageAsync(path, this, callfuncO_selector(AsynResLoader::callback)); } } //紋理加載回調方法 void AsynResLoader::callback(CCObject*){ this->count++; //當資源加載完成時,回調指定的lua函數 if (this->count >= this->total) { CCLOG("asyn load res completed.."); if (this->mLuaCallback) { CCLuaStack* pStack = CCLuaEngine::defaultEngine()->getLuaStack(); //第一個參數是函數的整數句柄,第二個參數是函數參數個數 pStack->executeFunctionByHandler(this->mLuaCallback,0); pStack->clean(); CCLOG("call lua function.."); } } }
當完成了自定義類的綁定後,如無心外應該會報錯。。。ui
由於把Lua函數傳遞給C++代碼時須要作一些預處理,作什麼處理呢?我也不知道。。但能夠參考Cocos2d-x的api,好比CCCallFuncN類是如何綁定到Lua的?this
打開tolua++目錄下的CCActoin.pkg文件,能夠看到CCCallFuncN的create方法是用LUA_FUNCTION表示lua函數的。lua
因而,我把AsynResLoader類的pkg文件修改以下:.net
class AsynResLoader: public CCObject { static AsynResLoader* create(); void asynLoadTexture(CCArray* paths, LUA_FUNCTION luaCallbck); };
在tolua++目錄下有個build.bat(Mac下是build.sh)腳本,用於生成LuaCocos2d.cpp,該腳本是這樣的:code
tolua++ -L basic.lua -o "../../scripting/lua/cocos2dx_support/LuaCocos2d.cpp" Cocos2d.pkg其中有一個參數是basic.lua,在tolua++目錄下也有這個文件,對Lua函數傳遞到C++中的預處理就是在這個文件中實現的。