1、cocos2dx对tolua++绑定的修正html
A.c对lua回调函数的引用c++
在使用cocos2dx编写游戏时,咱们常常会设置一些回调函数(时钟、菜单选择等)。若是采用脚本方式编写游戏的话,这些回调函数也是须要写在脚本里的。实现这个功能,就须要lua将本身的函数传递给c++,c++保持对这个函数的引用,不要让这个lua函数被垃圾回收,并在适当的时候回调这个lua函数。shell
这种需求的通常抽象是在C环境下保存lua状态,在PIL(Programming In Lua)里有比较详尽的描述。可使用luaL_ref函数,将一个luaValue(function、table等没有直接对应c类型的数据)存储到LUA_REGISTRY里(luaL_ref返回一个惟一整数,c++能够用这个整数来索引对应的luaValue)api
不过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里,而是放在一个本身建立的表格里。ui
B.野指针预防lua
使用已经释放的指针,一般是一个使人头疼的bug来源。若是能提前发现对野指针的使用,对于bug的定位有很大好处。tolua_fix.c里也提供了这样一套检查机制。.net
阅读自动生成的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接口时,只能取到空地址,错误也能提前发现了。
2、使用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(与重定义文件一致)
3、lua里的类型系统,对c++类型的继承
游戏开发是比较适合使用面向对象模型的,lua语言自己虽然没有提供面向对象模型,可是经过它的metatable机制,也有各类方式来实现这种模型。cocos2dx的LuaTest工程的extern.lua文件里,就提供了一种方式,既能够继承lua里的table类型,又能够经过调用c++生成对象接口的方式,继承c++类型。对c++对象的继承,在子类新增成员时,使用了tolua++的peer功能,给userdata添加字段。
4、其它的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等
5、cocos2dx 2.1.4
在cocos2dx 2.1.4的change log上看到新增了大部分lua test。若是是这样的话,那么对lua绑定的支持又上了一个台阶。
令我比较感兴趣的更新是对cocosbuilder的新绑定方式。相较cocos2dx-LuaProxy对cocosbuilder的绑定,新的绑定采用相似官方js绑定的方式,每一个cocosbuilder自定义类型对应一个lua里面的模块,自动导出cocosbuilder的成员变量到对应模块里。虽然要写模块定义文件,但对于较大型项目,这种方式感受更合适一些。