Cocos2d-x 3.0 中的lua binding - fonzieyang

前端之家收集整理的这篇文章主要介绍了Cocos2d-x 3.0 中的lua binding - fonzieyang前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

http://www.tuicool.com/articles/zQRbia

Cocos2d-x 3.0 中的lua binding

How it work

cocos2d-x 发展到了3.0,发生了非常大的变化。脚本的绑定也由过去简单的tolua++生成为主,然后通过luafix修正传递回调,到现在更加智能的方式去做。

新的绑定方式简单来讲是分为三步:

  1. 使用llvm前端clang对c++代码进行分析,获取AST(抽象语法树)
  2. 利用预先写好的tolua代码作为模版,使用AST信息去填写模版
  3. 一些需要fix的回调,通过manual的方式进行包装(这样c++代码就不用专门提供脚本注册函数registerScript(int functionId)之类的接口),然后再回调到正确的lua函数

优点:

  • 一套c++多套统绑定
  • 脚本系统透明化,c++代码不必提供脚本接口

缺点:

  • 熟悉tolua++的同学需要重新学习
  • 回调显得稍微麻烦一些,难以自动化绑定,每次需要绑定回调都要自己写c++代码

生成绑定

在$(EngineDir)/tools/tolua/目录下,执行genbindings.sh生成绑定代码,前提是你已经配置好环境,完成ini文件,如何编写以及配置,具体请看github上的文档 ,通常有误都是头文件目录错误,注意查看使用的是哪个版本的头文件

扩展绑定

新版本的回调函数绑定步骤如下:

  1. 增加函数对目标回调接口传递lua function
  2. 在该回调lua_CFunction里面,把lua function注册到事件管理器,同时增加自己的事件类型
  3. 在目标触发回调的地方,派发事件,传递自己的数据
  4. 把数据传递到注册起来的函数

第一、二步如下代码

  1. static int lua_cocos2dx_AssetsManager_setDelegate(lua_State* L)
  2. {
  3. if (nullptr == L)
  4. return 0;

  5. int argc = 0;
  6. AssetsManager* self = nullptr;

  7. #if COCOS2D_DEBUG >= 1
  8. tolua_Error tolua_err;
  9. if (!tolua_isusertype(L,1,"AssetsManager",0,&tolua_err))goto tolua_lerror;
  10. #endif

  11. self = (AssetsManager*) tolua_tousertype(L,1,0);

  12. #if COCOS2D_DEBUG >= 1
  13. if (nullptr == self)
  14. {
  15. tolua_error(L,"invalid 'self' in function 'lua_cocos2dx_AssetsManager_setDelegate'\n",nullptr);
  16. return 0;
  17. }
  18. #endif

  19. argc = lua_gettop(L) - 1;

  20. if (2 == argc)
  21. {
  22. #if COCOS2D_DEBUG >= 1
  23. if (!toluafix_isfunction(L, 2,"LUA_FUNCTION", 0,&tolua_err) ||
  24. !tolua_isnumber(L, 3,&tolua_err) )
  25. {
  26. goto tolua_lerror;
  27. }
  28. #endif
  29. LuaAssetsManagerDelegateProtocol* delegate = dynamic_cast<LuaAssetsManagerDelegateProtocol*>( self->getDelegate());
  30. if (nullptr == delegate)
  31. {
  32. delegate = new LuaAssetsManagerDelegateProtocol();
  33. if (nullptr == delegate)
  34. return 0;

  35. self->setUserObject(delegate);
  36. self->setDelegate(delegate);
  37. delegate->release();
  38. }

  39. LUA_FUNCTION handler = toluafix_ref_function(L, 0);
  40. ScriptHandlerMgr::HandlerType handlerType = (ScriptHandlerMgr::HandlerType) ((int)tolua_tonumber(L,3,0) + (int)ScriptHandlerMgr::HandlerType::ASSETSMANAGER_PROGRESS);

  41. ScriptHandlerMgr::getInstance()->addObjectHandler((void*)delegate,handler,handlerType);
  42. return 0;
  43. }

  44. CCLOG("'setDelegate' function of AssetsManager has wrong number of arguments: %d,was expecting %d\n",argc, 2);
  45. return 0;

  46. #if COCOS2D_DEBUG >= 1
  47. tolua_lerror:
  48. tolua_error(L,"#ferror in function 'setDelegate'.",&tolua_err);
  49. return 0;
  50. #endif
  51. }

第三步:

  1. int LuaEngine::handleAssetsManagerEvent(ScriptHandlerMgr::HandlerType type,void* data)
  2. {
  3. if (nullptr == data)
  4. return 0;

  5. BasicScriptData* eventData = static_cast<BasicScriptData*>(data);
  6. if (nullptr == eventData->nativeObject ||nullptr == eventData->value)
  7. return 0;

  8. LuaAssetsManagerEventData* assetsManagerData = static_cast<LuaAssetsManagerEventData*>(eventData->value);

  9. int handler = ScriptHandlerMgr::getInstance()->getObjectHandler((void*)eventData->nativeObject,type);

  10. if (0 == handler)
  11. return 0;

  12. int ret = 0;
  13. switch (type)
  14. {
  15. case ScriptHandlerMgr::HandlerType::ASSETSMANAGER_PROGRESS:
  16. case ScriptHandlerMgr::HandlerType::ASSETSMANAGER_ERROR:
  17. {
  18. _stack->pushInt(assetsManagerData->value);
  19. ret = _stack->executeFunctionByHandler(handler,1);
  20. }
  21. break;

  22. case ScriptHandlerMgr::HandlerType::ASSETSMANAGER_SUCCESS:
  23. {
  24. ret = _stack->executeFunctionByHandler(handler,0);
  25. }
  26. break;

  27. default:
  28. break;
  29. }

  30. return ret;
  31. }

第四步:

  1. int LuaStack::executeFunctionByHandler(int nHandler,int numArgs)
  2. {
  3. int ret = 0;
  4. if (pushFunctionByHandler(nHandler))/* L: ... arg1 arg2 ... func */
  5. {
  6. if (numArgs > 0)
  7. {
  8. lua_insert(_state,-(numArgs + 1));/* L: ... func arg1 arg2 ... */
  9. }
  10. ret = executeFunction(numArgs);
  11. }
  12. lua_settop(_state, 0
  13. return ret;
  14. }

猜你在找的Cocos2d-x相关文章