Commit cf84988f authored by Vinicius Jarina's avatar Vinicius Jarina
Browse files

[NLua] Added auto bind C# overload with Lua mats-methods (__add, __sub, __eq etc).

parent ab44601e
...@@ -42,15 +42,21 @@ namespace ConsoleTest ...@@ -42,15 +42,21 @@ namespace ConsoleTest
using (Lua lua = new Lua()) using (Lua lua = new Lua())
{ {
lua.DebugHook += DebugHook; lua.DebugHook += DebugHook;
lua.LoadCLRPackage ();
lua.SetDebugHook (NLua.Event.EventMasks.LUA_MASKLINE, 0); lua.SetDebugHook (NLua.Event.EventMasks.LUA_MASKLINE, 0);
lua.DoString (@" import ('System.Numerics')
c = Complex (10, 5)
c = -c ");
var a = new System.Numerics.Complex (10, 0); var a = new System.Numerics.Complex (10, 0);
var b = new System.Numerics.Complex (0, 3); var b = new System.Numerics.Complex (10, 0);
var c = lua ["c"];
var x = a + b; var x = a + b;
// lua.LoadCLRPackage (); // lua.LoadCLRPackage ();
lua ["a"] = a; lua ["a"] = a;
lua ["b"] = 1; lua ["b"] = b;
var res = lua.DoString (@"return a + b")[0]; var res = lua.DoString (@"return a ~= b")[0];
} }
......
...@@ -64,7 +64,79 @@ namespace NLua.Extensions ...@@ -64,7 +64,79 @@ namespace NLua.Extensions
var op_add = t.GetMethod ("op_Addition"); var op_add = t.GetMethod ("op_Addition");
return op_add != null; return op_add != null;
} }
public static bool HasSubtractionOpertator (this Type t)
{
if (t.IsPrimitive)
return true;
var op_add = t.GetMethod ("op_Subtraction");
return op_add != null;
}
public static bool HasMultiplyOpertator (this Type t)
{
if (t.IsPrimitive)
return true;
var op_add = t.GetMethod ("op_Multiply");
return op_add != null;
}
public static bool HasDivisionOpertator (this Type t)
{
if (t.IsPrimitive)
return true;
var op_add = t.GetMethod ("op_Division");
return op_add != null;
}
public static bool HasModulusOpertator (this Type t)
{
if (t.IsPrimitive)
return true;
var op_add = t.GetMethod ("op_Modulus");
return op_add != null;
}
public static bool HasUnaryNegationOpertator (this Type t)
{
if (t.IsPrimitive)
return true;
var op_add = t.GetMethod ("op_UnaryNegation");
return op_add != null;
}
public static bool HasEqualityOpertator (this Type t)
{
if (t.IsPrimitive)
return true;
var op_add = t.GetMethod ("op_Equality");
return op_add != null;
}
public static bool HasLessThanOpertator (this Type t)
{
if (t.IsPrimitive)
return true;
var op_add = t.GetMethod ("op_LessThan");
return op_add != null;
}
public static bool HasLessThanOrEqualOpertator (this Type t)
{
if (t.IsPrimitive)
return true;
var op_add = t.GetMethod ("op_LessThanOrEqual");
return op_add != null;
}
} }
static class StringExtensions static class StringExtensions
......
/* /*
* This file is part of NLua. * This file is part of NLua.
* * Copyright (C) 2014 Vinicius Jarina.
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz. * Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/> * Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
* *
...@@ -48,23 +48,39 @@ namespace NLua ...@@ -48,23 +48,39 @@ namespace NLua
* Functions used in the metatables of userdata representing * Functions used in the metatables of userdata representing
* CLR objects * CLR objects
* *
* Author: Fabio Mascarenhas
* Version: 1.0
*/ */
public class MetaFunctions public class MetaFunctions
{ {
internal LuaNativeFunction gcFunction, indexFunction, newindexFunction, baseIndexFunction, public LuaNativeFunction GcFunction { get; private set; }
classIndexFunction, classNewindexFunction, execDelegateFunction, callConstructorFunction, toStringFunction, addFunction; public LuaNativeFunction IndexFunction { get; private set; }
private Dictionary<object, object> memberCache = new Dictionary<object, object> (); public LuaNativeFunction NewIndexFunction { get; private set; }
private ObjectTranslator translator; public LuaNativeFunction BaseIndexFunction { get; private set; }
public LuaNativeFunction ClassIndexFunction { get; private set; }
public LuaNativeFunction ClassNewindexFunction { get; private set; }
public LuaNativeFunction ExecuteDelegateFunction { get; private set; }
public LuaNativeFunction CallConstructorFunction { get; private set; }
public LuaNativeFunction ToStringFunction { get; private set; }
public LuaNativeFunction AddFunction { get; private set; }
public LuaNativeFunction SubtractFunction { get; private set; }
public LuaNativeFunction MultiplyFunction { get; private set; }
public LuaNativeFunction DivisionFunction { get; private set; }
public LuaNativeFunction ModulosFunction { get; private set; }
public LuaNativeFunction UnaryNegationFunction { get; private set; }
public LuaNativeFunction EqualFunction { get; private set; }
public LuaNativeFunction LessThanFunction { get; private set; }
public LuaNativeFunction LessThanOrEqualFunction { get; private set; }
Dictionary<object, object> memberCache = new Dictionary<object, object> ();
ObjectTranslator translator;
/* /*
* __index metafunction for CLR objects. Implemented in Lua. * __index metafunction for CLR objects. Implemented in Lua.
*/ */
internal static string luaIndexFunction = static string luaIndexFunction =
@"local function index(obj,name) @"local function index(obj,name)
local meta=getmetatable(obj) local meta = getmetatable(obj)
local cached=meta.cache[name] local cached = meta.cache[name]
if cached ~= nil then if cached ~= nil then
return cached return cached
else else
...@@ -77,20 +93,30 @@ namespace NLua ...@@ -77,20 +93,30 @@ namespace NLua
end end
end end
return index"; return index";
public static string LuaIndexFunction {
get { return luaIndexFunction; }
}
public MetaFunctions (ObjectTranslator translator) public MetaFunctions (ObjectTranslator translator)
{ {
this.translator = translator; this.translator = translator;
gcFunction = new LuaNativeFunction (MetaFunctions.CollectObject); GcFunction = new LuaNativeFunction (MetaFunctions.CollectObject);
toStringFunction = new LuaNativeFunction (MetaFunctions.ToStringLua); ToStringFunction = new LuaNativeFunction (MetaFunctions.ToStringLua);
indexFunction = new LuaNativeFunction (MetaFunctions.GetMethod); IndexFunction = new LuaNativeFunction (MetaFunctions.GetMethod);
newindexFunction = new LuaNativeFunction (MetaFunctions.SetFieldOrProperty); NewIndexFunction = new LuaNativeFunction (MetaFunctions.SetFieldOrProperty);
baseIndexFunction = new LuaNativeFunction (MetaFunctions.GetBaseMethod); BaseIndexFunction = new LuaNativeFunction (MetaFunctions.GetBaseMethod);
callConstructorFunction = new LuaNativeFunction (MetaFunctions.CallConstructor); CallConstructorFunction = new LuaNativeFunction (MetaFunctions.CallConstructor);
classIndexFunction = new LuaNativeFunction (MetaFunctions.GetClassMethod); ClassIndexFunction = new LuaNativeFunction (MetaFunctions.GetClassMethod);
classNewindexFunction = new LuaNativeFunction (MetaFunctions.SetClassFieldOrProperty); ClassNewindexFunction = new LuaNativeFunction (MetaFunctions.SetClassFieldOrProperty);
execDelegateFunction = new LuaNativeFunction (MetaFunctions.RunFunctionDelegate); ExecuteDelegateFunction = new LuaNativeFunction (MetaFunctions.RunFunctionDelegate);
addFunction = new LuaNativeFunction (MetaFunctions.AddLua); AddFunction = new LuaNativeFunction (MetaFunctions.AddLua);
SubtractFunction = new LuaNativeFunction (MetaFunctions.SubtractLua);
MultiplyFunction = new LuaNativeFunction (MetaFunctions.MultiplyLua);
DivisionFunction = new LuaNativeFunction (MetaFunctions.DivideLua);
ModulosFunction = new LuaNativeFunction (MetaFunctions.ModLua);
UnaryNegationFunction = new LuaNativeFunction (MetaFunctions.UnaryNegationLua);
EqualFunction = new LuaNativeFunction (MetaFunctions.EqualLua);
LessThanFunction = new LuaNativeFunction (MetaFunctions.LessThanLua);
LessThanOrEqualFunction = new LuaNativeFunction (MetaFunctions.LessThanOrEqualLua);
} }
/* /*
...@@ -161,8 +187,8 @@ namespace NLua ...@@ -161,8 +187,8 @@ namespace NLua
return 1; return 1;
} }
/* /*
* __tostring metafunction of CLR objects. * __add metafunction of CLR objects.
*/ */
#if MONOTOUCH #if MONOTOUCH
[MonoTouch.MonoPInvokeCallback (typeof (LuaNativeFunction))] [MonoTouch.MonoPInvokeCallback (typeof (LuaNativeFunction))]
...@@ -195,8 +221,296 @@ namespace NLua ...@@ -195,8 +221,296 @@ namespace NLua
obj1 = opAddition.Invoke (obj1, new object[] { obj1, obj2 }); obj1 = opAddition.Invoke (obj1, new object[] { obj1, obj2 });
translator.Push (luaState, obj1); translator.Push (luaState, obj1);
return 1; return 1;
} }
/*
* __sub metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoTouch.MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
[System.Runtime.InteropServices.AllowReversePInvokeCalls]
static int SubtractLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return SubtractLua (luaState, translator);
}
static int SubtractLua (LuaState luaState, ObjectTranslator translator)
{
object obj1 = translator.GetRawNetObject (luaState, 1);
object obj2 = translator.GetRawNetObject (luaState, 2);
if (obj1 == null || obj2 == null) {
translator.ThrowError (luaState, "Cannot subtract a nil object");
LuaLib.LuaPushNil (luaState);
return 1;
}
Type type = obj1.GetType ();
MethodInfo opSubtract = type.GetMethod ("op_Subtraction");
if (opSubtract == null) {
translator.ThrowError (luaState, "Cannot subtract object (" + type.Name + " does not overload the operator -)");
LuaLib.LuaPushNil (luaState);
return 1;
}
obj1 = opSubtract.Invoke (obj1, new object [] { obj1, obj2 });
translator.Push (luaState, obj1);
return 1;
}
/*
* __mul metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoTouch.MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
[System.Runtime.InteropServices.AllowReversePInvokeCalls]
static int MultiplyLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return MultiplyLua (luaState, translator);
}
static int MultiplyLua (LuaState luaState, ObjectTranslator translator)
{
object obj1 = translator.GetRawNetObject (luaState, 1);
object obj2 = translator.GetRawNetObject (luaState, 2);
if (obj1 == null || obj2 == null) {
translator.ThrowError (luaState, "Cannot multiply a nil object");
LuaLib.LuaPushNil (luaState);
return 1;
}
Type type = obj1.GetType ();
MethodInfo opMultiply = type.GetMethod ("op_Multiply");
if (opMultiply == null) {
translator.ThrowError (luaState, "Cannot multiply object (" + type.Name + " does not overload the operator *)");
LuaLib.LuaPushNil (luaState);
return 1;
}
obj1 = opMultiply.Invoke (obj1, new object [] { obj1, obj2 });
translator.Push (luaState, obj1);
return 1;
}
/*
* __div metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoTouch.MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
[System.Runtime.InteropServices.AllowReversePInvokeCalls]
static int DivideLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return DivideLua (luaState, translator);
}
static int DivideLua (LuaState luaState, ObjectTranslator translator)
{
object obj1 = translator.GetRawNetObject (luaState, 1);
object obj2 = translator.GetRawNetObject (luaState, 2);
if (obj1 == null || obj2 == null) {
translator.ThrowError (luaState, "Cannot divide a nil object");
LuaLib.LuaPushNil (luaState);
return 1;
}
Type type = obj1.GetType ();
MethodInfo opDivide = type.GetMethod ("op_Division");
if (opDivide == null) {
translator.ThrowError (luaState, "Cannot divide object (" + type.Name + " does not overload the operator /)");
LuaLib.LuaPushNil (luaState);
return 1;
}
obj1 = opDivide.Invoke (obj1, new object [] { obj1, obj2 });
translator.Push (luaState, obj1);
return 1;
}
/*
* __mod metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoTouch.MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
[System.Runtime.InteropServices.AllowReversePInvokeCalls]
static int ModLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return ModLua (luaState, translator);
}
static int ModLua (LuaState luaState, ObjectTranslator translator)
{
object obj1 = translator.GetRawNetObject (luaState, 1);
object obj2 = translator.GetRawNetObject (luaState, 2);
if (obj1 == null || obj2 == null) {
translator.ThrowError (luaState, "Cannot mod a nil object");
LuaLib.LuaPushNil (luaState);
return 1;
}
Type type = obj1.GetType ();
MethodInfo opMod = type.GetMethod ("op_Modulus");
if (opMod == null) {
translator.ThrowError (luaState, "Cannot mod object (" + type.Name + " does not overload the operator %)");
LuaLib.LuaPushNil (luaState);
return 1;
}
obj1 = opMod.Invoke (obj1, new object [] { obj1, obj2 });
translator.Push (luaState, obj1);
return 1;
}
/*
* __unm metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoTouch.MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
[System.Runtime.InteropServices.AllowReversePInvokeCalls]
static int UnaryNegationLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return UnaryNegationLua (luaState, translator);
}
static int UnaryNegationLua (LuaState luaState, ObjectTranslator translator)
{
object obj1 = translator.GetRawNetObject (luaState, 1);
if (obj1 == null) {
translator.ThrowError (luaState, "Cannot negate a nil object");
LuaLib.LuaPushNil (luaState);
return 1;
}
Type type = obj1.GetType ();
MethodInfo opUnaryNegation = type.GetMethod ("op_UnaryNegation");
if (opUnaryNegation == null) {
translator.ThrowError (luaState, "Cannot negate object (" + type.Name + " does not overload the operator -)");
LuaLib.LuaPushNil (luaState);
return 1;
}
obj1 = opUnaryNegation.Invoke (obj1, new object [] { obj1 });
translator.Push (luaState, obj1);
return 1;
}
/*
* __eq metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoTouch.MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
[System.Runtime.InteropServices.AllowReversePInvokeCalls]
static int EqualLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return EqualLua (luaState, translator);
}
static int EqualLua (LuaState luaState, ObjectTranslator translator)
{
object obj1 = translator.GetRawNetObject (luaState, 1);
object obj2 = translator.GetRawNetObject (luaState, 2);
if (obj1 == null || obj2 == null) {
translator.ThrowError (luaState, "Cannot compare a nil object");
LuaLib.LuaPushNil (luaState);
return 1;
}
Type type = obj1.GetType ();
MethodInfo opEqual = type.GetMethod ("op_Equality");
if (opEqual == null) {
translator.ThrowError (luaState, "Cannot compare object (" + type.Name + " does not overload the operator =)");
LuaLib.LuaPushNil (luaState);
return 1;
}
obj1 = opEqual.Invoke (obj1, new object [] { obj1, obj2 });
translator.Push (luaState, obj1);
return 1;
}
/*
* __lt metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoTouch.MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
[System.Runtime.InteropServices.AllowReversePInvokeCalls]
static int LessThanLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return LessThanLua (luaState, translator);
}
static int LessThanLua (LuaState luaState, ObjectTranslator translator)
{
object obj1 = translator.GetRawNetObject (luaState, 1);
object obj2 = translator.GetRawNetObject (luaState, 2);
if (obj1 == null || obj2 == null) {
translator.ThrowError (luaState, "Cannot compare a nil object");
LuaLib.LuaPushNil (luaState);
return 1;
}
Type type = obj1.GetType ();
MethodInfo opLessThan = type.GetMethod ("op_LessThan");
if (opLessThan == null) {
translator.ThrowError (luaState, "Cannot compare object (" + type.Name + " does not overload the operator <)");
LuaLib.LuaPushNil (luaState);
return 1;
}
obj1 = opLessThan.Invoke (obj1, new object [] { obj1, obj2 });
translator.Push (luaState, obj1);
return 1;
}
/*
* __le metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoTouch.MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
[System.Runtime.InteropServices.AllowReversePInvokeCalls]
static int LessThanOrEqualLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return LessThanOrEqualLua (luaState, translator);
}
static int LessThanOrEqualLua (LuaState luaState, ObjectTranslator translator)
{
object obj1 = translator.GetRawNetObject (luaState, 1);
object obj2 = translator.GetRawNetObject (luaState, 2);
if (obj1 == null || obj2 == null) {
translator.ThrowError (luaState, "Cannot compare a nil object");
LuaLib.LuaPushNil (luaState);
return 1;
}
Type type = obj1.GetType ();
MethodInfo opLessThanOrEqual = type.GetMethod ("op_LessThanOrEqual");
if (opLessThanOrEqual == null) {
translator.ThrowError (luaState, "Cannot compare object (" + type.Name + " does not overload the operator <=)");
LuaLib.LuaPushNil (luaState);
return 1;
}
obj1 = opLessThanOrEqual.Invoke (obj1, new object [] { obj1, obj2 });
translator.Push (luaState, obj1);
return 1;
}
/// <summary> /// <summary>
/// Debug tool to dump the lua stack /// Debug tool to dump the lua stack
......
...@@ -127,8 +127,8 @@ namespace NLua ...@@ -127,8 +127,8 @@ namespace NLua
*/ */
private void CreateIndexingMetaFunction (LuaState luaState) private void CreateIndexingMetaFunction (LuaState luaState)
{ {
LuaLib.LuaPushString (luaState, "luaNet_indexfunction"); LuaLib.LuaPushString (luaState, "luaNet_indexfunction");
LuaLib.LuaLDoString (luaState, MetaFunctions.luaIndexFunction); LuaLib.LuaLDoString (luaState, MetaFunctions.LuaIndexFunction);
LuaLib.LuaRawSet (luaState, (int)LuaIndexes.Registry); LuaLib.LuaRawSet (luaState, (int)LuaIndexes.Registry);
} }
...@@ -140,16 +140,16 @@ namespace NLua ...@@ -140,16 +140,16 @@ namespace NLua
{ {
LuaLib.LuaLNewMetatable (luaState, "luaNet_searchbase"); LuaLib.LuaLNewMetatable (luaState, "luaNet_searchbase");
LuaLib.LuaPushString (luaState, "__gc"); LuaLib.LuaPushString (luaState, "__gc");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.gcFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.GcFunction);
LuaLib.LuaSetTable (luaState, -3); LuaLib.LuaSetTable (luaState, -3);
LuaLib.LuaPushString (luaState, "__tostring"); LuaLib.LuaPushString (luaState, "__tostring");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.toStringFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.ToStringFunction);
LuaLib.LuaSetTable (luaState, -3); LuaLib.LuaSetTable (luaState, -3);
LuaLib.LuaPushString (luaState, "__index"); LuaLib.LuaPushString (luaState, "__index");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.baseIndexFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.BaseIndexFunction);
LuaLib.LuaSetTable (luaState, -3); LuaLib.LuaSetTable (luaState, -3);
LuaLib.LuaPushString (luaState, "__newindex"); LuaLib.LuaPushString (luaState, "__newindex");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.newindexFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.NewIndexFunction);
LuaLib.LuaSetTable (luaState, -3); LuaLib.LuaSetTable (luaState, -3);
LuaLib.LuaSetTop (luaState, -2); LuaLib.LuaSetTop (luaState, -2);
} }
...@@ -161,19 +161,19 @@ namespace NLua ...@@ -161,19 +161,19 @@ namespace NLua
{ {
LuaLib.LuaLNewMetatable (luaState, "luaNet_class"); LuaLib.LuaLNewMetatable (luaState, "luaNet_class");
LuaLib.LuaPushString (luaState, "__gc"); LuaLib.LuaPushString (luaState, "__gc");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.gcFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.GcFunction);
LuaLib.LuaSetTable (luaState, -3); LuaLib.LuaSetTable (luaState, -3);
LuaLib.LuaPushString (luaState, "__tostring"); LuaLib.LuaPushString (luaState, "__tostring");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.toStringFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.ToStringFunction);
LuaLib.LuaSetTable (luaState, -3); LuaLib.LuaSetTable (luaState, -3);
LuaLib.LuaPushString (luaState, "__index"); LuaLib.LuaPushString (luaState, "__index");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.classIndexFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.ClassIndexFunction);
LuaLib.LuaSetTable (luaState, -3); LuaLib.LuaSetTable (luaState, -3);
LuaLib.LuaPushString (luaState, "__newindex"); LuaLib.LuaPushString (luaState, "__newindex");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.classNewindexFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.ClassNewindexFunction);
LuaLib.LuaSetTable (luaState, -3); LuaLib.LuaSetTable (luaState, -3);
LuaLib.LuaPushString (luaState, "__call"); LuaLib.LuaPushString (luaState, "__call");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.callConstructorFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.CallConstructorFunction);
LuaLib.LuaSetTable (luaState, -3); LuaLib.LuaSetTable (luaState, -3);
LuaLib.LuaSetTop (luaState, -2); LuaLib.LuaSetTop (luaState, -2);
} }
...@@ -183,7 +183,7 @@ namespace NLua ...@@ -183,7 +183,7 @@ namespace NLua
*/ */
private void SetGlobalFunctions (LuaState luaState) private void SetGlobalFunctions (LuaState luaState)
{ {
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.indexFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.IndexFunction);
LuaLib.LuaSetGlobal (luaState, "get_object_member"); LuaLib.LuaSetGlobal (luaState, "get_object_member");
LuaLib.LuaPushStdCallCFunction (luaState, importTypeFunction); LuaLib.LuaPushStdCallCFunction (luaState, importTypeFunction);
LuaLib.LuaSetGlobal (luaState, "import_type"); LuaLib.LuaSetGlobal (luaState, "import_type");
...@@ -210,10 +210,10 @@ namespace NLua ...@@ -210,10 +210,10 @@ namespace NLua
{ {
LuaLib.LuaLNewMetatable (luaState, "luaNet_function"); LuaLib.LuaLNewMetatable (luaState, "luaNet_function");
LuaLib.LuaPushString (luaState, "__gc"); LuaLib.LuaPushString (luaState, "__gc");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.gcFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.GcFunction);
LuaLib.LuaSetTable (luaState, -3); LuaLib.LuaSetTable (luaState, -3);
LuaLib.LuaPushString (luaState, "__call"); LuaLib.LuaPushString (luaState, "__call");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.execDelegateFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.ExecuteDelegateFunction);
LuaLib.LuaSetTable (luaState, -3); LuaLib.LuaSetTable (luaState, -3);
LuaLib.LuaSetTop (luaState, -2); LuaLib.LuaSetTop (luaState, -2);
} }
...@@ -631,14 +631,15 @@ namespace NLua ...@@ -631,14 +631,15 @@ namespace NLua
LuaLib.LuaRawGet (luaState, (int)LuaIndexes.Registry); LuaLib.LuaRawGet (luaState, (int)LuaIndexes.Registry);
LuaLib.LuaRawSet (luaState, -3); LuaLib.LuaRawSet (luaState, -3);
LuaLib.LuaPushString (luaState, "__gc"); LuaLib.LuaPushString (luaState, "__gc");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.gcFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.GcFunction);
LuaLib.LuaRawSet (luaState, -3); LuaLib.LuaRawSet (luaState, -3);
LuaLib.LuaPushString (luaState, "__tostring"); LuaLib.LuaPushString (luaState, "__tostring");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.toStringFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.ToStringFunction);
LuaLib.LuaRawSet (luaState, -3); LuaLib.LuaRawSet (luaState, -3);
LuaLib.LuaPushString (luaState, "__newindex"); LuaLib.LuaPushString (luaState, "__newindex");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.newindexFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.NewIndexFunction);
LuaLib.LuaRawSet (luaState, -3); LuaLib.LuaRawSet (luaState, -3);
// Bind C# operator with Lua metamethods (__add, __sub, __mul)
RegisterOperatorsFunctions (luaState, o.GetType ()); RegisterOperatorsFunctions (luaState, o.GetType ());
} }
} else } else
...@@ -660,7 +661,47 @@ namespace NLua ...@@ -660,7 +661,47 @@ namespace NLua
{ {
if (type.HasAdditionOpertator ()) { if (type.HasAdditionOpertator ()) {
LuaLib.LuaPushString (luaState, "__add"); LuaLib.LuaPushString (luaState, "__add");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.addFunction); LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.AddFunction);
LuaLib.LuaRawSet (luaState, -3);
}
if (type.HasSubtractionOpertator ()) {
LuaLib.LuaPushString (luaState, "__sub");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.SubtractFunction);
LuaLib.LuaRawSet (luaState, -3);
}
if (type.HasMultiplyOpertator ()) {
LuaLib.LuaPushString (luaState, "__mul");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.MultiplyFunction);
LuaLib.LuaRawSet (luaState, -3);
}
if (type.HasDivisionOpertator ()) {
LuaLib.LuaPushString (luaState, "__div");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.DivisionFunction);
LuaLib.LuaRawSet (luaState, -3);
}
if (type.HasModulusOpertator ()) {
LuaLib.LuaPushString (luaState, "__mod");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.ModulosFunction);
LuaLib.LuaRawSet (luaState, -3);
}
if (type.HasUnaryNegationOpertator ()) {
LuaLib.LuaPushString (luaState, "__unm");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.UnaryNegationFunction);
LuaLib.LuaRawSet (luaState, -3);
}
if (type.HasEqualityOpertator ()) {
LuaLib.LuaPushString (luaState, "__eq");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.EqualFunction);
LuaLib.LuaRawSet (luaState, -3);
}
if (type.HasLessThanOpertator ()) {
LuaLib.LuaPushString (luaState, "__lt");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.LessThanFunction);
LuaLib.LuaRawSet (luaState, -3);
}
if (type.HasLessThanOrEqualOpertator ()) {
LuaLib.LuaPushString (luaState, "__le");
LuaLib.LuaPushStdCallCFunction (luaState, metaFunctions.LessThanOrEqualFunction);
LuaLib.LuaRawSet (luaState, -3); LuaLib.LuaRawSet (luaState, -3);
} }
} }
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Numerics" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
...@@ -98,4 +99,4 @@ ...@@ -98,4 +99,4 @@
<Target Name="AfterBuild"> <Target Name="AfterBuild">
</Target> </Target>
--> -->
</Project> </Project>
\ No newline at end of file
...@@ -1924,5 +1924,97 @@ namespace NLuaTest ...@@ -1924,5 +1924,97 @@ namespace NLuaTest
} }
} }
[Test]
public void TestOperatorAdd ()
{
using (Lua lua = new Lua ()) {
var a = new System.Numerics.Complex (10, 0);
var b = new System.Numerics.Complex (0, 3);
var x = a + b;
lua ["a"] = a;
lua ["b"] = b;
var res = lua.DoString (@"return a + b") [0];
Assert.AreEqual (x, res);
}
}
[Test]
public void TestOperatorMinus ()
{
using (Lua lua = new Lua ()) {
var a = new System.Numerics.Complex (10, 0);
var b = new System.Numerics.Complex (0, 3);
var x = a - b;
lua ["a"] = a;
lua ["b"] = b;
var res = lua.DoString (@"return a - b") [0];
Assert.AreEqual (x, res);
}
}
[Test]
public void TestOperatorMultiply ()
{
using (Lua lua = new Lua ()) {
var a = new System.Numerics.Complex (10, 0);
var b = new System.Numerics.Complex (0, 3);
var x = a * b;
lua ["a"] = a;
lua ["b"] = b;
var res = lua.DoString (@"return a * b") [0];
Assert.AreEqual (x, res);
}
}
[Test]
public void TestOperatorEqual ()
{
using (Lua lua = new Lua ()) {
var a = new System.Numerics.Complex (10, 0);
var b = new System.Numerics.Complex (0, 3);
var x = a == b;
lua ["a"] = a;
lua ["b"] = b;
var res = lua.DoString (@"return a == b") [0];
Assert.AreEqual (x, res);
}
}
[Test]
public void TestOperatorNotEqual ()
{
using (Lua lua = new Lua ()) {
var a = new System.Numerics.Complex (10, 0);
var b = new System.Numerics.Complex (0, 3);
var x = a != b;
lua ["a"] = a;
lua ["b"] = b;
var res = lua.DoString (@"return a ~= b") [0];
Assert.AreEqual (x, res);
}
}
[Test]
public void TestUnaryMinus ()
{
using (Lua lua = new Lua ()) {
lua.LoadCLRPackage ();
lua.DoString (@" import ('System.Numerics')
c = Complex (10, 5)
c = -c ");
var expected = new System.Numerics.Complex (-10, -5);
var res = lua ["c"];
Assert.AreEqual (expected, res);
}
}
} }
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment