Using C# and LuaInterface, I am trying to read a nested table, but am getting a null LuaTable when I try to open the key containing the table.
The .lua file:
DB = {
["inventory"] = {
[10001] = {
["row"] = 140,
["count"] = 20,
开发者_如何学Go },
[10021] = {
["row"] = 83,
["count"] = 3,
},
[10075] = {
["row"] = 927,
["count"] = 15,
},
}
}
I can successfully foreach the entries under inventory, by opening that table with:
LuaTable tbl = lua.GetTable("DB.inventory");
foreach (DictionaryEntry de in tbl)
...
What I cannot do is open an inventory item and enumerate its entries the same way. Is this because the key is a System.Double
type? This fails:
LuaTable tbl = lua.GetTable("DB.inventory.10001");
foreach (DictionaryEntry de in tbl)
with an exception, because tbl is null.
Effectively, once I enumerate the keys (inventory items), I then want to drill down into the nested table and work with those contents. As you can see, I am not able to get a reference to the nested table the way I am doing it.
It appears that LuaInterface only supports string keys. From its Lua.cs, this function is eventually called by your code:
internal object getObject(string[] remainingPath)
{
object returnValue=null;
for(int i=0;i<remainingPath.Length;i++)
{
LuaDLL.lua_pushstring(luaState,remainingPath[i]);
LuaDLL.lua_gettable(luaState,-2);
returnValue=translator.getObject(luaState,-1);
if(returnValue==null) break;
}
return returnValue;
}
Note that there is no provision for keys which aren't strings, because this code calls lua_pushstring()
with part of the string that you indexed with.
The way LuaInterface takes a dot-delimited string argument to its operator[]()
is deficient. You found one shortcoming; another would appear if you tried to look up a key that actually had a dot in it (which is legal Lua--though not idiomatic, there are times like you've discovered when the most natural way to express a key is not with something that looks like a C identifier).
What LuaInterface should provide is an indexing method taking types other than strings. Since it does not, you can rewrite your table like this:
DB = {
["inventory"] = {
["10001"] = {
["row"] = 140,
["count"] = 20,
},
["10021"] = {
["row"] = 83,
["count"] = 3,
},
["10075"] = {
["row"] = 927,
["count"] = 15,
},
}
}
I think this will work. Note that Norman Ramsey's suggestion, while entirely appropriate for proper Lua, will break in LuaInterface, so you should index with dots alone, as you were before (despite that this will look like a bug to any normal Lua programmer).
I don't know about Luainterface, but the syntax
DB.Inventory.10001
is not valid syntax in standard Lua. Have you tried
DB.Inventory[10001]
which would be correct in standard Lua?
@Robert Kerr, How would you know the Inventory Numbers? the 10001, 10021 and 10075? Since you know that the table returned is in the fixed format of DB inventory INV_NUM row count
you can have two loops, one that iterates through the outer DB.inventory and the second that iterates through each of the INV_NUM table
Dim tbl As LuaTable = lua.GetTable("DB.inventory")
For Each item As DictionaryEntry In tbl
Debug.Print("{0} = {1}", item.Key, item.Value)
Dim subTbl As LuaTable = item.Value
For Each subItem As DictionaryEntry in subTbl
Debug.Print(" {0} = {1}", subItem.Key, subItem.Value)
Next
Next
This works with non-string keys as well.
精彩评论