Search code examples
c#lualuainterface

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,
        },
        [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.


Solution

  • 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).