cocos2dx开发中的lua继承与覆盖C++方法
转载自:www.litefeel.com » 《cocos2dx开发中的lua继承与覆盖C++方法》
前段时间开始学习cocos2d-x,后面会陆续写一些cocos2d-x方面的东西。由于cocos2d-x支持lua脚本绑定,所以我们的项目是C++与lua混用,要求运行时效率高及内存占用少的部分使用C++,而那些需要动态更新的部分使用lua来写。 lua虽说是脚本语言,但也可以实现类(class)和继承的概念。具体到cocos2d-x,是用{cocos2d-x根目录}/samples/Lua/TestLua/Resources/luaScript/extern.lua里的class方法来实现的。
刚开始写lua的时候不知道可以直接创建一个lua类继承C++(C++对象在lua里都是userdata),就在lua对象里方一个layer或者node属性来访问userdata对象。 类似于下面的代码:
local MyLayer = class ( "MyLayer" ) function MyLayer:ctor() self.layer = CCLayer:create() end return MyLayer |
这样的代码,每次添加到显示对象的时候,都不能直接addChild
,必须要addChild(myLayer.layer)
才行,很麻烦,后来问了老大才知道原来lua类可以直接继承C++类(userdada)的,于是就把上面的代码改成了下面的样子。
local MyLayer = class ( "MyLayer" , function() return CCLayer:create() end) return MyLayer |
这样就可以直接addChild(myLayer)
,并且可以直接调用基类CCLayer
的方法,很方便。
今天用lua写了一个动态的组件,显示的时候总是会动啊动的,隐藏的时候当然要让它停下来以节省资源,毫无疑问,我需要为其添加start()
和stop()
两个方法。在设置visible的时候显示的调用下start和stop方法就可以啦。但是老大说这个不方便,直接在调用setVisible的时候在组件内部start或者stop,经过仔细研究lua继承C++类(userdata)的class函数,并测试后终于搞定了lua类覆盖C++基类的方法,原理就是构造的时候先保存C++方法的指针,后面调用时候就跟C++中一样。 示例代码如下:
local _setVisible = nil local MyLayer = class ( "MyLayer" , function() local layer = CCLayer:create() -- save c++ member method point. _setVisible = layer.setVisible return layer end) -- override CCLayer::setVisible function MyLayer:setVisible(visible) -- invoke CCLayer::setVisible _setVisible(self, visible) -- to do something. end return MyLayer |
之前使用metatable来调用C++方法的时候出现了点问题就以为不能使用metatable的方式调用,~~后面再次测试后发现是可以正常使用的~~。相对于先保存引用的方式,通过metatable调用的方式更简单些。
经过再次研究代码后发现通过metatable调用C++类成员函数有限制,因为只有在lua绑定(pkg文件)的时候明确定义了的成员函数才会直接出现在metatable中,而C++的基类里的成员函数在其metatable的metatable中,继承关系越深,需要查找的metatable越多。 示例代码如下:
-- 获取基类的某个方法 -- table C++类或者lua table -- methodName 函数名,也可以是成员变量名 -- return 基类的函数或成员变量值(如果methodName为变量名) -- nil 表示找不到 local function getSuperMethod(table, methodName) local mt = getmetatable(table) local method = nil while mt and not method do method = mt[methodName] if not method then local index = mt.__index if index and type(index) == "function" then method = index(mt, methodName) elseif index and type(index) == "table" then method = index[methodName] end end mt = getmetatable(mt) end return method end local MyLayer = class ( "MyLayer" , function() return CCLayer:create() end) -- override CCLayer::setVisible function MyLayer:setVisible(visible) -- invoke CCLayer::setVisible getSuperMethod(self, "setVisible" )(self, visible) -- to do something. end return MyLayer |
出处:http://www.cnblogs.com/Ray1024/
版权声明:本文的版权归作者与博客园共有。转载时须注明本文的作者及详细链接,否则作者将保留追究其法律责任。
欢迎大家学习、共享,如果文章中有错误或漏洞,请大家在评论区留言!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?