Which overload of method the NeoLua is calling

Aug 27, 2014 at 11:36 PM
I'm writing program in which I use NeoLua script as script for drawing on Graphics area.
In this script I use e.g. DrawLine which among overloads has two with five arguments:
public void DrawLine(Pen pen, float x1, float y1, float x2, float y2);
public void DrawLine(Pen pen, int x1, int y1, int x2, int y2);
When I use PageUnit.Display unit then is ok - DrawLine works exactly so I want.
But when I use PageUnit.Millimeter unit and I give four float arguments for DrawLine method then is wrong - DrawLine draws line on whole millimeters! e.g. (in NeoLua script):
graphics.DrawLine(pen, 12.3, 50.1, 22.7, 50.1)
result is as
graphics.DrawLine(pen, 12, 50, 22, 50)
Why NeoLua choices DrawLine overload with int arguments, although I give float arguments?

I decided to study problem, I wrote litle console test program (file 'Program.cs'):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Neo.IronLua;

namespace CANeoLua {
    class Program {
        static void Main(string[] args) {
            MyObject myobject = new MyObject();

            Console.WriteLine("from c# code");
            myobject.method1(1);
            myobject.method1(1.1f);
            myobject.method2(1);
            myobject.method2(1.1f);

            Console.WriteLine("from lua script");
            Lua lua = new Lua();
            LuaGlobal luaglobal = lua.CreateEnvironment();
            luaglobal["myobject"] = myobject;
            LuaChunk luachunk = lua.CompileChunk("test.lua", true);
            luaglobal.DoChunk(luachunk);
        }
    }

    public class MyObject {
        public void method1(int i) {
            Console.WriteLine("method1 with int");
        }
        public void method1(float f) {
            Console.WriteLine("method1 with float");
        }
        public void method2(float f) {
            Console.WriteLine("method2 with float");
        }
        public void method2(int i) {
            Console.WriteLine("method2 with int");
        }
    }
}
and NeoLua script (file 'test.lua'):
myobject.method1(1)
myobject.method1(1.1)
myobject.method2(1)
myobject.method2(1.1)
result is:
from c# code
method1 with int
method1 with float
method2 with int
method2 with float
from lua script
method1 with int
method1 with int
method2 with int
method2 with float
How to call proper overload of method from NeoLua script?
Aug 28, 2014 at 12:26 AM
If you write 1.1 is this a double and not a float. Currently, the int and the double gets the same match points, in this example. So, the first one of both will win. You can go around this problem by choosing the correct overload via casts or the index syntax (obi.DrawLine[type,...]).

But these are work a rounds. I will see if I can change it, that it will work out of box.
Aug 28, 2014 at 9:48 PM
I will release a version on friday.
With this version it should work out of box.

Let me know.
Aug 28, 2014 at 11:26 PM
Thanks very much.

I was using second Lua constructor whith float type setup:
Lua(LuaIntegerType integerType, LuaFloatType floatType);
and is ok :)

I wrote test program with pseudo DrawLine method:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Neo.IronLua;
using System.Reflection;

namespace CANeoLua {
    class Program {
        static void Main(string[] args) {
            Graph graph = new Graph();

            Lua lua = new Lua(LuaIntegerType.Int32, LuaFloatType.Float);
            LuaGlobal luaglobal = lua.CreateEnvironment();
            luaglobal["graph"] = graph;
            LuaChunk luachunk = lua.CompileChunk("DrawLine.lua", true);
            luaglobal.DoChunk(luachunk);
        }
    }

    public class Graph {
        public struct PointF {
            public float x, y;
        }
        public class Point {
            public int x, y;
        }
        public void DrawLine(string pen, float x1, float y1, float x2, float y2) {
            Console.WriteLine(string.Format(@"DrawLine '{4}' with float: {0:f1}, {1:f1}, {2:f1}, {3:f1}", x1, y1, x2, y2, pen));
        }
        public void DrawLine(string pen, PointF pt1, PointF pt2) {
            Console.WriteLine(string.Format(@"DrawLine '{4}' with PointF: {0:f1},{1:f1}, {2:f1},{3:f1}", pt1.x, pt1.y, pt2.x, pt2.y, pen));
        }
        public void DrawLine(string pen, int x1, int y1, int x2, int y2) {
            Console.WriteLine(string.Format(@"DrawLine '{4}' with int: {0}, {1}, {2}, {3}", x1, y1, x2, y2, pen));
        }
        public void DrawLine(string pen, Point pt1, Point pt2) {
            Console.WriteLine(string.Format(@"DrawLine '{4}' with Point: {0},{1}, {2},{3}", pt1.x, pt1.y, pt2.x, pt2.y, pen));
        }
    }
}
and Lua script:
graph.DrawLine("a", 1, 1, 1, 1)
graph.DrawLine("b", 1, 1, 1, 1.0)
graph.DrawLine("c", 1, 1, 1.0, 1)
graph.DrawLine("d", 1, 1, 1.0, 1.0)
graph.DrawLine("e", 1, 1.0, 1, 1)
graph.DrawLine("f", 1, 1.0, 1, 1.0)
graph.DrawLine("g", 1, 1.0, 1.0, 1)
graph.DrawLine("h", 1, 1.0, 1.0, 1.0)
graph.DrawLine("i", 1.0, 1, 1, 1)
graph.DrawLine("j", 1.0, 1, 1, 1.0)
graph.DrawLine("k", 1.0, 1, 1.0, 1)
graph.DrawLine("l", 1.0, 1, 1.0, 1.0)
graph.DrawLine("m", 1.0, 1.0, 1, 1)
graph.DrawLine("n", 1.0, 1.0, 1, 1.0)
graph.DrawLine("o", 1.0, 1.0, 1.0, 1)
graph.DrawLine("p", 1.0, 1.0, 1.0, 1.0)
and result:
DrawLine 'a' with int: 1, 1, 1, 1
DrawLine 'b' with float: 1.0, 1.0, 1.0, 1.0
DrawLine 'c' with float: 1.0, 1.0, 1.0, 1.0
DrawLine 'd' with float: 1.0, 1.0, 1.0, 1.0
DrawLine 'e' with float: 1.0, 1.0, 1.0, 1.0
DrawLine 'f' with float: 1.0, 1.0, 1.0, 1.0
DrawLine 'g' with float: 1.0, 1.0, 1.0, 1.0
DrawLine 'h' with float: 1.0, 1.0, 1.0, 1.0
DrawLine 'i' with float: 1.0, 1.0, 1.0, 1.0
DrawLine 'j' with float: 1.0, 1.0, 1.0, 1.0
DrawLine 'k' with float: 1.0, 1.0, 1.0, 1.0
DrawLine 'l' with float: 1.0, 1.0, 1.0, 1.0
DrawLine 'm' with float: 1.0, 1.0, 1.0, 1.0
DrawLine 'n' with float: 1.0, 1.0, 1.0, 1.0
DrawLine 'o' with float: 1.0, 1.0, 1.0, 1.0
DrawLine 'p' with float: 1.0, 1.0, 1.0, 1.0
But when I wrote other script:
local i1 = 1
local i2 = 2
local i3 = 3
local i4 = 4
graph.DrawLine("a", i1, i1, i2, i1)
graph.DrawLine("b", i1, i2, i3, i4)
graph.DrawLine("c", i1, i1, i1, i1)
then result:
DrawLine 'a' with float: 1.0, 2.0, 1.0, 0.0
DrawLine 'b' with int: 1, 2, 3, 4
first DrawLine call gave bad result
second - ok
but third DrawLine call (line 7 in script) gave exception:
Unhandled Exception: System.Reflection.TargetInvocationException: Exception has
been thrown by the target of an invocation. ---> Neo.IronLua.LuaEmitException: N
o conversion defined from PointF to Int32.
   at Neo.IronLua.LuaEmit.Convert(Lua runtime, Expression expr, Type fromType, T
ype toType, Boolean lParse)
   at Neo.IronLua.LuaEmit.BindParameter[T](Lua runtime, Func`2 emitCall, Paramet
erInfo[] parameters, T[] arguments, Func`2 getExpr, Func`2 getType, Boolean lPar
se)
   at Neo.IronLua.LuaMethod.BindInvoke(Lua runtime, Expression methodExpression,
 ILuaMethod methodValue, MethodInfo mi, DynamicMetaObject[] args, Type typeRetur
n)
   at Neo.IronLua.LuaOverloadedMethod.LuaOverloadedMethodMetaObject.BindInvoke(I
nvokeBinder binder, DynamicMetaObject[] args)
   at System.Dynamic.InvokeBinder.Bind(DynamicMetaObject target, DynamicMetaObje
ct[] args)
   at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args, ReadOnlyCollect
ion`1 parameters, LabelTarget returnLabel)
   at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 site
, Object[] args)
   at System.Dynamic.UpdateDelegates.UpdateAndExecute4[T0,T1,T2,T3,TRet](CallSit
e site, T0 arg0, T1 arg1, T2 arg2, T3 arg3)
   at DrawLine.DrawLine(LuaGlobal _G)
   --- End of inner exception stack trace ---
   at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Ob
ject target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAt
tributes, RuntimeType typeOwner)
   at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Obj
ect target, Object[] arguments, Signature sig, MethodAttributes methodAttributes
, RuntimeType typeOwner)
   at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invoke
Attr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisib
ilityChecks)
   at System.Delegate.DynamicInvokeImpl(Object[] args)
   at Neo.IronLua.LuaGlobal.DoChunk(LuaChunk chunk, Object[] callArgs)
   at CANeoLua.Program.Main(String[] args) in C:\work\a_mvc#\WindowsFormsApp\WFA
Lua\CANeoLuaForDiscussion2\Program.cs:line 17
why?

In exception message is 'PointF to Int32' but I was not using struct PointF in my script!

Resolves new version of NeoLua this problem?
Aug 29, 2014 at 1:47 PM
Edited Aug 29, 2014 at 1:47 PM
Oh, I am feeling bad. A big typo. I used in on a Linq-Expression Union instead of Concat.

So your example were compiled to:
local i1 = 1
local i2 = 2
local i3 = 3
local i4 = 4
Call(getMember(getMember(_G, "graph"), "DrawLine"), "a", i1, i2)
Call(getMember(getMember(_G ",graph"), "DrawLine"), "b", i1, i2, i3, i4)
Call(getMember(getMember(_G, "graph"), "DrawLine"), "c", i1)
Sry, for that. And no test case had cover this :(.

I thing I will upload today in evening (german time).

Thank you, for your patients.
Aug 29, 2014 at 11:15 PM
Thank you, very very much :)
Version 0.8.19 is revelation!
Everything works well.
So, I'm going to write my program and enjoy the use of your dll :)