
cocos2d-x 发展到了3.0,发生了非常大的变化。脚本的绑定也由过去简单的tolua++生成为主,然后通过luafix修正传递回调,到现在更加智能的方式去做。
新的绑定方式简单来讲是分为三步:
使用llvm前端clang对c++代码进行分析,获取AST(抽象语法树)利用预先写好的tolua代码作为模版,使用AST信息去填写模版一些需要fix的回调,通过manual的方式进行包装(这样c++代码就不用专门提供脚本注册函数registerScript(int functionId)之类的接口),然后再回调到正确的lua函数。
优点:
缺点:
在$(EngineDir)/tools/tolua/目录下,执行genbindings.sh生成绑定代码,前提是你已经配置好环境,完成ini文件,如何编写以及配置,具体请看github上的文档,通常有误都是头文件目录错误,注意查看使用的是哪个版本的头文件。
新版本的回调函数绑定步骤如下:
第一、二步如下代码:
static int lua_cocos2dx_AssetsManager_setDelegate(lua_State* L){if (nullptr == L)return 0;int argc = 0;AssetsManager* self = nullptr;#if COCOS2D_DEBUG >= 1tolua_Error tolua_err;if (!tolua_isusertype(L,1,"AssetsManager",0,&tolua_err)) goto tolua_lerror;#endifself = (AssetsManager*) tolua_tousertype(L,1,0);#if COCOS2D_DEBUG >= 1if (nullptr == self){tolua_error(L,"invalid ‘self‘ in function ‘lua_cocos2dx_AssetsManager_setDelegate‘\n", nullptr);return 0;}#endifargc = lua_gettop(L) - 1;if (2 == argc){#if COCOS2D_DEBUG >= 1if (!toluafix_isfunction(L, 2, "LUA_FUNCTION", 0, &tolua_err) ||!tolua_isnumber(L, 3, 0, &tolua_err) ){goto tolua_lerror;}#endifLuaAssetsManagerDelegateProtocol* delegate = dynamic_cast<LuaAssetsManagerDelegateProtocol*>( self->getDelegate());if (nullptr == delegate){delegate = new LuaAssetsManagerDelegateProtocol();if (nullptr == delegate)return 0;self->setUserObject(delegate);self->setDelegate(delegate);delegate->release();}LUA_FUNCTION handler = toluafix_ref_function(L, 2, 0);ScriptHandlerMgr::HandlerType handlerType = (ScriptHandlerMgr::HandlerType) ((int)tolua_tonumber(L,3,0) + (int)ScriptHandlerMgr::HandlerType::ASSETSMANAGER_PROGRESS);ScriptHandlerMgr::getInstance()->addObjectHandler((void*)delegate, handler, handlerType);return 0;}CCLOG("‘setDelegate‘ function of AssetsManager has wrong number of arguments: %d, was expecting %d\n", argc, 2);return 0;#if COCOS2D_DEBUG >= 1tolua_lerror:tolua_error(L,"#ferror in function ‘setDelegate‘.",&tolua_err);return 0;#endif}
第三步:
int LuaEngine::handleAssetsManagerEvent(ScriptHandlerMgr::HandlerType type,void* data){if (nullptr == data)return 0;BasicScriptData* eventData = static_cast<BasicScriptData*>(data);if (nullptr == eventData->nativeObject || nullptr == eventData->value)return 0;LuaAssetsManagerEventData* assetsManagerData = static_cast<LuaAssetsManagerEventData*>(eventData->value);int handler = ScriptHandlerMgr::getInstance()->getObjectHandler((void*)eventData->nativeObject, type);if (0 == handler)return 0;int ret = 0;switch (type){case ScriptHandlerMgr::HandlerType::ASSETSMANAGER_PROGRESS:case ScriptHandlerMgr::HandlerType::ASSETSMANAGER_ERROR:{_stack->pushInt(assetsManagerData->value);ret = _stack->executeFunctionByHandler(handler, 1);}break;case ScriptHandlerMgr::HandlerType::ASSETSMANAGER_SUCCESS:{ret = _stack->executeFunctionByHandler(handler, 0);}break;default:break;}return ret;}
第四步:
int LuaStack::executeFunctionByHandler(int nHandler, int numArgs){int ret = 0;if (pushFunctionByHandler(nHandler)) /* L: ... arg1 arg2 ... func */{if (numArgs > 0){lua_insert(_state, -(numArgs + 1)); /* L: ... func arg1 arg2 ... */}ret = executeFunction(numArgs);}lua_settop(_state, 0return ret;}
原文:http://www.cnblogs.com/fonzieyang/p/3554889.html