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的成員變量到對應模塊裏。雖然要寫模塊定義文件,但對於較大型項目,這種方式感受更合適一些。