基於ulua 1.25版本,開啟C#類型動態注冊.
一. 步驟
- 注冊需要Wrap的C#類型.
在WrapFile.cs類中,使用_GT(typeof(XXX)), 注冊需要Wrap的C#類型
注冊的C#類型被包裝成BindType對象,在BindType構造函數里獲取注冊類型的類名,注冊給Lua的名稱,基類名稱,Wrap的文件名稱等信息,並保存在相應的BindType對象中.(這些是在WrapFile類創建時就生成的)
2. 執行編輯器腳本,生成Wrap的C#類, LuaBinder類,以及Wrap.lua文件.
執行編輯器腳本SimulatorRunScript,調用LuaBinding里的相關接口,LuaBinding里遍歷WrapFile中注冊的需要Wrap的C#類型,根據BindType里的信息,自動生成cs代碼文件,並且生成LuaBinder類和Wrap.lua文件.
3.以上是運行前的准備工作.點擊運行按鈕,運行項目
4.項目首先初始化LuaScriptMgr.cs類,該類初始化后會執行Global.lua代碼.
Global.lua首先require Wrap.lua文件,執行Wrap.lua文件中的代碼.
Wrap.lua是2步驟里生成的,其內容是import各種C#類型到Lua,由於ulua支持動態注冊C#類型.該類默認狀態下是import了所有的C#類型到Lua,可以根據性能需要,修改Wrap.lua的生成方式,減少其中不需要立刻import的類型,改為在首次使用時import.提高啟動效率.
通過import ‘XXX’ 可以把XXX類型注冊到Lua,其原理是在Lua.cs腳本里將import這一字段注冊到Lua的全局表中,並且將import綁定到C#中的LuaStatic.importWrap函數,因此Lua端執行import ‘XXX’之后,調用了C#的LuaStatic.importWrap函數,該函數從Lua棧中取出棧頂的XXX類型名,並調用了LuaBinder的Bind函數
LuaBinder也是在第2步中生成的類,其作用是注冊1步驟Wrap的類型到Lua,該類Bind函數,接收一個類型名,然后Switch該類型,得到該類型Wrap后的類,並調用Wrap類中的Register函數,將該類型的相關方法注冊到Lua,以供Lua端調用.
各Wrap類的Register函數通過調用LuaScriptMgr.RegisterLib函數,注冊到Lua,在RegisterLib函數里,為該類型的namespace的各級創建相應table並注冊到Lua端,以免類型的namespace在Lua端無法找到.例如System.IO.File會創建System,IO的table,以及File類型的table
二. 需要注意的事情
- 有些類在Wrap后會導致編譯錯誤,例如File類,因為ulua在Wrap時不支持泛型<T>,一些用到泛型的函數Wrap后會出錯,還有其他一些方面會導致Wrap出的類型報錯,或者有一些類是經過改造的,不能從原類型Wrap,這時,我們Wrap一次之后,修改Wrap后的文件以滿足我們的需要,解決編譯報錯,然后將該類型從WrapFile中_GT(typeof(XXX))刪除,不讓ulua在Wrap階段處理該類型,但是需要修改LuaBinder.cs和Wrap.lua的生成方式,保留該類型的相關代碼,以免影響該類型注冊到Lua的這一過程.
- 有些類比如Image,其繼承了Graphic類的color屬性,如果Image是屬於第1點中提到的Wrap一次的類,那么也必須要對其基類Graphic進行Wrap一次,否則Lua端會找不到Image繼承的color屬性.
- 編譯LuaJit – 同一台PC上如果安裝了多個版本的VS,可能會出現找不到kernel32庫的問題,嘗試用各個版本的命令行工具編譯.
- 編譯ulua庫時,如果環境變量里有其他MinGW,有可能導致編譯失敗.需要先將環境變量include,lib,path改為ulua源碼編譯工具中帶的MinGW
共同學習,如有錯誤,請務必提出.
轉載請注明:http://www.cnblogs.com/xixidaguai/p/5556791.html