Unverified Commit 1cc74393 authored by Vinicius Jarina's avatar Vinicius Jarina Committed by GitHub
Browse files

* Giant cleanup/reshuffle of all files. (#265)

* * Giant cleanup/reshuffle of all files.

* * Update upstream `KeraLua` to `0.1.14`

* Fixed .NET Core build.

* Add runsettings file

* * Fixed nuspec `dependencies` node

* Ignore _ in branch names for package names.

* * Fixed nuspec.
parent 3f254585
/*
* This file is part of NLua.
*
* Copyright (c) 2015 Vinicius Jarina (viniciusjarina@gmail.com)
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
using System.Text;
using System.Collections.Generic;
namespace NLua
{
/// <summary>
/// Base class to provide consistent disposal flow across lua objects. Uses code provided by Yves Duhoux and suggestions by Hans Schmeidenbacher and Qingrui Li
/// </summary>
public abstract class LuaBase : IDisposable
{
private bool _Disposed;
[CLSCompliantAttribute(false)]
protected int
_Reference;
[CLSCompliantAttribute(false)]
protected Lua
_Interpreter;
~LuaBase ()
{
Dispose (false);
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
public virtual void Dispose (bool disposeManagedResources)
{
if (!_Disposed) {
if (disposeManagedResources) {
if (_Reference != 0)
_Interpreter.DisposeInternal (_Reference);
}
_Interpreter = null;
_Disposed = true;
}
}
public override bool Equals (object o)
{
if (o is LuaBase) {
var l = (LuaBase)o;
return _Interpreter.CompareRef (l._Reference, _Reference);
} else
return false;
}
public override int GetHashCode ()
{
return _Reference;
}
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (c) 2015 Vinicius Jarina (viniciusjarina@gmail.com)
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
using System.Text;
using System.Collections.Generic;
namespace NLua
{
#if USE_KOPILUA
using LuaCore = KopiLua.Lua;
using LuaState = KopiLua.LuaState;
using LuaNativeFunction = KopiLua.LuaNativeFunction;
#else
using LuaCore = KeraLua.Lua;
using LuaState = KeraLua.LuaState;
using LuaNativeFunction = KeraLua.LuaNativeFunction;
#endif
public class LuaFunction : LuaBase
{
internal LuaNativeFunction function;
public LuaFunction (int reference, Lua interpreter)
{
_Reference = reference;
this.function = null;
_Interpreter = interpreter;
}
public LuaFunction (LuaNativeFunction function, Lua interpreter)
{
_Reference = 0;
this.function = function;
_Interpreter = interpreter;
}
/*
* Calls the function casting return values to the types
* in returnTypes
*/
internal object[] Call (object[] args, Type[] returnTypes)
{
return _Interpreter.CallFunction (this, args, returnTypes);
}
/*
* Calls the function and returns its return values inside
* an array
*/
public object[] Call (params object[] args)
{
return _Interpreter.CallFunction (this, args);
}
/*
* Pushes the function into the Lua stack
*/
internal void Push (LuaState luaState)
{
if (_Reference != 0)
LuaLib.LuaGetRef (luaState, _Reference);
else
_Interpreter.PushCSFunction (function);
}
public override string ToString ()
{
return "function";
}
public override bool Equals (object o)
{
if (o is LuaFunction) {
var l = (LuaFunction)o;
if (this._Reference != 0 && l._Reference != 0)
return _Interpreter.CompareRef (l._Reference, this._Reference);
else
return this.function == l.function;
} else
return false;
}
public override int GetHashCode ()
{
return _Reference != 0 ? _Reference : function.GetHashCode ();
}
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (c) 2015 Vinicius Jarina (viniciusjarina@gmail.com)
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
namespace NLua
{
/// <summary>
/// Marks a method for global usage in Lua scripts
/// </summary>
/// <see cref="LuaRegistrationHelper.TaggedInstanceMethods"/>
/// <see cref="LuaRegistrationHelper.TaggedStaticMethods"/>
[AttributeUsage(AttributeTargets.Method)]
public sealed class LuaGlobalAttribute : Attribute
{
/// <summary>
/// An alternative name to use for calling the function in Lua - leave empty for CLR name
/// </summary>
public string Name { get; set; }
/// <summary>
/// A description of the function
/// </summary>
public string Description { get; set; }
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (c) 2015 Vinicius Jarina (viniciusjarina@gmail.com)
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
namespace NLua
{
/// <summary>
/// Marks a method, field or property to be hidden from Lua auto-completion
/// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)]
public sealed class LuaHideAttribute : Attribute
{
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (c) 2015 Vinicius Jarina (viniciusjarina@gmail.com)
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com>
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
namespace NLua
{
public enum GCOptions : int
{
/// <summary>
/// Stops the garbage collector.
/// </summary>
Stop = 0,
/// <summary>
/// Restarts the garbage collector.
/// </summary>
Restart = 1,
/// <summary>
/// Performs a full garbage-collection cycle.
/// </summary>
Collect = 2,
/// <summary>
/// Returns the current amount of memory (in Kbytes) in use by KopiLua.Lua.
/// </summary>
Count = 3,
/// <summary>
/// Returns the remainder of dividing the current amount of bytes of memory in use by Lua by 1024.
/// </summary>
CountB = 4,
/// <summary>
/// Performs an incremental step of garbage collection. The step "size" is controlled by data (larger values mean more steps) in a non-specified way. ifyou want to control the step size you must experimentally tune the value of data. The function returns 1 ifthe step finished a garbage-collection cycle.
/// </summary>
Step = 5,
/// <summary>
/// Sets data as the new value for the pause (Controls how long the collector waits before starting a new cycle) of the collector (see §2.10). The function returns the previous value of the pause.
/// </summary>
SetPause = 6,
/// <summary>
/// Sets data as the new value for the step multiplier of the collector (Controls the relative speed of the collector relative to memory allocation.). The function returns the previous value of the step multiplier.
/// </summary>
SetStepMul = 7
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (c) 2015 Vinicius Jarina (viniciusjarina@gmail.com)
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com>
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
namespace NLua
{
/// <summary>
/// Enumeration of basic lua globals.
/// </summary>
public enum LuaEnums : int
{
/// <summary>
/// Option for multiple returns in `lua_pcall' and `lua_call'
/// </summary>
MultiRet = -1,
/// <summary>
/// Everything is OK.
/// </summary>
Ok = 0,
/// <summary>
/// Thread status, Ok or Yield
/// </summary>
Yield = 1,
/// <summary>
/// A Runtime error.
/// </summary>
ErrorRun = 2,
/// <summary>
/// A syntax error.
/// </summary>
ErrorSyntax = 3,
/// <summary>
/// A memory allocation error. For such errors, Lua does not call the error handler function.
/// </summary>
ErrorMemory = 4,
/// <summary>
/// An error in the error handling function.
/// </summary>
ErrorError = 5,
/// <summary>
/// An extra error for file load errors when using luaL_loadfile.
/// </summary>
ErrorFile = 6
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (c) 2015 Vinicius Jarina (viniciusjarina@gmail.com)
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com>
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
namespace NLua
{
#if USE_KOPILUA
using LuaCore = KopiLua.Lua;
using LuaState = KopiLua.LuaState;
#else
using LuaCore = KeraLua.Lua;
using LuaState = KeraLua.LuaState;
#endif
public class LuaIndexes
{
static int registryIndex = 0;
public static int Registry {
get
{
if (registryIndex != 0)
return registryIndex;
registryIndex = LuaCore.LuaNetRegistryIndex ();
return registryIndex;
}
}
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (c) 2014 Vinicius Jarina (viniciusjarina@gmail.com)
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com>
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
using System.IO;
using System.Text;
using NLua.Extensions;
namespace NLua
{
#if USE_KOPILUA
using LuaCore = KopiLua.Lua;
using LuaState = KopiLua.LuaState;
using LuaTag = KopiLua.LuaTag;
using LuaNativeFunction = KopiLua.LuaNativeFunction;
#else
using LuaCore = KeraLua.Lua;
using LuaState = KeraLua.LuaState;
using LuaTag = KeraLua.LuaTag;
using LuaNativeFunction = KeraLua.LuaNativeFunction;
#endif
public class LuaLib
{
public static int LuaGC (LuaState luaState, GCOptions what, int data)
{
return LuaCore.LuaGC (luaState, (int)what, data);
}
public static string LuaTypeName (LuaState luaState, LuaTypes type)
{
return LuaCore.LuaTypeName (luaState, (int)type).ToString ();
}
public static string LuaLTypeName (LuaState luaState, int stackPos)
{
return LuaTypeName (luaState, LuaType (luaState, stackPos));
}
public static void LuaLError (LuaState luaState, string message)
{
LuaCore.LuaLError (luaState, message);
}
public static void LuaLWhere (LuaState luaState, int level)
{
LuaCore.LuaLWhere (luaState, level);
}
public static LuaState LuaLNewState ()
{
return LuaCore.LuaLNewState ();
}
public static void LuaLOpenLibs (LuaState luaState)
{
LuaCore.LuaLOpenLibs (luaState);
}
public static int LuaLLoadString (LuaState luaState, string chunk)
{
return LuaCore.LuaLLoadString (luaState, chunk);
}
public static int LuaLLoadString (LuaState luaState, byte[] chunk)
{
return LuaCore.LuaLLoadString (luaState, chunk);
}
public static int LuaLDoString (LuaState luaState, string chunk)
{
int result = LuaLLoadString (luaState, chunk);
if (result != 0)
return result;
return LuaPCall (luaState, 0, -1, 0);
}
public static int LuaLDoString (LuaState luaState, byte[] chunk)
{
int result = LuaLLoadString (luaState, chunk);
if (result != 0)
return result;
return LuaPCall (luaState, 0, -1, 0);
}
public static void LuaCreateTable (LuaState luaState, int narr, int nrec)
{
LuaCore.LuaCreateTable (luaState, narr, nrec);
}
public static void LuaNewTable (LuaState luaState)
{
LuaCreateTable (luaState, 0, 0);
}
public static int LuaLDoFile (LuaState luaState, string fileName)
{
int result = LuaCore.LuaNetLoadFile (luaState, fileName);
if (result != 0)
return result;
return LuaCore.LuaNetPCall (luaState, 0, -1, 0);
}
public static void LuaGetGlobal (LuaState luaState, string name)
{
LuaCore.LuaNetGetGlobal (luaState, name);
}
public static void LuaSetGlobal (LuaState luaState, string name)
{
LuaCore.LuaNetSetGlobal (luaState, name);
}
public static void LuaSetTop (LuaState luaState, int newTop)
{
LuaCore.LuaSetTop (luaState, newTop);
}
public static void LuaPop (LuaState luaState, int amount)
{
LuaSetTop (luaState, -(amount) - 1);
}
public static void LuaInsert (LuaState luaState, int newTop)
{
LuaCore.LuaInsert (luaState, newTop);
}
public static void LuaRemove (LuaState luaState, int index)
{
LuaCore.LuaRemove (luaState, index);
}
public static void LuaGetTable (LuaState luaState, int index)
{
LuaCore.LuaGetTable (luaState, index);
}
public static void LuaRawGet (LuaState luaState, int index)
{
LuaCore.LuaRawGet (luaState, index);
}
public static void LuaSetTable (LuaState luaState, int index)
{
LuaCore.LuaSetTable (luaState, index);
}
public static void LuaRawSet (LuaState luaState, int index)
{
LuaCore.LuaRawSet (luaState, index);
}
public static void LuaSetMetatable (LuaState luaState, int objIndex)
{
LuaCore.LuaSetMetatable (luaState, objIndex);
}
public static int LuaGetMetatable (LuaState luaState, int objIndex)
{
return LuaCore.LuaGetMetatable (luaState, objIndex);
}
public static int LuaEqual (LuaState luaState, int index1, int index2)
{
return LuaCore.LuaNetEqual (luaState, index1, index2);
}
public static void LuaPushValue (LuaState luaState, int index)
{
LuaCore.LuaPushValue (luaState, index);
}
public static void LuaReplace (LuaState luaState, int index)
{
LuaCore.LuaReplace (luaState, index);
}
public static int LuaGetTop (LuaState luaState)
{
return LuaCore.LuaGetTop (luaState);
}
public static LuaTypes LuaType (LuaState luaState, int index)
{
return (LuaTypes)LuaCore.LuaType (luaState, index);
}
public static bool LuaIsNil (LuaState luaState, int index)
{
return LuaType (luaState, index) == LuaTypes.Nil;
}
public static bool LuaIsNumber (LuaState luaState, int index)
{
return LuaType (luaState, index) == LuaTypes.Number;
}
public static bool LuaIsBoolean (LuaState luaState, int index)
{
return LuaType (luaState, index) == LuaTypes.Boolean;
}
public static int LuaLRef (LuaState luaState, int registryIndex)
{
return LuaCore.LuaLRef (luaState, registryIndex);
}
public static int LuaRef (LuaState luaState, int lockRef)
{
return lockRef != 0 ? LuaLRef (luaState, (int)LuaIndexes.Registry) : 0;
}
public static void LuaRawGetI (LuaState luaState, int tableIndex, int index)
{
LuaCore.LuaRawGetI (luaState, tableIndex, index);
}
public static void LuaRawSetI (LuaState luaState, int tableIndex, int index)
{
LuaCore.LuaRawSetI (luaState, tableIndex, index);
}
public static object LuaNewUserData (LuaState luaState, int size)
{
return LuaCore.LuaNewUserData (luaState, (uint)size);
}
public static object LuaToUserData (LuaState luaState, int index)
{
return LuaCore.LuaToUserData (luaState, index);
}
public static void LuaGetRef (LuaState luaState, int reference)
{
LuaRawGetI (luaState, (int)LuaIndexes.Registry, reference);
}
public static void LuaUnref (LuaState luaState, int reference)
{
LuaCore.LuaLUnref (luaState, (int)LuaIndexes.Registry, reference);
}
public static bool LuaIsString (LuaState luaState, int index)
{
return LuaCore.LuaIsString (luaState, index) != 0;
}
public static bool LuaNetIsStringStrict (LuaState luaState, int index)
{
return LuaCore.LuaNetIsStringStrict (luaState, index) != 0;
}
public static bool LuaIsCFunction (LuaState luaState, int index)
{
return LuaCore.LuaIsCFunction (luaState, index);
}
public static void LuaPushNil (LuaState luaState)
{
LuaCore.LuaPushNil (luaState);
}
public static void LuaPushStdCallCFunction (LuaState luaState, LuaNativeFunction function)
{
LuaCore.LuaPushStdCallCFunction (luaState, function);
}
public static int LuaPCall (LuaState luaState, int nArgs, int nResults, int errfunc)
{
return LuaCore.LuaNetPCall (luaState, nArgs, nResults, errfunc);
}
public static LuaNativeFunction LuaToCFunction (LuaState luaState, int index)
{
return LuaCore.LuaToCFunction (luaState, index);
}
public static double LuaToNumber (LuaState luaState, int index)
{
return LuaCore.LuaNetToNumber (luaState, index);
}
public static bool LuaToBoolean (LuaState luaState, int index)
{
return LuaCore.LuaToBoolean (luaState, index) != 0;
}
public static string LuaToString (LuaState luaState, int index)
{
// FIXME use the same format string as lua i.e. LUA_NUMBER_FMT
var t = LuaType (luaState, index);
if (t == LuaTypes.Number)
return string.Format ("{0}", LuaToNumber (luaState, index));
else if (t == LuaTypes.String) {
uint strlen;
// Changed 2013-05-18 by Dirk Weltz
// Changed because binary chunks, which are also transfered as strings
// get corrupted by conversion to strings because of the encoding.
// So we use the ToString method with string length, so it could be checked,
// if string is a binary chunk and if, could transfered to string without
// encoding.
return LuaCore.LuaToLString (luaState, index, out strlen).ToString ((int)strlen);
} else if (t == LuaTypes.Nil)
return null; // treat lua nulls to as C# nulls
else
return "0"; // Because luaV_tostring does this
}
public static void LuaAtPanic (LuaState luaState, LuaNativeFunction panicf)
{
LuaCore.LuaAtPanic (luaState, (LuaNativeFunction)panicf);
}
public static void LuaPushNumber (LuaState luaState, double number)
{
LuaCore.LuaPushNumber (luaState, number);
}
public static void LuaPushBoolean (LuaState luaState, bool value)
{
LuaCore.LuaPushBoolean (luaState, value ? 1 : 0);
}
public static void LuaPushString (LuaState luaState, string str)
{
LuaCore.LuaPushString (luaState, str);
}
public static int LuaLNewMetatable (LuaState luaState, string meta)
{
return LuaCore.LuaLNewMetatable (luaState, meta);
}
public static void LuaGetField (LuaState luaState, int stackPos, string meta)
{
LuaCore.LuaGetField (luaState, stackPos, meta);
}
public static void LuaLGetMetatable (LuaState luaState, string meta)
{
LuaGetField (luaState, (int)LuaIndexes.Registry, meta);
}
public static object LuaLCheckUData (LuaState luaState, int stackPos, string meta)
{
return LuaCore.LuaLCheckUData (luaState, stackPos, meta);
}
public static bool LuaLGetMetafield (LuaState luaState, int stackPos, string field)
{
return LuaCore.LuaLGetMetafield (luaState, stackPos, field) != 0;
}
public static int LuaLLoadBuffer (LuaState luaState, string buff, string name)
{
var bytes = Encoding.UTF8.GetBytes(buff);
return LuaCore.LuaNetLoadBuffer (luaState, bytes, (uint)bytes.Length, name);
}
public static int LuaLLoadBuffer (LuaState luaState, byte [] buff, string name)
{
return LuaCore.LuaNetLoadBuffer (luaState, buff, (uint)buff.Length, name);
}
public static int LuaLLoadFile (LuaState luaState, string filename)
{
return LuaCore.LuaNetLoadFile (luaState, filename);
}
public static bool LuaLCheckMetatable (LuaState luaState, int index)
{
return LuaCore.LuaLCheckMetatable (luaState, index);
}
public static int LuaNetRegistryIndex ()
{
return LuaCore.LuaNetRegistryIndex ();
}
public static int LuaNetToNetObject (LuaState luaState, int index)
{
return LuaCore.LuaNetToNetObject (luaState, index);
}
public static void LuaNetNewUData (LuaState luaState, int val)
{
LuaCore.LuaNetNewUData (luaState, val);
}
public static int LuaNetRawNetObj (LuaState luaState, int obj)
{
return LuaCore.LuaNetRawNetObj (luaState, obj);
}
public static int LuaNetCheckUData (LuaState luaState, int ud, string tname)
{
return LuaCore.LuaNetCheckUData (luaState, ud, tname);
}
public static void LuaError (LuaState luaState)
{
LuaCore.LuaError (luaState);
}
public static bool LuaCheckStack (LuaState luaState, int extra)
{
return LuaCore.LuaCheckStack (luaState, extra) != 0;
}
public static int LuaNext (LuaState luaState, int index)
{
return LuaCore.LuaNext (luaState, index);
}
public static void LuaPushLightUserData (LuaState luaState, LuaTag udata)
{
LuaCore.LuaPushLightUserData (luaState, udata.Tag);
}
public static LuaTag LuaNetGetTag ()
{
return LuaCore.LuaNetGetTag ();
}
public static void LuaNetPushGlobalTable (LuaState luaState)
{
LuaCore.LuaNetPushGlobalTable (luaState);
}
public static void LuaNetPopGlobalTable (LuaState luaState)
{
LuaCore.LuaNetPopGlobalTable (luaState);
}
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (c) 2015 Vinicius Jarina (viniciusjarina@gmail.com)
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com>
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
using System.IO;
using System.Runtime.InteropServices;
#if !SILVERLIGHT && !NETFX_CORE
using System.Runtime.Serialization.Formatters.Binary;
#endif
using NLua.Extensions;
namespace NLua
{
public enum LuaTypes : int
{
None = -1,
Nil = 0,
Boolean = 1,
LightUserdata = 2,
Number = 3,
String = 4,
Table = 5,
Function = 6,
UserData = 7,
Thread = 8
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (c) 2015 Vinicius Jarina (viniciusjarina@gmail.com)
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2009 Joshua Simmons <simmons.44@gmail.com>
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
namespace NLua
{
public enum References : int
{
RefNil = -1,
NoRef = -2
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (c) 2015 Vinicius Jarina (viniciusjarina@gmail.com)
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
using System.Reflection;
using System.Diagnostics.CodeAnalysis;
using NLua.Extensions;
#if SILVERLIGHT
using System.Linq;
#endif
namespace NLua
{
public static class LuaRegistrationHelper
{
#region Tagged instance methods
/// <summary>
/// Registers all public instance methods in an object tagged with <see cref="LuaGlobalAttribute"/> as Lua global functions
/// </summary>
/// <param name="lua">The Lua VM to add the methods to</param>
/// <param name="o">The object to get the methods from</param>
public static void TaggedInstanceMethods (Lua lua, object o)
{
#region Sanity checks
if (lua == null)
throw new ArgumentNullException ("lua");
if (o == null)
throw new ArgumentNullException ("o");
#endregion
foreach (var method in o.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public)) {
foreach (LuaGlobalAttribute attribute in method.GetCustomAttributes(typeof(LuaGlobalAttribute), true)) {
if (string.IsNullOrEmpty (attribute.Name))
lua.RegisterFunction (method.Name, o, method); // CLR name
else
lua.RegisterFunction (attribute.Name, o, method); // Custom name
}
}
}
#endregion
#region Tagged static methods
/// <summary>
/// Registers all public static methods in a class tagged with <see cref="LuaGlobalAttribute"/> as Lua global functions
/// </summary>
/// <param name="lua">The Lua VM to add the methods to</param>
/// <param name="type">The class type to get the methods from</param>
public static void TaggedStaticMethods (Lua lua, Type type)
{
#region Sanity checks
if (lua == null)
throw new ArgumentNullException ("lua");
if (type == null)
throw new ArgumentNullException ("type");
if (!type.IsClass ())
throw new ArgumentException ("The type must be a class!", "type");
#endregion
foreach (var method in type.GetMethods (BindingFlags.Static | BindingFlags.Public)) {
foreach (LuaGlobalAttribute attribute in method.GetCustomAttributes (typeof(LuaGlobalAttribute), false)) {
if (string.IsNullOrEmpty (attribute.Name))
lua.RegisterFunction (method.Name, null, method); // CLR name
else
lua.RegisterFunction (attribute.Name, null, method); // Custom name
}
}
}
#endregion
#region Enumeration
/// <summary>
/// Registers an enumeration's values for usage as a Lua variable table
/// </summary>
/// <typeparam name="T">The enum type to register</typeparam>
/// <param name="lua">The Lua VM to add the enum to</param>
[SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "The type parameter is used to select an enum type")]
public static void Enumeration<T> (Lua lua)
{
#region Sanity checks
if (lua == null)
throw new ArgumentNullException ("lua");
#endregion
var type = typeof(T);
if (!type.IsEnum ())
throw new ArgumentException ("The type must be an enumeration!");
#if SILVERLIGHT
string[] names = type.GetFields().Where(x => x.IsLiteral).Select(field => field.Name).ToArray();
var values = type.GetFields().Where(x => x.IsLiteral).Select(field => (T)field.GetValue(null)).ToArray();
#else
string[] names = Enum.GetNames (type);
var values = (T[])Enum.GetValues (type);
#endif
lua.NewTable (type.Name);
for (int i = 0; i < names.Length; i++) {
string path = type.Name + "." + names [i];
lua [path] = values [i];
}
}
#endregion
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (c) 2015 Vinicius Jarina (viniciusjarina@gmail.com)
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
namespace NLua
{
#if USE_KOPILUA
using LuaCore = KopiLua.Lua;
using LuaState = KopiLua.LuaState;
using LuaNativeFunction = KopiLua.LuaNativeFunction;
#else
using LuaCore = KeraLua.Lua;
using LuaState = KeraLua.LuaState;
using LuaNativeFunction = KeraLua.LuaNativeFunction;
#endif
/*
* Wrapper class for Lua tables
*
* Author: Fabio Mascarenhas
* Version: 1.0
*/
public class LuaTable : LuaBase
{
public LuaTable (int reference, Lua interpreter)
{
_Reference = reference;
_Interpreter = interpreter;
}
/*
* Indexer for string fields of the table
*/
public object this [string field] {
get {
return _Interpreter.GetObject (_Reference, field);
}
set {
_Interpreter.SetObject (_Reference, field, value);
}
}
/*
* Indexer for numeric fields of the table
*/
public object this [object field] {
get {
return _Interpreter.GetObject (_Reference, field);
}
set {
_Interpreter.SetObject (_Reference, field, value);
}
}
public System.Collections.IDictionaryEnumerator GetEnumerator ()
{
return _Interpreter.GetTableDict (this).GetEnumerator ();
}
public ICollection Keys {
get { return _Interpreter.GetTableDict (this).Keys; }
}
public ICollection Values {
get { return _Interpreter.GetTableDict (this).Values; }
}
/*
* Gets an string fields of a table ignoring its metatable,
* if it exists
*/
internal object RawGet (string field)
{
return _Interpreter.RawGetObject (_Reference, field);
}
/*
* Pushes this table into the Lua stack
*/
internal void Push (LuaState luaState)
{
LuaLib.LuaGetRef (luaState, _Reference);
}
public override string ToString ()
{
return "table";
}
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (c) 2015 Vinicius Jarina (viniciusjarina@gmail.com)
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
using System.Text;
using System.Collections.Generic;
namespace NLua
{
#if USE_KOPILUA
using LuaCore = KopiLua.Lua;
using LuaState = KopiLua.LuaState;
#else
using LuaCore = KeraLua.Lua;
using LuaState = KeraLua.LuaState;
#endif
public class LuaUserData : LuaBase
{
public LuaUserData (int reference, Lua interpreter)
{
_Reference = reference;
_Interpreter = interpreter;
}
/*
* Indexer for string fields of the userdata
*/
public object this [string field] {
get {
return _Interpreter.GetObject (_Reference, field);
}
set {
_Interpreter.SetObject (_Reference, field, value);
}
}
/*
* Indexer for numeric fields of the userdata
*/
public object this [object field] {
get {
return _Interpreter.GetObject (_Reference, field);
}
set {
_Interpreter.SetObject (_Reference, field, value);
}
}
/*
* Calls the userdata and returns its return values inside
* an array
*/
public object[] Call (params object[] args)
{
return _Interpreter.CallFunction (this, args);
}
public override string ToString ()
{
return "userdata";
}
}
}
\ No newline at end of file
EXTRA_DIST =
# Warning: This is an automatically generated file, do not edit!
if ENABLE_DEBUG
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize- -debug "-define:DEBUG" "-keyfile:key.snk"
ASSEMBLY = ../../Run/Debug/net40/NLua.dll
ASSEMBLY_MDB = $(ASSEMBLY).mdb
COMPILE_TARGET = library
PROJECT_REFERENCES = \
../KeraLua/src/bin/Debug/net40/KeraLua.dll \
../KopiLua/Bin/Debug/net40/KopiLua.dll
BUILD_DIR = ../../Run/Debug/net40/
NLUA_DLL_MDB_SOURCE=../../Run/Debug/net40/NLua.dll.mdb
NLUA_DLL_MDB=$(BUILD_DIR)/NLua.dll.mdb
KERALUA_DLL_SOURCE=../KeraLua/src/bin/Debug/net40/KeraLua.dll
KERALUA_DLL_MDB_SOURCE=../KeraLua/src/bin/Debug/net40/KeraLua.dll.mdb
KERALUA_DLL_MDB=$(BUILD_DIR)/KeraLua.dll.mdb
KOPILUA_DLL_SOURCE=../KopiLua/Bin/Debug/net40/KopiLua.dll
KOPILUA_DLL_MDB_SOURCE=../KopiLua/Bin/Debug/net40/KopiLua.dll.mdb
KOPILUA_DLL_MDB=$(BUILD_DIR)/KopiLua.dll.mdb
endif
if ENABLE_DEBUGKOPILUA
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize- -debug "-define:DEBUG;USE_KOPILUA" "-keyfile:key.snk"
ASSEMBLY = bin/DebugKopiLua/NLua.dll
ASSEMBLY_MDB = $(ASSEMBLY).mdb
COMPILE_TARGET = library
PROJECT_REFERENCES = \
../KeraLua/src/bin/DebugKopiLua/KeraLua.dll \
../KopiLua/KopiLua/bin/DebugKopiLua/KopiLua.dll
BUILD_DIR = bin/DebugKopiLua/
NLUA_DLL_MDB_SOURCE=bin/DebugKopiLua/NLua.dll.mdb
NLUA_DLL_MDB=$(BUILD_DIR)/NLua.dll.mdb
KERALUA_DLL_SOURCE=../KeraLua/src/bin/DebugKopiLua/KeraLua.dll
KERALUA_DLL_MDB_SOURCE=../KeraLua/src/bin/DebugKopiLua/KeraLua.dll.mdb
KERALUA_DLL_MDB=$(BUILD_DIR)/KeraLua.dll.mdb
KOPILUA_DLL_SOURCE=../KopiLua/KopiLua/bin/DebugKopiLua/KopiLua.dll
KOPILUA_DLL_MDB_SOURCE=../KopiLua/KopiLua/bin/DebugKopiLua/KopiLua.dll.mdb
KOPILUA_DLL_MDB=$(BUILD_DIR)/KopiLua.dll.mdb
endif
if ENABLE_RELEASE
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ "-define:RELEASE" "-keyfile:key.snk"
ASSEMBLY = ../../Run/Release/net40/NLua.dll
ASSEMBLY_MDB =
COMPILE_TARGET = library
PROJECT_REFERENCES = \
../KeraLua/src/bin/Release/net40/KeraLua.dll \
../KopiLua/Bin/Release/net40/KopiLua.dll
BUILD_DIR = ../../Run/Release/net40/
NLUA_DLL_MDB=
KERALUA_DLL_SOURCE=../KeraLua/src/bin/Release/net40/KeraLua.dll
KERALUA_DLL_MDB=
KOPILUA_DLL_SOURCE=../KopiLua/Bin/Release/net40/KopiLua.dll
KOPILUA_DLL_MDB=
endif
if ENABLE_RELEASEKOPILUA
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize- "-define:USE_KOPILUA" "-keyfile:key.snk"
ASSEMBLY = bin/ReleaseKopiLua/NLua.dll
ASSEMBLY_MDB =
COMPILE_TARGET = library
PROJECT_REFERENCES = \
../KeraLua/src/bin/ReleaseKopiLua/KeraLua.dll \
../KopiLua/KopiLua/bin/ReleaseKopiLua/KopiLua.dll
BUILD_DIR = bin/ReleaseKopiLua/
NLUA_DLL_MDB=
KERALUA_DLL_SOURCE=../KeraLua/src/bin/ReleaseKopiLua/KeraLua.dll
KERALUA_DLL_MDB=
KOPILUA_DLL_SOURCE=../KopiLua/KopiLua/bin/ReleaseKopiLua/KopiLua.dll
KOPILUA_DLL_MDB=
endif
if ENABLE_DEBUG_X64
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize- -debug "-define:DEBUG" "-keyfile:key.snk"
ASSEMBLY = ../../Run/Debug/net40/NLua.dll
ASSEMBLY_MDB = $(ASSEMBLY).mdb
COMPILE_TARGET = library
PROJECT_REFERENCES = \
../KeraLua/src/bin/Debug/net40/KeraLua.dll \
../KopiLua/Bin/Debug/net40/KopiLua.dll
BUILD_DIR = ../../Run/Debug/net40/
NLUA_DLL_MDB_SOURCE=../../Run/Debug/net40/NLua.dll.mdb
NLUA_DLL_MDB=$(BUILD_DIR)/NLua.dll.mdb
KERALUA_DLL_SOURCE=../KeraLua/src/bin/Debug/net40/KeraLua.dll
KERALUA_DLL_MDB_SOURCE=../KeraLua/src/bin/Debug/net40/KeraLua.dll.mdb
KERALUA_DLL_MDB=$(BUILD_DIR)/KeraLua.dll.mdb
KOPILUA_DLL_SOURCE=../KopiLua/Bin/Debug/net40/KopiLua.dll
KOPILUA_DLL_MDB_SOURCE=../KopiLua/Bin/Debug/net40/KopiLua.dll.mdb
KOPILUA_DLL_MDB=$(BUILD_DIR)/KopiLua.dll.mdb
endif
if ENABLE_RELEASE_X64
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize+ "-define:RELEASE" "-keyfile:key.snk"
ASSEMBLY = ../../Run/Release/net40/NLua.dll
ASSEMBLY_MDB =
COMPILE_TARGET = library
PROJECT_REFERENCES = \
../KeraLua/src/bin/Release/net40/KeraLua.dll \
../KopiLua/Bin/Release/net40/KopiLua.dll
BUILD_DIR = ../../Run/Release/net40/
NLUA_DLL_MDB=
KERALUA_DLL_SOURCE=../KeraLua/src/bin/Release/net40/KeraLua.dll
KERALUA_DLL_MDB=
KOPILUA_DLL_SOURCE=../KopiLua/Bin/Release/net40/KopiLua.dll
KOPILUA_DLL_MDB=
endif
if ENABLE_DEBUGKOPILUA_X64
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize- -debug "-define:DEBUG;USE_KOPILUA" "-keyfile:key.snk"
ASSEMBLY = bin/DebugKopiLua/NLua.dll
ASSEMBLY_MDB = $(ASSEMBLY).mdb
COMPILE_TARGET = library
PROJECT_REFERENCES = \
../KeraLua/src/bin/DebugKopiLua/KeraLua.dll \
../KopiLua/KopiLua/bin/DebugKopiLua/KopiLua.dll
BUILD_DIR = bin/DebugKopiLua/
NLUA_DLL_MDB_SOURCE=bin/DebugKopiLua/NLua.dll.mdb
NLUA_DLL_MDB=$(BUILD_DIR)/NLua.dll.mdb
KERALUA_DLL_SOURCE=../KeraLua/src/bin/DebugKopiLua/KeraLua.dll
KERALUA_DLL_MDB_SOURCE=../KeraLua/src/bin/DebugKopiLua/KeraLua.dll.mdb
KERALUA_DLL_MDB=$(BUILD_DIR)/KeraLua.dll.mdb
KOPILUA_DLL_SOURCE=../KopiLua/KopiLua/bin/DebugKopiLua/KopiLua.dll
KOPILUA_DLL_MDB_SOURCE=../KopiLua/KopiLua/bin/DebugKopiLua/KopiLua.dll.mdb
KOPILUA_DLL_MDB=$(BUILD_DIR)/KopiLua.dll.mdb
endif
if ENABLE_RELEASEKOPILUA_X64
ASSEMBLY_COMPILER_COMMAND = dmcs
ASSEMBLY_COMPILER_FLAGS = -noconfig -codepage:utf8 -warn:4 -optimize- "-define:USE_KOPILUA" "-keyfile:key.snk"
ASSEMBLY = bin/ReleaseKopiLua/NLua.dll
ASSEMBLY_MDB =
COMPILE_TARGET = library
PROJECT_REFERENCES = \
../KeraLua/src/bin/ReleaseKopiLua/KeraLua.dll \
../KopiLua/KopiLua/bin/ReleaseKopiLua/KopiLua.dll
BUILD_DIR = bin/ReleaseKopiLua/
NLUA_DLL_MDB=
KERALUA_DLL_SOURCE=../KeraLua/src/bin/ReleaseKopiLua/KeraLua.dll
KERALUA_DLL_MDB=
KOPILUA_DLL_SOURCE=../KopiLua/KopiLua/bin/ReleaseKopiLua/KopiLua.dll
KOPILUA_DLL_MDB=
endif
AL=al
SATELLITE_ASSEMBLY_NAME=$(notdir $(basename $(ASSEMBLY))).resources.dll
PROGRAMFILES = \
$(NLUA_DLL_MDB) \
$(KERALUA_DLL) \
$(KERALUA_DLL_MDB) \
$(KOPILUA_DLL) \
$(KOPILUA_DLL_MDB)
LINUX_PKGCONFIG = \
$(NLUA_NET40_PC)
RESGEN=resgen2
all: $(ASSEMBLY) $(PROGRAMFILES) $(LINUX_PKGCONFIG)
FILES = \
CheckType.cs \
Lua.cs \
Metatables.cs \
ObjectTranslator.cs \
ProxyType.cs \
Properties/AssemblyInfo.cs \
LuaBase.cs \
LuaFunction.cs \
LuaGlobalAttribute.cs \
LuaHideAttribute.cs \
LuaRegistrationHelper.cs \
LuaTable.cs \
LuaUserData.cs \
Extensions/GeneralExtensions.cs \
GenerateEventAssembly/LuaClassType.cs \
GenerateEventAssembly/ILuaGeneratedType.cs \
GenerateEventAssembly/DelegateGenerator.cs \
GenerateEventAssembly/ClassGenerator.cs \
GenerateEventAssembly/CodeGeneration.cs \
Event/EventCodes.cs \
Event/EventMasks.cs \
Event/DebugHookEventArgs.cs \
Event/HookExceptionEventArgs.cs \
Exceptions/LuaException.cs \
Exceptions/LuaScriptException.cs \
LuaLib/LuaEnums.cs \
LuaLib/References.cs \
LuaLib/LuaTypes.cs \
Method/MethodCache.cs \
Method/MethodArgs.cs \
Method/LuaMethodWrapper.cs \
Method/EventHandlerContainer.cs \
Method/RegisterEventHandler.cs \
Method/LuaEventHandler.cs \
Method/LuaDelegate.cs \
Method/LuaClassHelper.cs \
LuaLib/LuaIndexes.cs \
LuaLib/GCOptions.cs \
LuaLib/LuaLib.cs \
Config/NLuaConfig.cs \
ObjectTranslatorPool.cs \
Platform/CLSCompliantAttribute.cs
DATA_FILES =
RESOURCES =
EXTRAS = \
key.snk \
nlua.net40.pc.in
REFERENCES = \
System \
System.Data \
System.Xml \
System.Core
DLL_REFERENCES =
CLEANFILES = $(PROGRAMFILES) $(LINUX_PKGCONFIG)
include $(top_srcdir)/Makefile.include
KERALUA_DLL = $(BUILD_DIR)/KeraLua.dll
KOPILUA_DLL = $(BUILD_DIR)/KopiLua.dll
NLUA_NET40_PC = $(BUILD_DIR)/nlua.net40.pc
$(eval $(call emit-deploy-target,KERALUA_DLL))
$(eval $(call emit-deploy-target,KERALUA_DLL_MDB))
$(eval $(call emit-deploy-target,KOPILUA_DLL))
$(eval $(call emit-deploy-target,KOPILUA_DLL_MDB))
$(eval $(call emit-deploy-wrapper,NLUA_NET40_PC,nlua.net40.pc))
$(eval $(call emit_resgen_targets))
$(build_xamlg_list): %.xaml.g.cs: %.xaml
xamlg '$<'
$(ASSEMBLY_MDB): $(ASSEMBLY)
$(ASSEMBLY): $(build_sources) $(build_resources) $(build_datafiles) $(DLL_REFERENCES) $(PROJECT_REFERENCES) $(build_xamlg_list) $(build_satellite_assembly_list)
mkdir -p $(shell dirname $(ASSEMBLY))
$(ASSEMBLY_COMPILER_COMMAND) $(ASSEMBLY_COMPILER_FLAGS) -out:$(ASSEMBLY) -target:$(COMPILE_TARGET) $(build_sources_embed) $(build_resources_embed) $(build_references_ref)
/*
* This file is part of NLua.
* Copyright (C) 2015 Vinicius Jarina.
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
using System.Linq;
using System.IO;
using System.Collections;
using System.Reflection;
using System.Diagnostics;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using NLua.Method;
using NLua.Extensions;
#if MONOTOUCH
using ObjCRuntime;
#endif
namespace NLua
{
#if USE_KOPILUA
using LuaCore = KopiLua.Lua;
using LuaState = KopiLua.LuaState;
using LuaNativeFunction = KopiLua.LuaNativeFunction;
#else
using LuaCore = KeraLua.Lua;
using LuaState = KeraLua.LuaState;
using LuaNativeFunction = KeraLua.LuaNativeFunction;
#endif
/*
* Functions used in the metatables of userdata representing
* CLR objects
*
*/
public class MetaFunctions
{
public LuaNativeFunction GcFunction { get; private set; }
public LuaNativeFunction IndexFunction { get; private set; }
public LuaNativeFunction NewIndexFunction { get; private set; }
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 CallDelegateFunction { 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.
*/
static string luaIndexFunction =
@"local function index(obj,name)
local meta = getmetatable(obj)
local cached = meta.cache[name]
if cached ~= nil then
return cached
else
local value,isFunc = get_object_member(obj,name)
if isFunc then
meta.cache[name]=value
end
return value
end
end
return index";
public static string LuaIndexFunction {
get { return luaIndexFunction; }
}
public MetaFunctions (ObjectTranslator translator)
{
this.translator = translator;
GcFunction = new LuaNativeFunction (MetaFunctions.CollectObject);
ToStringFunction = new LuaNativeFunction (MetaFunctions.ToStringLua);
IndexFunction = new LuaNativeFunction (MetaFunctions.GetMethod);
NewIndexFunction = new LuaNativeFunction (MetaFunctions.SetFieldOrProperty);
BaseIndexFunction = new LuaNativeFunction (MetaFunctions.GetBaseMethod);
CallConstructorFunction = new LuaNativeFunction (MetaFunctions.CallConstructor);
ClassIndexFunction = new LuaNativeFunction (MetaFunctions.GetClassMethod);
ClassNewindexFunction = new LuaNativeFunction (MetaFunctions.SetClassFieldOrProperty);
ExecuteDelegateFunction = new LuaNativeFunction (MetaFunctions.RunFunctionDelegate);
CallDelegateFunction = new LuaNativeFunction (MetaFunctions.CallDelegate);
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);
}
/*
* __call metafunction of CLR delegates, retrieves and calls the delegate.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
private static int RunFunctionDelegate (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return RunFunctionDelegate (luaState, translator);
}
private static int RunFunctionDelegate (LuaState luaState, ObjectTranslator translator)
{
LuaNativeFunction func = (LuaNativeFunction)translator.GetRawNetObject (luaState, 1);
LuaLib.LuaRemove (luaState, 1);
return func (luaState);
}
/*
* __gc metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
private static int CollectObject (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return CollectObject (luaState, translator);
}
private static int CollectObject (LuaState luaState, ObjectTranslator translator)
{
int udata = LuaLib.LuaNetRawNetObj (luaState, 1);
if (udata != -1)
translator.CollectObject (udata);
return 0;
}
/*
* __tostring metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
private static int ToStringLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return ToStringLua (luaState, translator);
}
private static int ToStringLua (LuaState luaState, ObjectTranslator translator)
{
object obj = translator.GetRawNetObject (luaState, 1);
if (obj != null)
translator.Push (luaState, obj.ToString () + ": " + obj.GetHashCode ().ToString());
else
LuaLib.LuaPushNil (luaState);
return 1;
}
/*
* __add metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
static int AddLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return MatchOperator (luaState, "op_Addition", translator);
}
/*
* __sub metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
static int SubtractLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return MatchOperator (luaState, "op_Subtraction", translator);
}
/*
* __mul metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
static int MultiplyLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return MatchOperator (luaState, "op_Multiply", translator);
}
/*
* __div metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
static int DivideLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return MatchOperator (luaState, "op_Division", translator);
}
/*
* __mod metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
static int ModLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return MatchOperator (luaState, "op_Modulus", translator);
}
/*
* __unm metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
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
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
static int EqualLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return MatchOperator (luaState, "op_Equality", translator);
}
/*
* __lt metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
static int LessThanLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return MatchOperator (luaState, "op_LessThan", translator);
}
/*
* __le metafunction of CLR objects.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
static int LessThanOrEqualLua (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
return MatchOperator (luaState, "op_LessThanOrEqual", translator);
}
/// <summary>
/// Debug tool to dump the lua stack
/// </summary>
/// FIXME, move somewhere else
public static void DumpStack (ObjectTranslator translator, LuaState luaState)
{
int depth = LuaLib.LuaGetTop (luaState);
#if WINDOWS_PHONE || NETFX_CORE
Debug.WriteLine("lua stack depth: {0}", depth);
#elif UNITY_3D
UnityEngine.Debug.Log(string.Format("lua stack depth: {0}", depth));
#elif !SILVERLIGHT
Debug.Print ("lua stack depth: {0}", depth);
#endif
for (int i = 1; i <= depth; i++) {
var type = LuaLib.LuaType (luaState, i);
// we dump stacks when deep in calls, calling typename while the stack is in flux can fail sometimes, so manually check for key types
string typestr = (type == LuaTypes.Table) ? "table" : LuaLib.LuaTypeName (luaState, type);
string strrep = LuaLib.LuaToString (luaState, i).ToString ();
if (type == LuaTypes.UserData) {
object obj = translator.GetRawNetObject (luaState, i);
strrep = obj.ToString ();
}
#if WINDOWS_PHONE || NETFX_CORE
Debug.WriteLine("{0}: ({1}) {2}", i, typestr, strrep);
#elif UNITY_3D
UnityEngine.Debug.Log(string.Format("{0}: ({1}) {2}", i, typestr, strrep));
#elif !SILVERLIGHT
Debug.Print ("{0}: ({1}) {2}", i, typestr, strrep);
#endif
}
}
/*
* Called by the __index metafunction of CLR objects in case the
* method is not cached or it is a field/property/event.
* Receives the object and the member name as arguments and returns
* either the value of the member or a delegate to call it.
* If the member does not exist returns nil.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
private static int GetMethod (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
var instance = translator.MetaFunctionsInstance;
return instance.GetMethodInternal (luaState);
}
private int GetMethodInternal (LuaState luaState)
{
object obj = translator.GetRawNetObject (luaState, 1);
if (obj == null) {
translator.ThrowError (luaState, "trying to index an invalid object reference");
LuaLib.LuaPushNil (luaState);
return 1;
}
object index = translator.GetObject (luaState, 2);
//var indexType = index.GetType();
string methodName = index as string; // will be null if not a string arg
var objType = obj.GetType ();
var proxyType = new ProxyType (objType);
// Handle the most common case, looking up the method by name.
// CP: This will fail when using indexers and attempting to get a value with the same name as a property of the object,
// ie: xmlelement['item'] <- item is a property of xmlelement
try {
if (!string.IsNullOrEmpty(methodName) && IsMemberPresent (proxyType, methodName))
return GetMember (luaState, proxyType, obj, methodName, BindingFlags.Instance);
} catch {
}
// Try to access by array if the type is right and index is an int (lua numbers always come across as double)
if (objType.IsArray && index is double) {
int intIndex = (int)((double)index);
#if NETFX_CORE
Type type = objType;
#else
Type type = objType.UnderlyingSystemType;
#endif
if (type == typeof(float[])) {
float[] arr = ((float[])obj);
translator.Push (luaState, arr [intIndex]);
} else if (type == typeof(double[])) {
double[] arr = ((double[])obj);
translator.Push (luaState, arr [intIndex]);
} else if (type == typeof(int[])) {
int[] arr = ((int[])obj);
translator.Push (luaState, arr [intIndex]);
} else {
object[] arr = (object[])obj;
translator.Push (luaState, arr [intIndex]);
}
} else {
if (!string.IsNullOrEmpty (methodName) && IsExtensionMethodPresent (objType, methodName)) {
return GetExtensionMethod (luaState, objType, obj, methodName);
}
// Try to use get_Item to index into this .net object
var methods = objType.GetMethods ();
foreach (var mInfo in methods) {
if (mInfo.Name == "get_Item") {
//check if the signature matches the input
if (mInfo.GetParameters ().Length == 1) {
var getter = mInfo;
var actualParms = (getter != null) ? getter.GetParameters () : null;
if (actualParms == null || actualParms.Length != 1) {
translator.ThrowError (luaState, "method not found (or no indexer): " + index);
LuaLib.LuaPushNil (luaState);
} else {
// Get the index in a form acceptable to the getter
index = translator.GetAsType (luaState, 2, actualParms [0].ParameterType);
object[] args = new object[1];
// Just call the indexer - if out of bounds an exception will happen
args [0] = index;
try {
object result = getter.Invoke (obj, args);
translator.Push (luaState, result);
} catch (TargetInvocationException e) {
// Provide a more readable description for the common case of key not found
if (e.InnerException is KeyNotFoundException)
translator.ThrowError (luaState, "key '" + index + "' not found ");
else
translator.ThrowError (luaState, "exception indexing '" + index + "' " + e.Message);
LuaLib.LuaPushNil (luaState);
}
}
}
}
}
}
LuaLib.LuaPushBoolean (luaState, false);
return 2;
}
/*
* __index metafunction of base classes (the base field of Lua tables).
* Adds a prefix to the method name to call the base version of the method.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
private static int GetBaseMethod (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
var instance = translator.MetaFunctionsInstance;
return instance.GetBaseMethodInternal (luaState);
}
private int GetBaseMethodInternal (LuaState luaState)
{
object obj = translator.GetRawNetObject (luaState, 1);
if (obj == null) {
translator.ThrowError (luaState, "trying to index an invalid object reference");
LuaLib.LuaPushNil (luaState);
LuaLib.LuaPushBoolean (luaState, false);
return 2;
}
string methodName = LuaLib.LuaToString (luaState, 2).ToString ();
if (string.IsNullOrEmpty(methodName)) {
LuaLib.LuaPushNil (luaState);
LuaLib.LuaPushBoolean (luaState, false);
return 2;
}
GetMember (luaState, new ProxyType(obj.GetType ()), obj, "__luaInterface_base_" + methodName, BindingFlags.Instance);
LuaLib.LuaSetTop (luaState, -2);
if (LuaLib.LuaType (luaState, -1) == LuaTypes.Nil) {
LuaLib.LuaSetTop (luaState, -2);
return GetMember (luaState, new ProxyType(obj.GetType ()), obj, methodName, BindingFlags.Instance);
}
LuaLib.LuaPushBoolean (luaState, false);
return 2;
}
/// <summary>
/// Does this method exist as either an instance or static?
/// </summary>
/// <param name="objType"></param>
/// <param name="methodName"></param>
/// <returns></returns>
bool IsMemberPresent (ProxyType objType, string methodName)
{
object cachedMember = CheckMemberCache (memberCache, objType, methodName);
if (cachedMember != null)
return true;
var members = objType.GetMember (methodName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public);
return (members.Length > 0);
}
bool IsExtensionMethodPresent (Type type, string name)
{
object cachedMember = CheckMemberCache (memberCache, type, name);
if (cachedMember != null)
return true;
return translator.IsExtensionMethodPresent (type, name);
}
int GetExtensionMethod (LuaState luaState, Type type, object obj, string name)
{
object cachedMember = CheckMemberCache (memberCache, type, name);
if (cachedMember != null && cachedMember is LuaNativeFunction) {
translator.PushFunction (luaState, (LuaNativeFunction)cachedMember);
translator.Push (luaState, true);
return 2;
}
MethodInfo methodInfo = translator.GetExtensionMethod (type, name);
var wrapper = new LuaNativeFunction ((new LuaMethodWrapper (translator, obj,new ProxyType(type), methodInfo)).invokeFunction);
SetMemberCache (memberCache, type, name, wrapper);
translator.PushFunction (luaState, wrapper);
translator.Push (luaState, true);
return 2;
}
/*
* Pushes the value of a member or a delegate to call it, depending on the type of
* the member. Works with static or instance members.
* Uses reflection to find members, and stores the reflected MemberInfo object in
* a cache (indexed by the type of the object and the name of the member).
*/
int GetMember (LuaState luaState, ProxyType objType, object obj, string methodName, BindingFlags bindingType)
{
bool implicitStatic = false;
MemberInfo member = null;
object cachedMember = CheckMemberCache (memberCache, objType, methodName);
if (cachedMember is LuaNativeFunction) {
translator.PushFunction (luaState, (LuaNativeFunction)cachedMember);
translator.Push (luaState, true);
return 2;
} else if (cachedMember != null)
member = (MemberInfo)cachedMember;
else {
var members = objType.GetMember (methodName, bindingType | BindingFlags.Public);
if (members.Length > 0)
member = members [0];
else {
// If we can't find any suitable instance members, try to find them as statics - but we only want to allow implicit static
members = objType.GetMember (methodName, bindingType | BindingFlags.Static | BindingFlags.Public);
if (members.Length > 0) {
member = members [0];
implicitStatic = true;
}
}
}
if (member != null) {
#if NETFX_CORE
if (member is FieldInfo) {
#else
if (member.MemberType == MemberTypes.Field) {
#endif
var field = (FieldInfo)member;
if (cachedMember == null)
SetMemberCache (memberCache, objType, methodName, member);
try {
var value = field.GetValue (obj);
translator.Push (luaState, value);
} catch {
LuaLib.LuaPushNil (luaState);
}
#if NETFX_CORE
} else if (member is PropertyInfo) {
#else
} else if (member.MemberType == MemberTypes.Property) {
#endif
var property = (PropertyInfo)member;
if (cachedMember == null)
SetMemberCache (memberCache, objType, methodName, member);
try {
object value = property.GetValue (obj, null);
translator.Push (luaState, value);
} catch (ArgumentException) {
// If we can't find the getter in our class, recurse up to the base class and see
// if they can help.
if (objType.UnderlyingSystemType != typeof(object))
#if NETFX_CORE
return GetMember (luaState, new ProxyType(objType.UnderlyingSystemType.GetTypeInfo().BaseType), obj, methodName, bindingType);
#else
return GetMember (luaState, new ProxyType(objType.UnderlyingSystemType.BaseType), obj, methodName, bindingType);
#endif
else
LuaLib.LuaPushNil (luaState);
} catch (TargetInvocationException e) { // Convert this exception into a Lua error
ThrowError (luaState, e);
LuaLib.LuaPushNil (luaState);
}
#if NETFX_CORE
} else if (member is EventInfo) {
#else
} else if (member.MemberType == MemberTypes.Event) {
#endif
var eventInfo = (EventInfo)member;
if (cachedMember == null)
SetMemberCache (memberCache, objType, methodName, member);
translator.Push (luaState, new RegisterEventHandler (translator.pendingEvents, obj, eventInfo));
} else if (!implicitStatic) {
#if NETFX_CORE
var typeInfo = member as TypeInfo;
if (typeInfo != null && !typeInfo.IsPublic && !typeInfo.IsNotPublic) {
#else
if (member.MemberType == MemberTypes.NestedType) {
#endif
// kevinh - added support for finding nested types-
// cache us
if (cachedMember == null)
SetMemberCache (memberCache, objType, methodName, member);
// Find the name of our class
string name = member.Name;
var dectype = member.DeclaringType;
// Build a new long name and try to find the type by name
string longname = dectype.FullName + "+" + name;
var nestedType = translator.FindType (longname);
translator.PushType (luaState, nestedType);
} else {
// Member type must be 'method'
var wrapper = new LuaNativeFunction ((new LuaMethodWrapper (translator, objType, methodName, bindingType)).invokeFunction);
if (cachedMember == null)
SetMemberCache (memberCache, objType, methodName, wrapper);
translator.PushFunction (luaState, wrapper);
translator.Push (luaState, true);
return 2;
}
} else {
// If we reach this point we found a static method, but can't use it in this context because the user passed in an instance
translator.ThrowError (luaState, "can't pass instance to static method " + methodName);
LuaLib.LuaPushNil (luaState);
}
} else {
if (objType.UnderlyingSystemType != typeof(object)) {
#if NETFX_CORE
return GetMember (luaState, new ProxyType(objType.UnderlyingSystemType.GetTypeInfo().BaseType), obj, methodName, bindingType);
#else
return GetMember (luaState, new ProxyType(objType.UnderlyingSystemType.BaseType), obj, methodName, bindingType);
#endif
}
// kevinh - we want to throw an exception because meerly returning 'nil' in this case
// is not sufficient. valid data members may return nil and therefore there must be some
// way to know the member just doesn't exist.
translator.ThrowError (luaState, "unknown member name " + methodName);
LuaLib.LuaPushNil (luaState);
}
// push false because we are NOT returning a function (see luaIndexFunction)
translator.Push (luaState, false);
return 2;
}
/*
* Checks if a MemberInfo object is cached, returning it or null.
*/
object CheckMemberCache (Dictionary<object, object> memberCache, Type objType, string memberName)
{
return CheckMemberCache (memberCache, new ProxyType (objType), memberName);
}
object CheckMemberCache (Dictionary<object, object> memberCache, ProxyType objType, string memberName)
{
object members = null;
if (memberCache.TryGetValue(objType, out members))
{
var membersDict = members as Dictionary<object, object>;
object memberValue = null;
if (members != null && membersDict.TryGetValue(memberName, out memberValue))
{
return memberValue;
}
}
return null;
}
/*
* Stores a MemberInfo object in the member cache.
*/
void SetMemberCache (Dictionary<object, object> memberCache, Type objType, string memberName, object member)
{
SetMemberCache (memberCache, new ProxyType (objType), memberName, member);
}
void SetMemberCache (Dictionary<object, object> memberCache, ProxyType objType, string memberName, object member)
{
Dictionary<object, object> members = null;
object memberCacheValue = null;
if (memberCache.TryGetValue(objType, out memberCacheValue)) {
members = (Dictionary<object, object>)memberCacheValue;
} else {
members = new Dictionary<object, object>();
memberCache[objType] = members;
}
members [memberName] = member;
}
/*
* __newindex metafunction of CLR objects. Receives the object,
* the member name and the value to be stored as arguments. Throws
* and error if the assignment is invalid.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
private static int SetFieldOrProperty (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
var instance = translator.MetaFunctionsInstance;
return instance.SetFieldOrPropertyInternal (luaState);
}
private int SetFieldOrPropertyInternal (LuaState luaState)
{
object target = translator.GetRawNetObject (luaState, 1);
if (target == null) {
translator.ThrowError (luaState, "trying to index and invalid object reference");
return 0;
}
var type = target.GetType ();
// First try to look up the parameter as a property name
string detailMessage;
bool didMember = TrySetMember (luaState, new ProxyType(type), target, BindingFlags.Instance, out detailMessage);
if (didMember)
return 0; // Must have found the property name
// We didn't find a property name, now see if we can use a [] style this accessor to set array contents
try {
if (type.IsArray && LuaLib.LuaIsNumber (luaState, 2)) {
int index = (int)LuaLib.LuaToNumber (luaState, 2);
var arr = (Array)target;
object val = translator.GetAsType (luaState, 3, arr.GetType ().GetElementType ());
arr.SetValue (val, index);
} else {
// Try to see if we have a this[] accessor
var setter = type.GetMethod ("set_Item");
if (setter != null) {
var args = setter.GetParameters ();
var valueType = args [1].ParameterType;
// The new val ue the user specified
object val = translator.GetAsType (luaState, 3, valueType);
var indexType = args [0].ParameterType;
object index = translator.GetAsType (luaState, 2, indexType);
object[] methodArgs = new object[2];
// Just call the indexer - if out of bounds an exception will happen
methodArgs [0] = index;
methodArgs [1] = val;
setter.Invoke (target, methodArgs);
} else
translator.ThrowError (luaState, detailMessage); // Pass the original message from trySetMember because it is probably best
}
#if !SILVERLIGHT
} catch (SEHException) {
// If we are seeing a C++ exception - this must actually be for Lua's private use. Let it handle it
throw;
#endif
} catch (Exception e) {
ThrowError (luaState, e);
}
return 0;
}
/// <summary>
/// Tries to set a named property or field
/// </summary>
/// <param name="luaState"></param>
/// <param name="targetType"></param>
/// <param name="target"></param>
/// <param name="bindingType"></param>
/// <returns>false if unable to find the named member, true for success</returns>
bool TrySetMember (LuaState luaState, ProxyType targetType, object target, BindingFlags bindingType, out string detailMessage)
{
detailMessage = null; // No error yet
// If not already a string just return - we don't want to call tostring - which has the side effect of
// changing the lua typecode to string
// Note: We don't use isstring because the standard lua C isstring considers either strings or numbers to
// be true for isstring.
if (LuaLib.LuaType (luaState, 2) != LuaTypes.String) {
detailMessage = "property names must be strings";
return false;
}
// We only look up property names by string
string fieldName = LuaLib.LuaToString (luaState, 2).ToString ();
if (fieldName == null || fieldName.Length < 1 || !(char.IsLetter (fieldName [0]) || fieldName [0] == '_')) {
detailMessage = "invalid property name";
return false;
}
// Find our member via reflection or the cache
var member = (MemberInfo)CheckMemberCache (memberCache, targetType, fieldName);
if (member == null) {
var members = targetType.GetMember (fieldName, bindingType | BindingFlags.Public);
if (members.Length > 0) {
member = members [0];
SetMemberCache (memberCache, targetType, fieldName, member);
} else {
detailMessage = "field or property '" + fieldName + "' does not exist";
return false;
}
}
#if NETFX_CORE
if (member is FieldInfo) {
#else
if (member.MemberType == MemberTypes.Field) {
#endif
var field = (FieldInfo)member;
object val = translator.GetAsType (luaState, 3, field.FieldType);
try {
field.SetValue (target, val);
} catch (Exception e) {
ThrowError (luaState, e);
}
// We did a call
return true;
#if NETFX_CORE
} else if (member is PropertyInfo) {
#else
} else if (member.MemberType == MemberTypes.Property) {
#endif
var property = (PropertyInfo)member;
object val = translator.GetAsType (luaState, 3, property.PropertyType);
try {
property.SetValue (target, val, null);
} catch (Exception e) {
ThrowError (luaState, e);
}
// We did a call
return true;
}
detailMessage = "'" + fieldName + "' is not a .net field or property";
return false;
}
/*
* Writes to fields or properties, either static or instance. Throws an error
* if the operation is invalid.
*/
private int SetMember (LuaState luaState, ProxyType targetType, object target, BindingFlags bindingType)
{
string detail;
bool success = TrySetMember (luaState, targetType, target, bindingType, out detail);
if (!success)
translator.ThrowError (luaState, detail);
return 0;
}
/// <summary>
/// Convert a C# exception into a Lua error
/// </summary>
/// <param name="e"></param>
/// We try to look into the exception to give the most meaningful description
void ThrowError (LuaState luaState, Exception e)
{
// If we got inside a reflection show what really happened
var te = e as TargetInvocationException;
if (te != null)
e = te.InnerException;
translator.ThrowError (luaState, e);
}
/*
* __index metafunction of type references, works on static members.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
private static int GetClassMethod (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
var instance = translator.MetaFunctionsInstance;
return instance.GetClassMethodInternal (luaState);
}
private int GetClassMethodInternal (LuaState luaState)
{
ProxyType klass;
object obj = translator.GetRawNetObject (luaState, 1);
if (obj == null || !(obj is ProxyType)) {
translator.ThrowError (luaState, "trying to index an invalid type reference");
LuaLib.LuaPushNil (luaState);
return 1;
} else
klass = (ProxyType)obj;
if (LuaLib.LuaIsNumber (luaState, 2)) {
int size = (int)LuaLib.LuaToNumber (luaState, 2);
translator.Push (luaState, Array.CreateInstance (klass.UnderlyingSystemType, size));
return 1;
} else {
string methodName = LuaLib.LuaToString (luaState, 2).ToString ();
if (string.IsNullOrEmpty(methodName)) {
LuaLib.LuaPushNil (luaState);
return 1;
}
else
return GetMember (luaState, klass, null, methodName, BindingFlags.Static);
}
}
/*
* __newindex function of type references, works on static members.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
private static int SetClassFieldOrProperty (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
var instance = translator.MetaFunctionsInstance;
return instance.SetClassFieldOrPropertyInternal (luaState);
}
private int SetClassFieldOrPropertyInternal (LuaState luaState)
{
ProxyType target;
object obj = translator.GetRawNetObject (luaState, 1);
if (obj == null || !(obj is ProxyType)) {
translator.ThrowError (luaState, "trying to index an invalid type reference");
return 0;
} else
target = (ProxyType)obj;
return SetMember (luaState, target, null, BindingFlags.Static);
}
/*
* __call metafunction of Delegates.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
static int CallDelegate (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
var instance = translator.MetaFunctionsInstance;
return instance.CallDelegateInternal (luaState);
}
int CallDelegateInternal (LuaState luaState)
{
object objDelegate = translator.GetRawNetObject (luaState, 1);
if (objDelegate == null || !(objDelegate is Delegate)) {
translator.ThrowError (luaState, "trying to invoke a not delegate or callable value");
LuaLib.LuaPushNil (luaState);
return 1;
}
LuaLib.LuaRemove (luaState, 1);
var validDelegate = new MethodCache ();
Delegate del = (Delegate)objDelegate;
#if NETFX_CORE || WP80 || NET45 || PCL
MethodBase methodDelegate = del.GetMethodInfo ();
#else
MethodBase methodDelegate = del.Method;
#endif
bool isOk = MatchParameters (luaState, methodDelegate, ref validDelegate);
if (isOk) {
object result;
if (methodDelegate.IsStatic)
result = methodDelegate.Invoke (null, validDelegate.args);
else
result = methodDelegate.Invoke (del.Target, validDelegate.args);
translator.Push (luaState, result);
return 1;
}
translator.ThrowError (luaState, "Cannot invoke delegate (invalid arguments for " + methodDelegate.Name + ")");
LuaLib.LuaPushNil (luaState);
return 1;
}
/*
* __call metafunction of type references. Searches for and calls
* a constructor for the type. Returns nil if the constructor is not
* found or if the arguments are invalid. Throws an error if the constructor
* generates an exception.
*/
#if MONOTOUCH
[MonoPInvokeCallback (typeof (LuaNativeFunction))]
#endif
private static int CallConstructor (LuaState luaState)
{
var translator = ObjectTranslatorPool.Instance.Find (luaState);
var instance = translator.MetaFunctionsInstance;
return instance.CallConstructorInternal (luaState);
}
private int CallConstructorInternal (LuaState luaState)
{
var validConstructor = new MethodCache ();
ProxyType klass;
object obj = translator.GetRawNetObject (luaState, 1);
if (obj == null || !(obj is ProxyType)) {
translator.ThrowError (luaState, "trying to call constructor on an invalid type reference");
LuaLib.LuaPushNil (luaState);
return 1;
} else
klass = (ProxyType)obj;
LuaLib.LuaRemove (luaState, 1);
var constructors = klass.UnderlyingSystemType.GetConstructors ();
foreach (var constructor in constructors) {
bool isConstructor = MatchParameters (luaState, constructor, ref validConstructor);
if (isConstructor) {
try {
translator.Push (luaState, constructor.Invoke (validConstructor.args));
} catch (TargetInvocationException e) {
ThrowError (luaState, e);
LuaLib.LuaPushNil (luaState);
} catch {
LuaLib.LuaPushNil (luaState);
}
return 1;
}
}
#if NETFX_CORE
if (klass.UnderlyingSystemType.GetTypeInfo ().IsValueType) {
#else
if (klass.UnderlyingSystemType.IsValueType) {
#endif
int numLuaParams = LuaLib.LuaGetTop (luaState);
if (numLuaParams == 0) {
translator.Push (luaState, Activator.CreateInstance (klass.UnderlyingSystemType));
return 1;
}
}
string constructorName = (constructors.Length == 0) ? "unknown" : constructors [0].Name;
translator.ThrowError (luaState, String.Format ("{0} does not contain constructor({1}) argument match",
klass.UnderlyingSystemType, constructorName));
LuaLib.LuaPushNil (luaState);
return 1;
}
static bool IsInteger(double x) {
return Math.Ceiling(x) == x;
}
static object GetTargetObject (LuaState luaState, string operation, ObjectTranslator translator)
{
Type t;
object target = translator.GetRawNetObject (luaState, 1);
if (target != null) {
t = target.GetType ();
if (t.HasMethod (operation))
return target;
}
target = translator.GetRawNetObject (luaState, 2);
if (target != null) {
t = target.GetType ();
if (t.HasMethod (operation))
return target;
}
return null;
}
static int MatchOperator (LuaState luaState, string operation, ObjectTranslator translator)
{
var validOperator = new MethodCache ();
object target = GetTargetObject (luaState, operation, translator);
if (target == null) {
translator.ThrowError (luaState, "Cannot call " + operation + " on a nil object");
LuaLib.LuaPushNil (luaState);
return 1;
}
Type type = target.GetType ();
var operators = type.GetMethods (operation, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
foreach (var op in operators) {
bool isOk = translator.MatchParameters (luaState, op, ref validOperator);
if (!isOk)
continue;
object result;
if (op.IsStatic)
result = op.Invoke (null, validOperator.args);
else
result = op.Invoke (target, validOperator.args);
translator.Push (luaState, result);
return 1;
}
translator.ThrowError (luaState, "Cannot call (" + operation + ") on object type " + type.Name);
LuaLib.LuaPushNil (luaState);
return 1;
}
internal Array TableToArray (Func<int, object> luaParamValueExtractor, Type paramArrayType, int startIndex, int count)
{
Array paramArray;
if (count == 0)
return Array.CreateInstance (paramArrayType, 0);
var luaParamValue = luaParamValueExtractor (startIndex);
if (luaParamValue is LuaTable) {
LuaTable table = (LuaTable)luaParamValue;
IDictionaryEnumerator tableEnumerator = table.GetEnumerator ();
tableEnumerator.Reset ();
paramArray = Array.CreateInstance (paramArrayType, table.Values.Count);
int paramArrayIndex = 0;
while (tableEnumerator.MoveNext ()) {
object value = tableEnumerator.Value;
if (paramArrayType == typeof (object)) {
if (value != null && value.GetType () == typeof (double) && IsInteger ((double)value))
value = Convert.ToInt32 ((double)value);
}
#if SILVERLIGHT
paramArray.SetValue (Convert.ChangeType (value, paramArrayType, System.Globalization.CultureInfo.InvariantCulture), paramArrayIndex);
#else
paramArray.SetValue (Convert.ChangeType (value, paramArrayType), paramArrayIndex);
#endif
paramArrayIndex++;
}
} else {
paramArray = Array.CreateInstance (paramArrayType, count);
paramArray.SetValue (luaParamValue, 0);
for (int i = 1; i < count; i++) {
startIndex++;
var value = luaParamValueExtractor (startIndex);
paramArray.SetValue (value, i);
}
}
return paramArray;
}
/*
* Matches a method against its arguments in the Lua stack. Returns
* if the match was successful. It it was also returns the information
* necessary to invoke the method.
*/
internal bool MatchParameters (LuaState luaState, MethodBase method, ref MethodCache methodCache)
{
ExtractValue extractValue;
bool isMethod = true;
var paramInfo = method.GetParameters ();
int currentLuaParam = 1;
int nLuaParams = LuaLib.LuaGetTop (luaState);
var paramList = new List<object> ();
var outList = new List<int> ();
var argTypes = new List<MethodArgs> ();
foreach (var currentNetParam in paramInfo) {
#if !SILVERLIGHT
if (!currentNetParam.IsIn && currentNetParam.IsOut) // Skips out params
#else
if (currentNetParam.IsOut) // Skips out params
#endif
{
paramList.Add (null);
outList.Add (paramList.LastIndexOf (null));
} // Type does not match, ignore if the parameter is optional
else if (IsParamsArray (luaState, nLuaParams, currentLuaParam, currentNetParam, out extractValue)) {
int count = (nLuaParams - currentLuaParam) + 1;
Type paramArrayType = currentNetParam.ParameterType.GetElementType ();
Func<int, object> extractDelegate = (currentParam) => {
currentLuaParam++;
return extractValue (luaState, currentParam);
};
Array paramArray = TableToArray (extractDelegate, paramArrayType, currentLuaParam, count);
paramList.Add (paramArray);
int index = paramList.LastIndexOf (paramArray);
var methodArg = new MethodArgs ();
methodArg.index = index;
methodArg.extractValue = extractValue;
methodArg.isParamsArray = true;
methodArg.paramsArrayType = paramArrayType;
argTypes.Add (methodArg);
}
else if (IsTypeCorrect(luaState, currentLuaParam, currentNetParam, out extractValue))
{ // Type checking
var value = extractValue(luaState, currentLuaParam);
paramList.Add(value);
int index = paramList.LastIndexOf(value);
var methodArg = new MethodArgs();
methodArg.index = index;
methodArg.extractValue = extractValue;
argTypes.Add(methodArg);
if (currentNetParam.ParameterType.IsByRef)
outList.Add(index);
currentLuaParam++;
} else if (currentLuaParam > nLuaParams) { // Adds optional parameters
if (currentNetParam.IsOptional)
paramList.Add (currentNetParam.DefaultValue);
else {
isMethod = false;
break;
}
} else if (currentNetParam.IsOptional)
paramList.Add (currentNetParam.DefaultValue);
else { // No match
isMethod = false;
break;
}
}
if (currentLuaParam != nLuaParams + 1) // Number of parameters does not match
isMethod = false;
if (isMethod) {
methodCache.args = paramList.ToArray ();
methodCache.cachedMethod = method;
methodCache.outList = outList.ToArray ();
methodCache.argTypes = argTypes.ToArray ();
}
return isMethod;
}
/// <summary>
/// CP: Fix for operator overloading failure
/// Returns true if the type is set and assigns the extract value
/// </summary>
/// <param name="luaState"></param>
/// <param name="currentLuaParam"></param>
/// <param name="currentNetParam"></param>
/// <param name="extractValue"></param>
/// <returns></returns>
private bool IsTypeCorrect (LuaState luaState, int currentLuaParam, ParameterInfo currentNetParam, out ExtractValue extractValue)
{
try {
return (extractValue = translator.typeChecker.CheckLuaType (luaState, currentLuaParam, currentNetParam.ParameterType)) != null;
} catch {
extractValue = null;
Debug.WriteLine ("Type wasn't correct");
return false;
}
}
private bool IsParamsArray (LuaState luaState, int nLuaParams, int currentLuaParam, ParameterInfo currentNetParam, out ExtractValue extractValue)
{
extractValue = null;
bool isParamArray = false;
if (currentNetParam.GetCustomAttributes (typeof(ParamArrayAttribute), false).Any ()) {
isParamArray = nLuaParams < currentLuaParam;
LuaTypes luaType;
try {
luaType = LuaLib.LuaType (luaState, currentLuaParam);
} catch (Exception ex) {
Debug.WriteLine ("Could not retrieve lua type while attempting to determine params Array Status.");
Debug.WriteLine (ex.Message);
extractValue = null;
return false;
}
if (luaType == LuaTypes.Table) {
try {
extractValue = translator.typeChecker.GetExtractor (typeof(LuaTable));
} catch (Exception/* ex*/) {
Debug.WriteLine ("An error occurred during an attempt to retrieve a LuaTable extractor while checking for params array status.");
}
if (extractValue != null) {
return true;
}
} else {
var paramElementType = currentNetParam.ParameterType.GetElementType ();
try {
extractValue = translator.typeChecker.CheckLuaType (luaState, currentLuaParam, paramElementType);
} catch (Exception/* ex*/) {
Debug.WriteLine (string.Format ("An error occurred during an attempt to retrieve an extractor ({0}) while checking for params array status.", paramElementType.FullName));
}
if (extractValue != null) {
return true;
}
}
}
return isParamArray;
}
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
using System.Diagnostics;
using System.Collections.Generic;
namespace NLua.Method
{
/// <summary>
/// We keep track of what delegates we have auto attached to an event - to allow us to cleanly exit a NLua session
/// </summary>
class EventHandlerContainer : IDisposable
{
private Dictionary<Delegate, RegisterEventHandler> dict = new Dictionary<Delegate, RegisterEventHandler> ();
public void Add (Delegate handler, RegisterEventHandler eventInfo)
{
dict.Add (handler, eventInfo);
}
public void Remove (Delegate handler)
{
bool found = dict.Remove (handler);
Debug.Assert (found);
}
/// <summary>
/// Remove any still registered handlers
/// </summary>
public void Dispose ()
{
foreach (KeyValuePair<Delegate, RegisterEventHandler> pair in dict)
pair.Value.RemovePending (pair.Key);
dict.Clear ();
}
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
namespace NLua.Method
{
/*
* Static helper methods for Lua tables acting as CLR objects.
*
* Author: Fabio Mascarenhas
* Version: 1.0
*/
public class LuaClassHelper
{
/*
* Gets the function called name from the provided table,
* returning null if it does not exist
*/
public static LuaFunction GetTableFunction (LuaTable luaTable, string name)
{
if (luaTable == null)
return null;
object funcObj = luaTable.RawGet (name);
if (funcObj is LuaFunction)
return (LuaFunction)funcObj;
else
return null;
}
/*
* Calls the provided function with the provided parameters
*/
public static object CallFunction (LuaFunction function, object[] args, Type[] returnTypes, object[] inArgs, int[] outArgs)
{
// args is the return array of arguments, inArgs is the actual array
// of arguments passed to the function (with in parameters only), outArgs
// has the positions of out parameters
object returnValue;
int iRefArgs;
object[] returnValues = function.Call (inArgs, returnTypes);
if (returnTypes [0] == typeof(void)) {
returnValue = null;
iRefArgs = 0;
} else {
returnValue = returnValues [0];
iRefArgs = 1;
}
for (int i = 0; i < outArgs.Length; i++) {
args [outArgs [i]] = returnValues [iRefArgs];
iRefArgs++;
}
return returnValue;
}
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
namespace NLua.Method
{
/*
* Wrapper class for Lua functions as delegates
* Subclasses with correct signatures are created
* at runtime.
*
* Author: Fabio Mascarenhas
* Version: 1.0
*/
public class LuaDelegate
{
public LuaFunction function;
public Type[] returnTypes;
public LuaDelegate ()
{
function = null;
returnTypes = null;
}
public object CallFunction (object[] args, object[] inArgs, int[] outArgs)
{
// args is the return array of arguments, inArgs is the actual array
// of arguments passed to the function (with in parameters only), outArgs
// has the positions of out parameters
object returnValue;
int iRefArgs;
object[] returnValues = function.Call (inArgs, returnTypes);
if (returnTypes [0] == typeof(void)) {
returnValue = null;
iRefArgs = 0;
} else {
returnValue = returnValues [0];
iRefArgs = 1;
}
// Sets the value of out and ref parameters (from
// the values returned by the Lua function).
for (int i = 0; i < outArgs.Length; i++) {
args [outArgs [i]] = returnValues [iRefArgs];
iRefArgs++;
}
return returnValue;
}
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
namespace NLua.Method
{
/*
* Base wrapper class for Lua function event handlers.
* Subclasses that do actual event handling are created
* at runtime.
*
* Author: Fabio Mascarenhas
* Version: 1.0
*/
public class LuaEventHandler
{
public LuaFunction handler = null;
// CP: Fix provided by Ben Bryant for delegates with one param
// link: http://luaforge.net/forum/message.php?msg_id=9318
public void HandleEvent (object[] args)
{
handler.Call (args);
}
//public void handleEvent(object sender,object data)
//{
// handler.call(new object[] { sender,data },new Type[0]);
//}
}
}
\ No newline at end of file
/*
* This file is part of NLua.
*
* Copyright (C) 2003-2005 Fabio Mascarenhas de Queiroz.
* Copyright (C) 2012 Megax <http://megax.yeahunter.hu/>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using NLua.Exceptions;
using NLua.Extensions;
namespace NLua.Method
{
#if USE_KOPILUA
using LuaCore = KopiLua.Lua;
using LuaState = KopiLua.LuaState;
using LuaNativeFunction = KopiLua.LuaNativeFunction;
#else
using LuaCore = KeraLua.Lua;
using LuaState = KeraLua.LuaState;
using LuaNativeFunction = KeraLua.LuaNativeFunction;
#endif
/*
* Argument extraction with type-conversion function
*/
delegate object ExtractValue (LuaState luaState, int stackPos);
/*
* Wrapper class for methods/constructors accessed from Lua.
*
* Author: Fabio Mascarenhas
* Version: 1.0
*/
class LuaMethodWrapper
{
internal LuaNativeFunction invokeFunction;
ObjectTranslator _Translator;
MethodBase _Method;
MethodCache _LastCalledMethod = new MethodCache ();
string _MethodName;
MemberInfo[] _Members;
ExtractValue _ExtractTarget;
object _Target;
bool _IsStatic;
/*
* Constructs the wrapper for a known MethodBase instance
*/
public LuaMethodWrapper (ObjectTranslator translator, object target, ProxyType targetType, MethodBase method)
{
invokeFunction = new LuaNativeFunction (this.Call);
_Translator = translator;
_Target = target;
if (targetType != null)
_ExtractTarget = translator.typeChecker.GetExtractor (targetType);
_Method = method;
_MethodName = method.Name;
_IsStatic = method.IsStatic;
}
/*
* Constructs the wrapper for a known method name
*/
public LuaMethodWrapper (ObjectTranslator translator, ProxyType targetType, string methodName, BindingFlags bindingType)
{
invokeFunction = new LuaNativeFunction (this.Call);
_Translator = translator;
_MethodName = methodName;
if (targetType != null)
_ExtractTarget = translator.typeChecker.GetExtractor (targetType);
_IsStatic = (bindingType & BindingFlags.Static) == BindingFlags.Static;
_Members = GetMethodsRecursively (targetType.UnderlyingSystemType, methodName, bindingType | BindingFlags.Public);
}
MethodInfo [] GetMethodsRecursively (Type type, string methodName, BindingFlags bindingType)
{
if (type == typeof(object))
return type.GetMethods (methodName, bindingType);
var methods = type.GetMethods (methodName, bindingType);
#if NETFX_CORE
var baseMethods = GetMethodsRecursively (type.GetTypeInfo ().BaseType, methodName, bindingType);
#else
var baseMethods = GetMethodsRecursively (type.BaseType, methodName, bindingType);
#endif
return methods.Concat (baseMethods).ToArray ();
}
/// <summary>
/// Convert C# exceptions into Lua errors
/// </summary>
/// <returns>num of things on stack</returns>
/// <param name="e">null for no pending exception</param>
int SetPendingException (Exception e)
{
return _Translator.interpreter.SetPendingException (e);
}
/*
* Calls the method. Receives the arguments from the Lua stack
* and returns values in it.
*/
int Call (LuaState luaState)
{
var methodToCall = _Method;
object targetObject = _Target;
bool failedCall = true;
int nReturnValues = 0;
if (!LuaLib.LuaCheckStack (luaState, 5))
throw new LuaException ("Lua stack overflow");
bool isStatic = _IsStatic;
SetPendingException (null);
if (methodToCall == null) { // Method from name
if (isStatic)
targetObject = null;
else
targetObject = _ExtractTarget (luaState, 1);
if (_LastCalledMethod.cachedMethod != null) { // Cached?
int numStackToSkip = isStatic ? 0 : 1; // If this is an instance invoe we will have an extra arg on the stack for the targetObject
int numArgsPassed = LuaLib.LuaGetTop (luaState) - numStackToSkip;
MethodBase method = _LastCalledMethod.cachedMethod;
if (numArgsPassed == _LastCalledMethod.argTypes.Length) { // No. of args match?
if (!LuaLib.LuaCheckStack (luaState, _LastCalledMethod.outList.Length + 6))
throw new LuaException ("Lua stack overflow");
object [] args = _LastCalledMethod.args;
try {
for (int i = 0; i < _LastCalledMethod.argTypes.Length; i++) {
MethodArgs type = _LastCalledMethod.argTypes [i];
int index = i + 1 + numStackToSkip;
Func<int, object> valueExtractor = (currentParam) => {
return type.extractValue (luaState, currentParam);
};
if (_LastCalledMethod.argTypes [i].isParamsArray) {
int count = _LastCalledMethod.argTypes.Length - i;
Array paramArray = _Translator.TableToArray (valueExtractor, type.paramsArrayType, index, count);
args [_LastCalledMethod.argTypes [i].index] = paramArray;
} else {
args [type.index] = valueExtractor (index);
}
if (_LastCalledMethod.args [_LastCalledMethod.argTypes [i].index] == null &&
!LuaLib.LuaIsNil (luaState, i + 1 + numStackToSkip))
throw new LuaException (string.Format("argument number {0} is invalid",(i + 1)));
}
if (_IsStatic)
_Translator.Push (luaState, method.Invoke (null, _LastCalledMethod.args));
else {
if (method.IsConstructor)
_Translator.Push (luaState, ((ConstructorInfo)method).Invoke (_LastCalledMethod.args));
else
_Translator.Push (luaState, method.Invoke (targetObject, _LastCalledMethod.args));
}
failedCall = false;
} catch (TargetInvocationException e) {
// Failure of method invocation
if (_Translator.interpreter.UseTraceback) e.GetBaseException().Data["Traceback"] = _Translator.interpreter.GetDebugTraceback();
return SetPendingException (e.GetBaseException ());
} catch (Exception e) {
if (_Members.Length == 1) // Is the method overloaded?
// No, throw error
return SetPendingException (e);
}
}
}
// Cache miss
if (failedCall) {
// System.Diagnostics.Debug.WriteLine("cache miss on " + methodName);
// If we are running an instance variable, we can now pop the targetObject from the stack
if (!isStatic) {
if (targetObject == null) {
_Translator.ThrowError (luaState, String.Format ("instance method '{0}' requires a non null target object", _MethodName));
LuaLib.LuaPushNil (luaState);
return 1;
}
LuaLib.LuaRemove (luaState, 1); // Pops the receiver
}
bool hasMatch = false;
string candidateName = null;
foreach (var member in _Members) {
#if NETFX_CORE
candidateName = member.DeclaringType.Name + "." + member.Name;
#else
candidateName = member.ReflectedType.Name + "." + member.Name;
#endif
var m = (MethodInfo)member;
bool isMethod = _Translator.MatchParameters (luaState, m, ref _LastCalledMethod);
if (isMethod) {
hasMatch = true;
break;
}
}
if (!hasMatch) {
string msg = (candidateName == null) ? "invalid arguments to method call" : ("invalid arguments to method: " + candidateName);
_Translator.ThrowError (luaState, msg);
LuaLib.LuaPushNil (luaState);
return 1;
}
}
} else { // Method from MethodBase instance
if (methodToCall.ContainsGenericParameters) {
_Translator.MatchParameters (luaState, methodToCall, ref _LastCalledMethod);
if (methodToCall.IsGenericMethodDefinition) {
//need to make a concrete type of the generic method definition
var typeArgs = new List<Type> ();
foreach (object arg in _LastCalledMethod.args)
typeArgs.Add (arg.GetType ());
var concreteMethod = (methodToCall as MethodInfo).MakeGenericMethod (typeArgs.ToArray ());
_Translator.Push (luaState, concreteMethod.Invoke (targetObject, _LastCalledMethod.args));
failedCall = false;
} else if (methodToCall.ContainsGenericParameters) {
_Translator.ThrowError (luaState, "unable to invoke method on generic class as the current method is an open generic method");
LuaLib.LuaPushNil (luaState);
return 1;
}
} else {
if (!methodToCall.IsStatic && !methodToCall.IsConstructor && targetObject == null) {
targetObject = _ExtractTarget (luaState, 1);
LuaLib.LuaRemove (luaState, 1); // Pops the receiver
}
if (!_Translator.MatchParameters (luaState, methodToCall, ref _LastCalledMethod)) {
_Translator.ThrowError (luaState, "invalid arguments to method call");
LuaLib.LuaPushNil (luaState);
return 1;
}
}
}
if (failedCall) {
if (!LuaLib.LuaCheckStack (luaState, _LastCalledMethod.outList.Length + 6))
throw new LuaException ("Lua stack overflow");
try {
if (isStatic)
_Translator.Push (luaState, _LastCalledMethod.cachedMethod.Invoke (null, _LastCalledMethod.args));
else {
if (_LastCalledMethod.cachedMethod.IsConstructor)
_Translator.Push (luaState, ((ConstructorInfo)_LastCalledMethod.cachedMethod).Invoke (_LastCalledMethod.args));
else
_Translator.Push (luaState, _LastCalledMethod.cachedMethod.Invoke (targetObject, _LastCalledMethod.args));
}
} catch (TargetInvocationException e) {
if (_Translator.interpreter.UseTraceback) e.GetBaseException().Data["Traceback"] = _Translator.interpreter.GetDebugTraceback();
return SetPendingException (e.GetBaseException ());
} catch (Exception e) {
return SetPendingException (e);
}
}
// Pushes out and ref return values
for (int index = 0; index < _LastCalledMethod.outList.Length; index++) {
nReturnValues++;
_Translator.Push (luaState, _LastCalledMethod.args [_LastCalledMethod.outList [index]]);
}
//by isSingle 2010-09-10 11:26:31
//Desc:
// if not return void,we need add 1,
// or we will lost the function's return value
// when call dotnet function like "int foo(arg1,out arg2,out arg3)" in lua code
if (!_LastCalledMethod.IsReturnVoid && nReturnValues > 0)
nReturnValues++;
return nReturnValues < 1 ? 1 : nReturnValues;
}
}
}
\ No newline at end of file
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