AnnulusGames / Lua-CSharp

High performance Lua interpreter implemented in C# for .NET and Unity
MIT License
165 stars 7 forks source link

`LuaObject` src generator constantly causing a `UserData` related error? #50

Open Dismalitie opened 1 week ago

Dismalitie commented 1 week ago

Hi! I'm trying to make a UI library for Lua called Glua (yes very original) that uses WinForms under the hood and I'm using the source generator (LuaObject) to implement a window. But regardless of what values I pass on the Lua side, I get this error:

Lua.LuaRuntimeException
  HResult=0x80131500
  Message=test.lua:1: bad argument #1 to 'create' (Number expected, got UserData)
  Source=Lua
  StackTrace:
   at Lua.LuaRuntimeException.BadArgument(Traceback traceback, Int32 argumentId, String functionName, String expected, String actual)
   at Lua.LuaFunctionExecutionContext.GetArgument[T](Int32 index)
   at glua.gluaWindow.<>c.<.cctor>b__30_0(LuaFunctionExecutionContext context, Memory`1 buffer, CancellationToken ct) in C:\Users\dsml\source\repos\glua\glua\obj\Debug\net8.0-windows\Lua.SourceGenerator\Lua.SourceGenerator.LuaObjectGenerator\glua.gluaWindow.LuaObject.g.cs:line 19
   at Lua.Runtime.LuaVirtualMachine.<ExecuteClosureAsync>d__0.MoveNext()

This is my Lua code:

-- test.lua
local w = window:create("test", 500, 500)
w:show()

Here are the relevant C# snippets:

static async Task Main(string[] args)
{
    args = [".\\test.lua"];

    ApplicationConfiguration.Initialize();

    LuaState state = LuaState.Create();
    state.OpenStandardLibraries();

    state.Environment["window"] = new gluaWindow();

    var r = await state.DoFileAsync(args[0]);

    foreach (LuaValue item in r)
    {
        Console.WriteLine(item.ToString());
    }
}
[LuaObject]
public partial class gluaWindow
{
    static Form f;

    #region constructor stuff

    [LuaMember("create")]
    public static void Create(string title, int width = 700, int height = 400)
    {
        f = new Form()
        {
            Text = title,
            Width = width,
            Height = height,
        };
    }
// ...

If you need any other snippets, or know how to fix this, please tell me!

AnnulusGames commented 1 week ago

In Lua, semicolon : access is sugar syntax for object-oriented notation, and it implicitly passes the self instance as the first argument.

local t = {
  foo = function (self)
    -- do something...
  end
}

t:foo()

When you add LuaMember to an instance method, the source generator adds the self argument to the LuaFunction you generate. However, since your code uses a static method as a Lua function, you don't need the self argument. You can access it with a regular comma ..

The following code will probably work:

-- test.lua
local w = window.create("test", 500, 500)
w.show()
Dismalitie commented 1 week ago

Ok, I have done that but now it's even weirder.

local w = window.create("test", 500, 500)
w.show()

It wants a Number, so I pass a number but I get this:

Lua.LuaRuntimeException
  HResult=0x80131500
  Message=test.lua:1: bad argument #2 to 'create' (Number expected, got Number)
  Source=Lua
  StackTrace:
   at Lua.LuaRuntimeException.BadArgument(Traceback traceback, Int32 argumentId, String functionName, String expected, String actual)
   at Lua.LuaFunctionExecutionContext.GetArgument[T](Int32 index)
   at glua.gluaWindow.<>c.<.cctor>b__30_0(LuaFunctionExecutionContext context, Memory`1 buffer, CancellationToken ct) in C:\Users\dsml\source\repos\glua\glua\obj\Debug\net8.0-windows\Lua.SourceGenerator\Lua.SourceGenerator.LuaObjectGenerator\glua.gluaWindow.LuaObject.g.cs:line 20
   at Lua.Runtime.LuaVirtualMachine.<ExecuteClosureAsync>d__0.MoveNext()

"Number expected, got Number"? I haven't modified any of the C# code.

Dismalitie commented 1 week ago

Although it does accept the first argument

AnnulusGames commented 1 week ago

I see, it seems that there is some problem with the conversion to and from the integer type on the Lua.SourceGenerator side. I will look into it.

Dismalitie commented 1 week ago

Thanks!