一、cocos2dx对tolua++绑定的修正

A.c对lua回调函数的引用

在使用cocos2dx编写游戏时,我们经常会设置一些回调函数(时钟、菜单选择等)。如果采用脚本方式编写游戏的话,这些回调函数也是需要写在脚本里的。实现这个功能,就需要lua将自己的函数传递给c++,c++保持对这个函数的引用,不要让这个lua函数被垃圾回收,并在适当的时候回调这个lua函数。

这种需求的一般抽象是在C环境下保存lua状态,在PIL(Programming In Lua)里有比较详尽的描述。可以使用luaL_ref函数,将一个luaValue(function、table等没有直接对应c类型的数据)存储到LUA_REGISTRY里(luaL_ref返回一个唯一整数,c++可以用这个整数来索引对应的luaValue)

不过cocos2dx因为某种原因,并没有使用这个功能,而是自己实现了一套类似的引用机制。

cocos2dx注册回调函数的接口,除了一个参数为c函数指针的版本外,都会提供一个参数为int的对应版本。阅读一下自动生成的cocos2dx lua绑定代码,会发现注册回调函数的接口,都会调用toluafix_ref_function函数,将lua函数转换为一个LUA_FUNCTION(int),并调用响应的注册回调函数的cocos2dx api。

这个toluafix_ref_function,定义在tolua_fix.c里,干的事情就很类似luaL_ref了。区别是对lua函数的引用,没有直接保存在LUA_REGISTRY里,而是放在一个自己创建的表格里。

B.野指针预防

使用已经释放的指针,通常是一个令人头疼的bug来源。如果能提早发现对野指针的使用,对于bug的定位有很大好处。tolua_fix.c里也提供了这样一套检查机制。

阅读自动生成的cocos2dx lua绑定代码,会发现每当把一个继承自CCObject类型的对象传给lua时,会调用toluafix_pushusertype_ccobject函数。

如果这个对象是第一次传递给lua,toluafix_pushusertype_ccobject会为这个对象生成一个索引id,并将这个对象的指针、类型字符串和这个索引相关联。cocos2dx再将这个索引存储在CCObject数据结构里。

在c++里析构这个对象时,CCObject的析构函数会调用toluafix_remove_ccobject_by_refid。这个函数先利用整数索引,找到指针、类型字符串,再通过tolua的tolua_ubox表格(见tolua++实现分析),取到对象的userdata(值为对象的地址),将它置空。这样,以后lua环境再使用这个对象,调用这个对象的c接口时,只能取到空地址,错误也能提早发现了。

二、使用tolua++导出自定义类时,注意定制tolua++

上面提到的cocos2dx对tolua++的修正,体现在代码上,要对标准的tolua++自动生成的绑定代码,进行上百处修改。手工修改显然不适合。tolua++提供了通过重定义lua文件来定制自己的机制。

参考cocos2dx里调用tolua++的shell脚本命令

${TOLUA} -L basic.lua -o ../../scripting/lua/cocos2dx_support/LuaCocos2d.cpp Cocos2d.pkg

这里的-L basic.lua就指定了一个重定义文件。

在这个文件里,指定了LUA_FUNCTION类型的转换函数(toluafix_ref_function)、类型判断函数(toluafix_isfunction),指定了对哪些继承自CCObject的类型,使用自定的推入函数(toluafix_pushusertype_ccobject),另外还进行了一些文本替换,达到一些特殊的功能。

如果你的导出类需要注册lua回调函数,或者继承自CCObject,那么这个重定义文件的帮助就很大了。另外还要注意,在tolua++的pkg定义文件里,对回调函数,使用LUA_FUNCTION做类型名称,而不是int(与重定义文件一致)

三、lua里的类型系统,对c++类型的继承

游戏开发是比较适合使用面向对象模型的,lua语言本身虽然没有提供面向对象模型,但是通过它的metatable机制,也有各种方式来实现这种模型。cocos2dx的LuaTest工程的extern.lua文件里,就提供了一种方式,既可以继承lua里的table类型,又可以通过调用c++生成对象接口的方式,继承c++类型。对c++对象的继承,在子类新增成员时,使用了tolua++的peer功能,给userdata添加字段。

四、其它的cocos2dx lua资源

quick-cocos2d-x

提供了一整套成熟的cocos2dx lua framework。上面提到的lua++绑定修正、类型继承方式,cocos2dx应该都是吸收了quick-cocos2d-x中的相应功能。

本文上面对lua++绑定修正的分析,也得到了quick-cocos2d-x作者dualface的帮助。

cocos2dx-LuaProxy

针对cocos2dx-extension的lua绑定做了一些工作。包括绑定cocosbuilder、tableview等

五、cocos2dx 2.1.4

在cocos2dx 2.1.4的change log上看到新增了大部分lua test。如果是这样的话,那么对lua绑定的支持又上了一个台阶。

令我比较感兴趣的更新是对cocosbuilder的新绑定方式。相较cocos2dx-LuaProxy对cocosbuilder的绑定,新的绑定采用类似官方js绑定的方式,每个cocosbuilder自定义类型对应一个lua里面的模块,自动导出cocosbuilder的成员变量到对应模块里。虽然要写模块定义文件,但对于较大型项目,这种方式感觉更合适一些。

cocos2dx的lua绑定的更多相关文章

  1. cocos2dx 关于lua 绑定的环境配置官方文档翻译与 将自己定义c++方法绑定到lua的的方法

    网上有好多写如何讲自己定义的方法绑定到lua的文章,当中都仅仅对环境配置做了简单的介绍,看到有的帖子写在绑定中遇到了各种各样的error.大部分是因为环境配置不对导致的,下面是官方的文档有标准的说明, ...

  2. cocos2dx之lua绑定简析

    一.总原则:c++对象的生命期不依赖lua gc管理,手动创建的对象要手动销毁 二.引擎层在设计上就是支持脚本概念的(也就是说脚本的使用是“侵入式”的),与lua打交道的代码都封在CCLuaEngin ...

  3. cocos2dx v3.x lua绑定分析

    打算新项目转到cocos2dx v3上了,下载代码浏览过后发现改动真是非常大,结构性调整很多. 比如tolua绑定这一块,就几乎全翻新了. 胶水代码的生成,改成了全自动式的,通过clang来分析c++ ...

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

    转自:http://segmentfault.com/blog/hongliang/1190000000631630 关于cocos2d-x下Lua调用C++的文档看了不少,但没有一篇真正把这事给讲明 ...

  5. cocos2d-x lua绑定解析

    花了几天时间看了下cocos2d-x lua绑定那块,总算是基本搞明白了,下面分三部分解析lua绑定: 一.lua绑定主要用到的底层函数 lua绑定其本质就是有一个公用的lua_Stack来进行C和L ...

  6. cocos2dx lua 绑定之二:手动绑定自定义类中的函数

    cococs2dx 3.13.1 + vs2013 + win10 1.首先按照<cocos2dx lua 绑定之一:自动绑定自定义类>绑定Student类 2.在Student类中增加一 ...

  7. Cocos2d-x v3.3 lua绑定c++类方法总结

    网上有很多cocos2d-x lua绑定c++类的接口教程,这篇文章也是总结他们的经验. 其中重点参考了 http://cn.cocos2d-x.org/tutorial/show?id=1295, ...

  8. win7系统cocos2dx 3.4 绑定自定义类到Lua

    Cocos2d-x 3.0开始使用bindings-generator来生成c++类的lua绑定.bindings-generator基于tolua++,通过配置tools/tolua中的ini文件以 ...

  9. cocos2dx lua 绑定之一:自动绑定自定义类中的函数

    cococs2dx 3.13.1 + vs2013 + win10 1.首先定义C++类Student 在cocos2d-x\cocos文件夹下新建一个user_define的文件夹放置两个文件. 注 ...

随机推荐

  1. 创建一个简单的HTTP服务(自动查找未使用的端口)

    var t = new Thread(new ThreadStart(() => { HttpListener listener = new HttpListener(); var prefix ...

  2. 在Android中开源类库使用过程中兼容性等问题的讨论

    1.在Android4.0环境下编译的actionbarsherlock.slidingmenu类库,能不能在4.0以下的版本中使用 相信很多人跟我一样,都以为在低版本(如Android2.1或2.3 ...

  3. MATLAB实现将图像转换为素描(简笔画)风格

    代码: colorgrad.m function [VG, A, PPG] = colorgrad(f, T) ) || (size(f,)~=) error('Input image must be ...

  4. fir.im Weekly - 新开发时代,每个人都在创造

    七夕纷纷扰扰地过去了,身边的程序员们依旧安静从容地写代码.可是满屏幕的"对象",不如身边一个对象(。・`ω´・)- 闲话说完,这周像往期一样为大家收集了一些优秀的 GitHub 资 ...

  5. 定义一个时钟类——Clock,它包括三个int型 成员变量分别表示时、分、秒,一个构造方法用于对三个成员变量(时、分、秒) 进行初始化,还有一个成员方法show()用于显示时钟对象的时间。其次,再定义 一个主类——TestClass,在主类的main方法中创建多个时钟类的对象,使用这 些对象调用方法show()来显示时钟的时间

    package java1; public class Clock { int hhh; int mmm; int sss; Clock(int h,int m,int s) { hhh=h; mmm ...

  6. bzoj 2659: [Beijing wc2012]算不出的算式

    2659: [Beijing wc2012]算不出的算式 Time Limit: 3 Sec  Memory Limit: 128 MB Description 算不出的算式背景:曾经有一个老掉牙的游 ...

  7. ArcGIS Server新建主题图服务的步骤

    ArcGIS Server新建主题图服务的步骤: 1.修改数据库模型图(PowerDesigner) 2.修改lygis.gdb文件数据库(发布时可以快速把表结构从gdb数据库拷贝到客户服务器的SDE ...

  8. shell日期的应用

    #!bin/bash del_table() { #月初的第一天 month_first_day=`date +%Y%m01` #要删除的日期 last_7day_ago=`date -d " ...

  9. nginx 负载均衡集群解决方案 healthcheck_nginx_upstreams (一)

    该文章来源于互联网,目前找不到原作者,放在这里的目的是记录healthcheck_nginx_upstreams 的安装过程和相关配置,在起初安装成功后不能够正常运行healthcheck_nginx ...

  10. informix 查看 当前锁表

    select username,sid,waiter,dbsname,tabname,rowidlk,keynum,type from sysmaster:syslocks l, sysmaster: ...