(转载)我所理解Cocos2d-x 3.6(Lua):Cocos如何绑定Lua自定义类

我所理解Cocos2d-x 3.6(Lua):Cocos如何绑定Lua自定义类

热血枫叶2015-06-19 16:27:182289 次阅读

Cocos2d-x 2.x 与 Cocos2d-x 3.x 差异(tolua++)

Cocos2d-x在2.x版本里就是用toLua++和.pkg文件这么把自己注册进Lua环境里的,然而从Cocos2d-x 3.x开始,用bindings-generator脚本代替了toLua++。

bindings-generator脚本的工作机制是:

1、不用编写.pkg和.h文件了,直接定义一个ini文件,注册到Lua环境里的模块名是什么,就行了。

2、摸清了toLua++工具的生成方法,改由Python脚本动态分析C++类,自动生成桥接的.h和.cpp代码,不调用tolua++命令了

3、虽然不再调用tolua++命令了,但是底层仍然使用toLua++的库函数,比如tolua_function,bindings-generator脚本生成的代码就跟使用toLua++工具生成的几乎一样

bindings-generator脚本掌握了生成toLua++桥接代码的主动权,不仅可以省下大量的.pkg和.h文件,而且可以更好地插入自定义代码,达到Cocos2d-x环境下的一些特殊目的,比如内存回收之类的,所以Cocos2d-x从3.x开始放弃了toLua++和.pkg而改用了自己写的bindings-generator脚本是非常值得赞赏的聪明做法。

接下来说怎么用bindings-generator脚本:

1、写自己的C++类,按照Cocos2d-x的规矩,继承cocos2d::Ref类,以便使用Cocos2d-x的内存回收机制。

2、编写一个.ini文件,让bindings-generator可以根据这个配置文件知道C++类该怎么暴露出来

3、修改bindings-generator脚本,让它去读取这个.ini文件

4、执行bindings-generator脚本,生成桥接C++类方法

5、用VS2012将自定义的C++类和生成的桥接文件加入工程,不然编译不到

6、修改AppDelegate.cpp,执行桥接方法,自定义的C++类就注册进Lua环境里了。

首先是自定义的C++类。我习惯将文件保存在frameworks/runtime-src/Classes/目录下:

frameworks/runtime-src/Classes/MyClass.h


1

2

3

4

5

6

7

8

9

10

11

#include "cocos2d.h"

using namespace cocos2d;

class MyClass : public Ref

{

    public:

    MyClass()   {};

    ~MyClass()  {};

    bool init() { return true; };

    CREATE_FUNC(MyClass);

    int foo(int i);

};

frameworks/runtime-src/Classes/MyClass.cpp


1

2

3

4

5

#include "MyClass.h"

int MyClass::foo(int i)

{

    return i + 100;

}

然后编写.ini文件。在frameworks/cocos2d-x/tools/tolua/目录下能看到genbindings.py脚本和一大堆.ini文件,这些就是bindings-generator的实际执行环境了。随便找一个内容比较少的.ini文件,复制一份,重新命名为MyClass.ini。大部分内容都可以凑合不需要改,这里仅列出必须要改的重要部分:

frameworks/cocos2d-x/tools/tolua/MyClass.ini


1

2

3

4

5

[MyClass]

prefix = MineClass     # 添中前缀名XX,注册文件头及注册函数名以前缀名(XX)组合命名

target_namespace = my   # 空间命名,调用时,以my.xxx, xxx为自定义类的方法

headers = %(cocosdir)s/../runtime-src/Classes/MyClass.h    # 获取自定义类的文件头

classes = MyClass   # 需要注册类YY(方法),同时注册函数名以前缀名(XX)_YY组合命名

frameworks/cocos2d-x/tools/tolua/genbindings.py


1

2

cmd_args = {‘cocos2dx.ini‘ : (‘cocos2d-x‘‘lua_cocos2dx_auto‘), \

‘MyClass.ini‘ : (‘MyClass‘‘lua_MyClass_auto‘), \

(其实这一步本来是可以省略的,只要让genbindings.py脚本自动搜寻当前目录下的所有ini文件就行了,不知道将来Cocos2d-x团队会不会这样优化)

至此,生成桥接文件的准备工作就做好了,执行genbindings.py脚本:


1

python genbindings.py

成功执行genbindings.py脚本后,会在frameworks/cocos2d-x/cocos/scripting/lua-bindings/auto/目录下看到新生成的文件:

注:若python报错,看下是否缺少yaml、Cheetah包,若是,安装包就行了。

简单解释下编译成后lua_MyClass_auto.cpp


1

2

3

4

5

6

7

8

9

10

11

12

13

TOLUA_API int register_all_MineClass(lua_State* tolua_S)

{

    //入口点,它创建管理的内部变量

    tolua_open(tolua_S);

    //创建新模块

    tolua_module(tolua_S,"my",0);

    //注册一个模块或类

    tolua_beginmodule(tolua_S,"my");

    // 类的注册

    lua_register_MineClass_MyClass(tolua_S);

    tolua_endmodule(tolua_S);

    return 1;

}

注册类:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

int lua_register_MineClass_MyClass(lua_State* tolua_S)

{

    tolua_usertype(tolua_S,"MyClass");                                   //注册用户类型

    tolua_cclass(tolua_S,"MyClass","MyClass","cc.Ref",nullptr);          //注册类

    tolua_beginmodule(tolua_S,"MyClass");                                //注册模块

    tolua_function(tolua_S,"new",lua_MineClass_MyClass_constructor); //绑定函数(将Lua里面MyClass对象的”new”绑定到你的lua_MineClass_MyClass_constructor()函数中去.)

    tolua_function(tolua_S,"init",lua_MineClass_MyClass_init);

    tolua_function(tolua_S,"foo",lua_MineClass_MyClass_foo);

    tolua_function(tolua_S,"create", lua_MineClass_MyClass_create);

    tolua_endmodule(tolua_S);

    std::string typeName = typeid(MyClass).name();                      //保存注册类

    g_luaType[typeName] = "MyClass";

    g_typeCast["MyClass"] = "MyClass";

    return 1;

}

绑定函数,要注意下:


1

cobj = (MyClass*)tolua_tousertype(tolua_S,1,0); //是将数据栈下的对象以(CTest* )的指针形式弹出来。

从栈中弹出对象(其实是自定类的对象),接着把对象引用方法(包括含参数及handle)返回结果压栈,实现c、lua之间互相调用了。

2.编译运行

打开Classes/lua_module_register.h文件,添加头文件


1

#include "tolua++/lua_MyClass_auto.hpp"

在static int lua_module_register(lua_State* L)添加注册函数


1

register_all_MineClass(L);

若vs2012编译错误,估计都是没把源文件及生成的文件加入工程; 若有特殊处理,比如更换genbindings.py脚本生成文件路径,注意在vs2012环境->属性->c/c++->附加包含目录,添加路径。

lua代码:


1

2

3

4

5

6

function myadd(x, y)

-- 自定义

local test = my.MyClass:create()

print("lua bind: " .. test:foo(99))

return x + y

end

编译运行:

参考文章:

【教程分享】Cocos如何绑定Lua自定义类

Cocos2d-x下Lua调用自定义C++类和函数的最佳实践

来源网址:http://blog.csdn.net/rexuefengye/article/details/46553239

时间: 2024-10-24 15:58:50

(转载)我所理解Cocos2d-x 3.6(Lua):Cocos如何绑定Lua自定义类的相关文章

我所理解cocos2d-x 3.6 lua -- Cocos如何绑定Lua自定义类

cocos2d-x 2.x 与 cocos2d-x 3.x 差异(tolua++) cocos2d-x在2.x版本里就是用toLua++和.pkg文件这么把自己注册进Lua环境里的,然而从cocos2d-x 3.x开始,用bindings-generator脚本代替了toLua++. bindings-generator脚本的工作机制是:        1.不用编写.pkg和.h文件了,直接定义一个ini文件,注册到Lua环境里的模块名是什么,就行了.        2.摸清了toLua++工具

【转载】深入理解Loadrunner中的Browser Emulation

一:基本介绍 在Loadrunner的使用中,对于Run-time Settings下的browser emulation设置是比较容易让人产生困惑的地方.下面我们结合sniffer来具体看看每个选项的用途,以及对测试的影响. Browser Emulation 图 二:案例和工具 1.测试案例: 打开网站首页两次,对比不同Browser Emulation设置下loadrunner的行为,脚本如下. Action(){web_url("www.primeton.com","

cocos2d 2.x在opengl es 2.0 下自定义着色器来创建特别酷的特效(译)

cocos2d 2.x在opengl es 2.0 下自定义着色器来创建特别酷的特效(译) (2012-12-24 13:22:17) 转载▼ 标签: it cocos2d opengl 着色器 渲染 翻译:弹涂鱼 PS:欢迎加入开发群:285275050 本文翻译自:http://www.raywenderlich.com/10862/how-to-create-cool-effects-with-custom-shaders-in-opengl-es-2-0-and-cocos2d-2-x#

【转载】深入理解PHP Opcode缓存原理

转载地址:深入理解PHP Opcode缓存原理 什么是opcode缓存? 当解释器完成对脚本代码的分析后,便将它们生成可以直接运行的中间代码,也称为操作码(Operate Code,opcode).Opcode cache的目地是避免重复编译,减少CPU和内存开销.如果动态内容的性能瓶颈不在于CPU和内存,而在于I/O操作,比如数据库查询带来的磁盘I/O开销,那么opcode cache的性能提升是非常有限的.但是既然opcode cache能带来CPU和内存开销的降低,这总归是好事. 现代操作

【转载】快速理解android View的测量onMeasure()与MeasureSpec

笔者之前有一篇文章已经使用onMeasure()解决了listview与scollview的显示冲突问题,博客地址如下: onMeasure简单方法 完美解决ListView与ScollView冲突问题! 在此就针对View的测量以及onMeasure()涉及的几个问题做一个详细解释: 一.MeasureSpec的概念: MeasureSpec通过将SpecMode和SpecSize打包成一个int值来避免过多的对象内存分配,为了方便操作,其提供了打包和解包的方法.SpecMode和SpecSi

【转载】深入理解Direct3D9

原文:Effulgent的<深入理解Direct3D9>整理版(转) 深入理解Direct3D9 深入理解D3D9对图形程序员来说意义重大,我把以前的一些学习笔记都汇总起来,希望对朋友们有些所帮助,因为是零散笔记,思路很杂,还请包涵. 其实只要你能完美理解D3DLOCK.D3DUSAGE.D3DPOOL.LOST DEVICE.QUERY.Present().BeginScene().EndScene()等概念,就算是理解D3D9了, 不知道大家有没有同感.有如下几个问题,如果你能圆满回答就算

《转载》深入理解 CSS 中的行高与基线

这篇文章总结的很好,故转载收藏. 1.基本概念 1.  基线.底线.顶线.中线 注意:基线(base line)并不是汉字文字的下端沿,而是英文字母“x”的下端沿. 2. 内容区 内容区是指底线和顶线包裹的区域(行内元素display:inline可以通过background-color属性显示出来),实际中不一定看得到,但确实存在.内容区的大小依据font-size的值和字数进行变化. 3. 行距.行高 行高(line-height):包括内容区与以内容区为基础对称拓展的空白区域,我们称之为行

(转载)深入理解java的接口和抽象类

本文转自地址:http://www.cnblogs.com/dolphin0520/p/3811437.html 作者:海子 出处:http://www.cnblogs.com/dolphin0520/ 深入理解Java的接口和抽象类 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的时候会以为它们可以随意互换使用,但是实际则不然.今天我们就一起来学习一下Java中的接口和抽象类

【Todo】【转载】深入理解Java内存模型

参考Infoq上的这篇文章:Link <深入理解Java内存模型(一)--基础>