
Cocos2d-x 3.0 中的lua binding How it work
cocos2d-x 发展到了3.0,发生了非常大的变化。脚本的绑定也由过去简单的tolua++生成为主,然后通过luafix修正传递回调,到现在更加智能的方式去做。
新的绑定方式简单来讲是分为三步:
使用llvm前端clang对c++代码进行分析,获取AST(抽象语法树) 利用预先写好的tolua代码作为模版,使用AST信息去填写模版 一些需要fix的回调,通过manual的方式进行包装(这样c++代码就不用专门提供脚本注册函数registerScript(int functionID)之类的接口),然后再回调到正确的lua函数。 优点:
一套c++多套统绑定 脚本系统透明化,c++代码不必提供脚本接口缺点:
熟悉tolua++的同学需要重新学习 回调显得稍微麻烦一些,难以自动化绑定,每次需要绑定回调都要自己写c++代码 生成绑定在$(EngineDir)/tools/tolua/目录下,执行genbindings.sh生成绑定代码,前提是你已经配置好环境,完成ini文件,如何编写以及配置,具体请看github上的文档 ,通常有误都是头文件目录错误,注意查看使用的是哪个版本的头文件。
扩展绑定新版本的回调函数绑定步骤如下:
增加函数对目标回调接口传递lua function 在该回调lua_CFunction里面,把lua function注册到事件管理器,同时增加自己的事件类型 在目标触发回调的地方,派发事件,传递自己的数据 把数据传递到注册起来的函数中第一、二步如下代码:
static int lua_cocos2dx_AssetsManager_setDelegate(lua_State* L) { if (nullptr == L) return 0; int argc = 0; AssetsManager* self = nullptr; #if COCOS2D_DEBUG >= 1 tolua_Error tolua_err; if (!tolua_isusertype(L,1,"AssetsManager",0,&tolua_err))goto tolua_lerror; #endif self = (AssetsManager*) tolua_tousertype(L,1,0); #if COCOS2D_DEBUG >= 1 if (nullptr == self) { tolua_error(L,"invalID 'self' in function 'lua_cocos2dx_AssetsManager_setDelegate'\n",nullptr); return 0; } #endif argc = lua_gettop(L) - 1; if (2 == argc) { #if COCOS2D_DEBUG >= 1 if (!toluafix_isfunction(L, 2,"LUA_FUNCTION", 0,&tolua_err) || !tolua_isnumber(L, 3,&tolua_err) ) { goto tolua_lerror; } #endif LuaAssetsManagerDelegateProtocol* 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, 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 >= 1 tolua_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, 0 return ret; } 总结 以上是内存溢出为你收集整理的Cocos2d-x 3.0 中的lua binding - fonzieyang全部内容,希望文章能够帮你解决Cocos2d-x 3.0 中的lua binding - fonzieyang所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)