开发者

Read nested Lua table who key is a System.Double

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜