首页 > 其他 > 详细

Cocos2d-x 3.0 中的lua binding

时间:2014-02-19 15:56:11      阅读:409      评论:0      收藏:0      [点我收藏+]

Cocos2d-x 3.0 中的lua binding

bubuko.com,布布扣

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, 0, &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, 2, 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 3.0 中的lua binding

原文:http://www.cnblogs.com/fonzieyang/p/3554889.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!