0

Question: how can I insert a table from C# into 'LuaInterface' script scope using a C# object (preferably anonymous type)?

/// I want to do this, but it does not work 
/// (complains that 'test' is userdata and not table 
/// when I pass it to pairs() in the script)
//lua["test"] = new { A = 1, B = 2 };

/// another option
/// but building this string is a PITA (actual string is nested and long).
lua.DoString("test = { A = 1, B = 2 }");

// So I have to do this
lua.NewTable("test");
((LuaTable) lua["test"])["A"] = 1;
((LuaTable) lua["test"])["B"] = 2;

lua.DoString("for k,v in pairs(test) do print(k..': '..v) end");
THX-1138
  • 21,316
  • 26
  • 96
  • 160

2 Answers2

0

You could fill a C# Dictionary with the keys and values you want to put inside the table. Then do what you're doing in the "I have to..." section, but inside a foreach loop.

Untested code:

var test = new Dictionary<string, int> {
    { "A", 1 },
    { "B", 2 }
};

foreach (var entry in test)
{
    ((LuaTable) lua]["test"])[entry.Key] = entry.Value;
}

I'd refactor this basic idea into a generic class for added flexibility.

Cogwheel
  • 22,781
  • 4
  • 49
  • 67
  • Yes, this will work. The problem is that table is nested (elements of the table, are also tables). Sure, recursion will be an easy solution. But initializing the dictionary of dictionaries will not be pretty. I already have large anonymous-type data structure that I want to push into lua scope. I just hoped there is a way LuaInterface just uses reflection to map my type into a table. I really don't get it why it doesn't do so. Ofcause, I can just write that myself (I mean use reflection to do type->table conversion). – THX-1138 Jun 16 '10 at 05:11
  • The problem is that you need to create the lua table with both a key and a value. But in your anonymous type, you are mixing structure with data. You want to get the keys from the property names, but property names themselves aren't values. The only way to programmatically walk through the property names and values is with reflection. – Cogwheel Jun 16 '10 at 05:27
  • FWIW, I'm not familiar enough with LuaInterface to say for certain that there isn't something there, but reflection isn't that great for performance so it wouldn't make much sense. A dictionary is a much more accurate representation of the problem you're trying to solve. From a general data structure point of view, lua tables ARE dictionaries. – Cogwheel Jun 16 '10 at 05:29
0

I think if you want to serialize anonymous types into lua tables you will need to user reflection. Maybe you can try to write a lua table serializer. I think I would try to assemble my tables as string and pass it to Lua with DoString

I think the dictionary solution is good and you can use nested tables with without reflection. I tried Tuples, but they are not generic enough and eventually I fell back to the reflection idea.

I would create an extension method:

public static class LuaExt
{
    public static LuaTable GetTable(this Lua lua, string tableName)
    {
        return lua[tableName] as LuaTable;
    }

    public static LuaTable CreateTable(this Lua lua, string tableName)
    {
        lua.NewTable(tableName);
        return lua.GetTable(tableName);
    }

    public static LuaTable CreateTable(this Lua lua)
    {
        lua.NewTable("my");
        return lua.GetTable("my");
    }
}

Then I could write something like this:

var lua = new Lua();
var table = lua.CreateTable("test");

table["A"] = 1;
table["B"] = 1;

table["C"] = lua.CreateTable();
((LuaTable) table["C"])["A"] = 3;

table["D"] = lua.CreateTable();
((LuaTable)table["D"])["A"] = 3;

foreach (var v in table.Keys)
{
    Console.WriteLine(v + ":" + table[v]);
}
Jeno Laszlo
  • 2,023
  • 18
  • 36