Skip to content

Request: LuaTable ctor with Array and/or Dictionary parameters #166

Open

Description

For better data-exchange from C# to Lua I would really like to have a LuaTable initializer that I can just pass an array, a dictionary, or both and preferably with internalized LuaValue conversion.

This would be good enough:

LuaValue[] array = ...
var arrayTable = new LuaTable(array);

IDictionary<LuaValue, LuaValue> dict = ...
var dictTable = new LuaTable(dict);

// and both:
var table = new LuaTable(array, dict);

While this would be great:

bool[] boolArray = ...
var arrayTable = new LuaTable(boolArray);

Dictionary<int, SomeUserDataType> userdataDict = ...
var dictTable = new LuaTable(userdataDict);

// and both:
float[] floatArray = ...
Dictionary<string, int> intDict = ...
var table = new LuaTable(floatArray, intDict);

And for best Unity serialization support, since it cannot serialize dictionaries, using two lists for dictionary keys and values to avoid having to first create a dictionary that would then internally get converted to LuaValueDictionary:

ILuaUserData[] array = ...
IEnumerable<string> keys = ...
IEnumerable<int> values = ...
var dictTable = new LuaTable(array, keys, values);

The keys and values enumerables need to have matching lengths.

Again, the types are just for example. Supported LuaValue Types should be automatically converted, otherwise it throws.

Activity

  1. changed the title [-]Request: LuaTable ctor with Array or Dictionary or both[/-] [+]Request: LuaTable ctor with Array and/or Dictionary parameters[/+] on Jun 8, 2025
  2. akeit0 commented on Jun 8, 2025

    @akeit0
    Collaborator

    It seems sufficient to make the following on your own.
    It is not likely to be possible to implement individual case optimization on the part of this library.

    IDictionary<LuaValue, LuaValue> dict = ...
    CreateTable(dict);
    
    static LuaTable CreateTable(IEnumerable<KeyValuePair<LuaValue, LuaValue>> pairs)
    {
        var table = new LuaTable();
        foreach (var pair in pairs)
        {
            table[pair.Key] = pair.Value;
        }
    
        return table;
    }
  3. CodeSmile-0000011110110111 commented on Jun 9, 2025

    @CodeSmile-0000011110110111
    Author

    That's what I've done so far. Would be nice to have this as an extension method in the framework so that this has a common API.

  4. CodeSmile-0000011110110111 commented on Jun 11, 2025

    @CodeSmile-0000011110110111
    Author

    Will we be able to do DoFileAsync(script, LuaValue[] args) passing arguments to the script in 0.5?

    So that outside any function we can get these as "command line" arguments:

    local scriptArgs = {...}

  5. akeit0 commented on Jun 12, 2025

    @akeit0
    Collaborator

    Will we be able to do DoFileAsync(script, LuaValue[] args) passing arguments to the script in 0.5?

    I had a discussion with nuskey about it before, but we finally decided not to support it, because it is not supported in clua and can be handled by loadfile(path)(args).

  6. CodeSmile-0000011110110111 commented on Jun 13, 2025

    @CodeSmile-0000011110110111
    Author

    In case someone has the same need, I went with this solution just passing a single LuaTable as argument.

    These are the necessary extension methods:

    public static class LuaStateExt
    {
    	public static ValueTask<LuaValue[]> DoStringAsync(this LuaState state, String source, String? chunkName,
    		LuaTable arguments, CancellationToken cancellationToken = default)
    	{
    		var access = state.RootAccess;
    		access.ThrowIfInvalid();
    		var closure = access.State.Load(source, chunkName ?? source);
    		access.Thread.Stack.Push(arguments);
    		return access.DoClosureAsync(closure, 1, cancellationToken);
    	}
    
    	public static async ValueTask<LuaValue[]> DoClosureAsync(this LuaThreadAccess access, LuaClosure closure,
    		Int32 argumentCount, CancellationToken cancellationToken = default)
    	{
    		access.ThrowIfInvalid();
    		var count = await access.RunAsync(closure, argumentCount, cancellationToken);
    		using var results = access.ReadReturnValues(count);
    		return results.AsSpan().ToArray();
    	}
    }
    

    I can then call Dostring like this:

    var args = new LuaTable();
    args["HelloFromCSharp"] = "uh, hello?";
    await m_Lua.State.DoStringAsync(m_LuaAsset.text, m_LuaAsset.name, args);
    

    And in the Lua script I use the arguments like so:

    local args = ...
    
    print("args count: " .. tostring(#args))
    for k, v in pairs(args) do
        print("\t" .. tostring(k) .. " = " .. tostring(v))
    end
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions