加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

关于cocos2dx3.0 cpp回调lua函数新方法

发布时间:2020-12-14 14:17:12 所属栏目:百科 来源:网络整理
导读:http://blog.sina.com.cn/s/blog_93add5520101lv02.html 本来只是单纯想实现异步加载图片的功能 ,恰恰发现lua竟然没有这个异步机 制,于是无奈求助于C++的 addImageAsync 方法,但是接下来是,加载完了如果告诉lua任务完成 呢,果断回调啊,但这就牵扯到了C

http://blog.sina.com.cn/s/blog_93add5520101lv02.html



本来只是单纯想实现异步加载图片的功能,恰恰发现lua竟然没有这个异步机制,于是无奈求助于C++的addImageAsync方法,但是接下来是,加载完了如果告诉lua任务完成呢,果断回调啊,但这就牵扯到了C++与lua之间的通信问题了,众所周知,lua与C++通信通过栈来处理,其实这块cocos2dx 3.0已经帮我们做好了封装,就在CCLuaEngine里面,不知道路劲?就在frameworkscocos2d-xcocosscriptinglua-bindingsmanual下面是官方手动封装好的,我们打开这个cpp着重看下handleCallFuncActionEvent这个方法:

关于cocos2dx3.0<wbr></p>cpp回调lua函数新方法


这个看字面意思大概就是处理回调的方法。
他首先把参数给强制转换成了BasicScriptData的结构体,结构体里面的naviveObject一定要存在,这个nativeObject是啥意思呢,下一行就是关键了,我们进getObjectHandler查看

关于cocos2dx3.0<wbr></p>cpp回调lua函数新方法
我们发现他从一个_mapObjectHandlers里面去找这个object,也就是BasicScriptData结构体里面的nativeObject,那么我们猜测有getObjectHandler肯定也有addObjectHandler,经过查询在LuaScriptHandlerMgr里面还真有这个方法:

关于cocos2dx3.0<wbr></p>cpp回调lua函数新方法
我们大致了解了,这里面是存了一个key-value的键值对,key是个对象,值是包含了handler和handlerType的数据,handlerType我们可以根据他前面的信息查到他的内容,其实就是枚举的一个值,handler是什么意思呢?他其实呢,就是lua方法在C++里面的一个ID。如果不懂,那么就看下tolua_Cocos2d_ScriptHandlerMgr_registerScriptHandler00这个方法吧,如果你看到下面这段代码,稍微有点lua基础的童鞋应该就明白了,如果不明白,那就只有回去翻翻有关lua和C++之间栈通信的资料吧,这里就不细说了

关于cocos2dx3.0<wbr></p>cpp回调lua函数新方法

我们回到最先的handleCallFuncActionEven t,下一步,他把结构体里面的value又强转成了Ref类型的值,如果这个不是空指针那么压入lua栈,最后根据getObjectHandler查到的lua函数ID,执行lua函数。
OK整个流程差不多分析完了,我们大概了解了这么一个交互过程:
lua将一个tolua的C++对象和一个lua函数绑在一起,放到了一个map中,然后当我们C++中要执行lua回调了,那么就根据obj找到对应的lua函数id,传参,执行....
有人肯定要问了,那C++怎么去执行这个handleCallFuncActionEven t?我写了一个范例,如下:
Ref *i = __Integer;
BasicScriptData data(this,&i);
ScriptEvent scriptEvent(kCallFuncEvent,&data);
LuaEngine::getInstance()->sendEvent(&event)
在lua端呢,cocos2dx也帮我们写好了一个方法
ScriptHandlerMgr:getInstance():registerScriptHandler(c++对应的tolua对象,lua函数,事件类型)
这就是一个完整的C++回调lua的过程了,很简单吧,就上面几行代码,但是这个还是有约束性的,其实最大的约束来自于kCallFuncEvent这个类型的时间只能传递Ref类型的值,这让我很不爽啊,为毛一定要一个对象呢,不过这难不倒我们已经深入挖掘了cocos2dx交互机制的人了,我们来给他扩展下,自己写自己的handleEvent。当然不用说,为了避免自己再去写那套机制,懒人还是有懒人的方法,那就是继承LuaEngine(LuaEngine的构造函数被放进了private里面去了,这个必须手动把他拿到public,不然是无法继承的)。然后,我们给我们事件定义个类型,我们在CCSpriteSupport.h里ScriptEventType最后一行定义一个自己事件类型,

关于cocos2dx3.0<wbr></p>cpp回调lua函数新方法
我们还要在ScriptHandlerMgr的HandlerType定义一个自己的回调类型,

关于cocos2dx3.0<wbr></p>cpp回调lua函数新方法
看来官方可能知道我们自己也要修改,所以加了Event_CUSTOM给我们做预留呢

关于cocos2dx3.0<wbr></p>cpp回调lua函数新方法

然后我们开始写自己的handler函数

关于cocos2dx3.0<wbr></p>cpp回调lua函数新方法

关于cocos2dx3.0<wbr></p>cpp回调lua函数新方法
怎么样,很简单吧,我就把传递进来的BasiceScriptData的value换成了一个int的vector,依葫芦画瓢画瓢,完成了一个自定义的回调方法,那我们再来看下,怎么调用的

关于cocos2dx3.0<wbr></p>cpp回调lua函数新方法
很简单吧,就是吧数据从Ref改成了vector,lua那边还是跟原来一样,最后一个事件类型别忘记写成我们自己的

cc.Handler.EVENT_EVENT_CUSTOMINT 你可以对应在frameworkscocos2d-xcocosscriptinglua-bindingsscript下面的Cocos2dConstant.lua里面找到对应cc.Handler的一批值,在后面补上EVENT_EVENT_CUSTOMINT = 10001,:
ScriptHandlerMgr:getInstance():registerScriptHandler(cc.LoadManager:GetInstance(),LoadCallBack,cc.Handler.EVENT_EVENT_CUSTOMINT )
OK至此大功告成,以后想回调传什么值,我们可以自己在添加,随便加,哈哈哈,最后说一句,继承luaEngine的类一定要跟luaEngine放在一起,不然就等着呵呵吧

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读