前言
最近一款遊戲開發中,客戶端基於lua語言開發,爲了方便客戶端調用原型數據,全部的原型數據都以lua表格的形式存放;對於服務器端的java語言就須要解析出lua中的數據, 轉換爲java對象。html
橋接的選擇
網上大體搜索了一下,用的比較普遍的是下面這兩款:
1.luajava 官網:http://luaforge.net/projects/luajava/
2.luaj 官網:http://www.luaj.org/luaj/3.0/README.htmljava
看luajava的官網上支持的lua寫的是lua5,lua如今的最新版本已經到5.3了,應該是很久沒有更新了,同時也能夠看github上的源碼luajava,最近的一次改動是在3年前;相比較luaj雖然沒有提供最新的lua5.3支持,可是已經提供到了lua5.2的支持,明顯更加活躍。
另一點就是luajava在使用中是依賴於dll(動態連接庫)的,而luaj是純java語言git
綜上最終選擇luaj做爲橋接器
maven引入:github
<dependency> <groupId>org.luaj</groupId> <artifactId>luaj-jse</artifactId> <version>2.0.3</version> </dependency>
實例
1.準備一個存放數據的lua文件TbTest.lua,存放路徑D:/Datawindows
TbTest = { [1] = {1,[[name1]],{1,2}, }, [2] = {2,[[name2]], }, }
準備了一張表數據,裏面準備了int類型,string類型以及table類型服務器
2.提供lua對外的接口LuaToJavaBridge.luamaven
LuaToJavaBridge = {} function LuaToJavaBridge.getData(dbName,dataId,fieldIndex) require(dbName) local dbData=_G[dbName] local lineData=dbData[dataId] return lineData[fieldIndex] end
提供了一個lua類LuaToJavaBridge,方法getData的3個參數分別是:表名,表Id和字段編號
require(dbName) 引入須要的lua文件編輯器
3.提供一個java調用lua的類JavaToLuaBridge測試
import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.jse.JsePlatform; public class JavaToLuaBridge { private static LuaValue javaToLua; private JavaToLuaBridge() { } public static void init(String packagePath, String javaToLuaFile, String javaToLuaClass) { LuaValue _G = JsePlatform.standardGlobals(); _G.get("package").set("path", packagePath); _G.get("dofile").call(LuaValue.valueOf(javaToLuaFile)); javaToLua = _G.get(javaToLuaClass); } public static LuaValue getData(String dbName, int dataId, int fieldIndex) { LuaValue result = javaToLua.get("getData").call( LuaValue.valueOf(dbName), LuaValue.valueOf(dataId), LuaValue.valueOf(fieldIndex)); return result; } }
init方法,提供一個lua的運行環境,lua是弱語言,全部傳遞給lua,或者從lua獲取的都是LuaValue對象
_G.get(「package」).set(「path」, packagePath); 用來設置lua數據的位置,這裏能夠設置成D:/Data/?.lua
_G.get(「dofile」).call(LuaValue.valueOf(javaToLuaFile));獲取dofile的對象,而後加載LuaToJavaBridge.lua文件
最後獲取LuaToJavaBridge.lua文件中的類文件ui
4.測試
public static void main(String[] args) { JavaToLuaBridge.init("D:/Data/?.lua", "LuaToJavaBridge.lua", "LuaToJavaBridge"); int id = JavaToLuaBridge.getData("TbTest", 1, 1).checkint(); String name = JavaToLuaBridge.getData("TbTest", 1, 2).checkjstring(); LuaTable table = JavaToLuaBridge.getData("TbTest", 1, 3).checktable(); int len = table.length(); for (int i = 1; i <= len; i++) { int tv = table.get(i).checkint(); System.out.println(tv); } System.out.println("id = " + id + ",name = " + name); }
首先初始化,而後獲取數據文件中的數據,對於int和string類型,分別調用checkint()和checkjstring()方法轉化爲對於的java類型;對於table類型須要checktable(),須要注意的是全部的lua表下標都是從1開始的。
在此期間遇到一個問題,讓我迷惑了半天,剛剛還運行好好的,不一會就報下面這個錯了:
Exception in thread "main" org.luaj.vm2.LuaError: LuaToJavaBridge.lua:1: unexpected symbol at org.luaj.vm2.LuaValue.error(Unknown Source) at org.luaj.vm2.lib.BaseLib$BaseLibV.invoke(Unknown Source) at org.luaj.vm2.lib.VarArgFunction.call(Unknown Source) at com.luaj.luajTest.JavaToLuaBridge.init(JavaToLuaBridge.java:20) at com.luaj.luajTest.JavaToLuaBridge.main(JavaToLuaBridge.java:32)
大意就是裏面出現了意想不到的符號;
緣由:使用了記事本進行修改,記事本修改後保存的lua文件只是UTF-8編碼,可是通常來講,lua是不支持有BOM的,lua文件應該保存爲UTF-8無BOM類型,而windows記事本的UTF-8是有BOM的,這就會形成錯誤。因此,文件存儲時格式通常選擇UTF-8無BOM格式
BOM: Byte Order Mark
UTF-8 BOM又叫UTF-8 簽名,其實UTF-8 的BOM對UFT-8沒有做用,是爲了支援UTF-16,UTF-32才加上的BOM,BOM簽名的意思就是告訴編輯器當前文件採用何種編碼,方便編輯器識別,可是BOM雖然在編輯器中不顯示,可是會產生輸出,就像多了一個空行。
總結 整體來講使用起來仍是挺方便的,以上只是一個簡單的例子,涉及的數據類型也沒有全,不過整體的結構能夠參考一下;其實若是想更加熟練的使用luaj,仍是要對lua自己比較熟悉。