add lua dll

master
Christopher 2020-08-07 11:39:22 +02:00
parent 78a6904ab0
commit 6683f9f5eb
40 changed files with 83 additions and 6972 deletions

BIN
KeraLua.dll Normal file

Binary file not shown.

BIN
NLua.dll Normal file

Binary file not shown.

BIN
lua54.dll Normal file

Binary file not shown.

View File

@ -30,6 +30,10 @@
<Reference name="OpenSim.Services.Interfaces" path="../../../bin"/>
<Reference name="OpenSim.Server.Base" path="../../../bin"/>
<Reference name="OpenSim.Data" path="../../../bin"/>
<Reference name="KeraLua.dll" path="../" localCopy="true"/>
<Reference name="lua54.dll" path="../" localCopy="true"/>
<Reference name="NLua.dll" path="../" localCopy="true"/>
<Files>
<Match pattern="*.cs" recurse="true"/>
</Files>

View File

@ -1,406 +0,0 @@
using System;
using System.Collections.Generic;
using KeraLua;
using NLua.Method;
using NLua.Extensions;
namespace NLua
{
using LuaState = KeraLua.Lua;
sealed class CheckType
{
readonly Dictionary<Type, ExtractValue> _extractValues = new Dictionary<Type, ExtractValue>();
readonly ExtractValue _extractNetObject;
readonly ObjectTranslator _translator;
public CheckType(ObjectTranslator translator)
{
_translator = translator;
_extractValues.Add(typeof(object), GetAsObject);
_extractValues.Add(typeof(sbyte), GetAsSbyte);
_extractValues.Add(typeof(byte), GetAsByte);
_extractValues.Add(typeof(short), GetAsShort);
_extractValues.Add(typeof(ushort), GetAsUshort);
_extractValues.Add(typeof(int), GetAsInt);
_extractValues.Add(typeof(uint), GetAsUint);
_extractValues.Add(typeof(long), GetAsLong);
_extractValues.Add(typeof(ulong), GetAsUlong);
_extractValues.Add(typeof(double), GetAsDouble);
_extractValues.Add(typeof(char), GetAsChar);
_extractValues.Add(typeof(float), GetAsFloat);
_extractValues.Add(typeof(decimal), GetAsDecimal);
_extractValues.Add(typeof(bool), GetAsBoolean);
_extractValues.Add(typeof(string), GetAsString);
_extractValues.Add(typeof(char[]), GetAsCharArray);
_extractValues.Add(typeof(byte[]), GetAsByteArray);
_extractValues.Add(typeof(LuaFunction), GetAsFunction);
_extractValues.Add(typeof(LuaTable), GetAsTable);
_extractValues.Add(typeof(LuaUserData), GetAsUserdata);
_extractNetObject = GetAsNetObject;
}
/*
* Checks if the value at Lua stack index stackPos matches paramType,
* returning a conversion function if it does and null otherwise.
*/
internal ExtractValue GetExtractor(ProxyType paramType)
{
return GetExtractor(paramType.UnderlyingSystemType);
}
internal ExtractValue GetExtractor(Type paramType)
{
if (paramType.IsByRef)
paramType = paramType.GetElementType();
return _extractValues.ContainsKey(paramType) ? _extractValues[paramType] : _extractNetObject;
}
internal ExtractValue CheckLuaType(LuaState luaState, int stackPos, Type paramType)
{
LuaType luatype = luaState.Type(stackPos);
if (paramType.IsByRef)
paramType = paramType.GetElementType();
var underlyingType = Nullable.GetUnderlyingType(paramType);
if (underlyingType != null)
{
paramType = underlyingType; // Silently convert nullable types to their non null requics
}
bool netParamIsNumeric = paramType == typeof(int) ||
paramType == typeof(uint) ||
paramType == typeof(long) ||
paramType == typeof(ulong) ||
paramType == typeof(short) ||
paramType == typeof(ushort) ||
paramType == typeof(float) ||
paramType == typeof(double) ||
paramType == typeof(decimal) ||
paramType == typeof(byte);
// If it is a nullable
if (underlyingType != null)
{
// null can always be assigned to nullable
if (luatype == LuaType.Nil)
{
// Return the correct extractor anyways
if (netParamIsNumeric || paramType == typeof(bool))
return _extractValues[paramType];
return _extractNetObject;
}
}
if (paramType == typeof(object))
return _extractValues[paramType];
//CP: Added support for generic parameters
if (paramType.IsGenericParameter)
{
if (luatype == LuaType.Boolean)
return _extractValues[typeof(bool)];
if (luatype == LuaType.String)
return _extractValues[typeof(string)];
if (luatype == LuaType.Table)
return _extractValues[typeof(LuaTable)];
if (luatype == LuaType.UserData)
return _extractValues[typeof(object)];
if (luatype == LuaType.Function)
return _extractValues[typeof(LuaFunction)];
if (luatype == LuaType.Number)
return _extractValues[typeof(double)];
}
bool netParamIsString = paramType == typeof(string) || paramType == typeof(char[]) || paramType == typeof(byte[]);
if (netParamIsNumeric)
{
if (luaState.IsNumber(stackPos) && !netParamIsString)
return _extractValues[paramType];
}
else if (paramType == typeof(bool))
{
if (luaState.IsBoolean(stackPos))
return _extractValues[paramType];
}
else if (netParamIsString)
{
if (luaState.IsString(stackPos))
return _extractValues[paramType];
if (luatype == LuaType.Nil)
return _extractNetObject; // kevinh - silently convert nil to a null string pointer
}
else if (paramType == typeof(LuaTable))
{
if (luatype == LuaType.Table || luatype == LuaType.Nil)
return _extractValues[paramType];
}
else if (paramType == typeof(LuaUserData))
{
if (luatype == LuaType.UserData || luatype == LuaType.Nil)
return _extractValues[paramType];
}
else if (paramType == typeof(LuaFunction))
{
if (luatype == LuaType.Function || luatype == LuaType.Nil)
return _extractValues[paramType];
}
else if (typeof(Delegate).IsAssignableFrom(paramType) && luatype == LuaType.Function && paramType.GetMethod("Invoke") != null)
return new DelegateGenerator(_translator, paramType).ExtractGenerated;
else if (paramType.IsInterface && luatype == LuaType.Table)
return new ClassGenerator(_translator, paramType).ExtractGenerated;
else if ((paramType.IsInterface || paramType.IsClass) && luatype == LuaType.Nil)
{
// kevinh - allow nil to be silently converted to null - extractNetObject will return null when the item ain't found
return _extractNetObject;
}
else if (luaState.Type(stackPos) == LuaType.Table)
{
if (luaState.GetMetaField(stackPos, "__index") != LuaType.Nil)
{
object obj = _translator.GetNetObject(luaState, -1);
luaState.SetTop(-2);
if (obj != null && paramType.IsInstanceOfType(obj))
return _extractNetObject;
}
else
return null;
}
else
{
object obj = _translator.GetNetObject(luaState, stackPos);
if (obj != null && paramType.IsInstanceOfType(obj))
return _extractNetObject;
}
return null;
}
/*
* The following functions return the value in the Lua stack
* index stackPos as the desired type if it can, or null
* otherwise.
*/
private object GetAsSbyte(LuaState luaState, int stackPos)
{
if (!luaState.IsNumericType(stackPos))
return null;
if (luaState.IsInteger(stackPos))
return (sbyte)luaState.ToInteger(stackPos);
return (sbyte)luaState.ToNumber(stackPos);
}
private object GetAsByte(LuaState luaState, int stackPos)
{
if (!luaState.IsNumericType(stackPos))
return null;
if (luaState.IsInteger(stackPos))
return (byte)luaState.ToInteger(stackPos);
return (byte)luaState.ToNumber(stackPos);
}
private object GetAsShort(LuaState luaState, int stackPos)
{
if (!luaState.IsNumericType(stackPos))
return null;
if (luaState.IsInteger(stackPos))
return (short)luaState.ToInteger(stackPos);
return (short)luaState.ToNumber(stackPos);
}
private object GetAsUshort(LuaState luaState, int stackPos)
{
if (!luaState.IsNumericType(stackPos))
return null;
if (luaState.IsInteger(stackPos))
return (ushort)luaState.ToInteger(stackPos);
return (ushort)luaState.ToNumber(stackPos);
}
private object GetAsInt(LuaState luaState, int stackPos)
{
if (!luaState.IsNumericType(stackPos))
return null;
if (luaState.IsInteger(stackPos))
return (int)luaState.ToInteger(stackPos);
return (int)luaState.ToNumber(stackPos);
}
private object GetAsUint(LuaState luaState, int stackPos)
{
if (!luaState.IsNumericType(stackPos))
return null;
if (luaState.IsInteger(stackPos))
return (uint)luaState.ToInteger(stackPos);
return (uint)luaState.ToNumber(stackPos);
}
private object GetAsLong(LuaState luaState, int stackPos)
{
if (!luaState.IsNumericType(stackPos))
return null;
if (luaState.IsInteger(stackPos))
return luaState.ToInteger(stackPos);
return (long)luaState.ToNumber(stackPos);
}
private object GetAsUlong(LuaState luaState, int stackPos)
{
if (!luaState.IsNumericType(stackPos))
return null;
if (luaState.IsInteger(stackPos))
return (ulong)luaState.ToInteger(stackPos);
return (ulong)luaState.ToNumber(stackPos);
}
private object GetAsDouble(LuaState luaState, int stackPos)
{
if (!luaState.IsNumericType(stackPos))
return null;
if (luaState.IsInteger(stackPos))
return (double)luaState.ToInteger(stackPos);
return luaState.ToNumber(stackPos);
}
private object GetAsChar(LuaState luaState, int stackPos)
{
if (!luaState.IsNumericType(stackPos))
return null;
if (luaState.IsInteger(stackPos))
return (char)luaState.ToInteger(stackPos);
return (char)luaState.ToNumber(stackPos);
}
private object GetAsFloat(LuaState luaState, int stackPos)
{
if (!luaState.IsNumericType(stackPos))
return null;
if (luaState.IsInteger(stackPos))
return (float)luaState.ToInteger(stackPos);
return (float)luaState.ToNumber(stackPos);
}
private object GetAsDecimal(LuaState luaState, int stackPos)
{
if (!luaState.IsNumericType(stackPos))
return null;
if (luaState.IsInteger(stackPos))
return (decimal)luaState.ToInteger(stackPos);
return (decimal)luaState.ToNumber(stackPos);
}
private object GetAsBoolean(LuaState luaState, int stackPos)
{
return luaState.ToBoolean(stackPos);
}
private object GetAsCharArray(LuaState luaState, int stackPos)
{
if (!luaState.IsString(stackPos))
return null;
string retVal = luaState.ToString(stackPos, false);
return retVal.ToCharArray();
}
private object GetAsByteArray(LuaState luaState, int stackPos)
{
if (!luaState.IsString(stackPos))
return null;
byte [] retVal = luaState.ToBuffer(stackPos, false);
return retVal;
}
private object GetAsString(LuaState luaState, int stackPos)
{
if (!luaState.IsString(stackPos))
return null;
return luaState.ToString(stackPos, false);
}
private object GetAsTable(LuaState luaState, int stackPos)
{
return _translator.GetTable(luaState, stackPos);
}
private object GetAsFunction(LuaState luaState, int stackPos)
{
return _translator.GetFunction(luaState, stackPos);
}
private object GetAsUserdata(LuaState luaState, int stackPos)
{
return _translator.GetUserData(luaState, stackPos);
}
public object GetAsObject(LuaState luaState, int stackPos)
{
if (luaState.Type(stackPos) == LuaType.Table)
{
if (luaState.GetMetaField(stackPos, "__index") != LuaType.Nil)
{
if (luaState.CheckMetaTable(-1, _translator.Tag))
{
luaState.Insert(stackPos);
luaState.Remove(stackPos + 1);
}
else
luaState.SetTop(-2);
}
}
object obj = _translator.GetObject(luaState, stackPos);
return obj;
}
public object GetAsNetObject(LuaState luaState, int stackPos)
{
object obj = _translator.GetNetObject(luaState, stackPos);
if (obj != null || luaState.Type(stackPos) != LuaType.Table)
return obj;
if (luaState.GetMetaField(stackPos, "__index") == LuaType.Nil)
return null;
if (luaState.CheckMetaTable(-1, _translator.Tag))
{
luaState.Insert(stackPos);
luaState.Remove(stackPos + 1);
obj = _translator.GetNetObject(luaState, stackPos);
}
else
luaState.SetTop(-2);
return obj;
}
}
}

View File

@ -1,21 +0,0 @@
using System;
using KeraLua;
namespace NLua.Event
{
/// <summary>
/// Event args for hook callback event
/// </summary>
public class DebugHookEventArgs : EventArgs
{
public DebugHookEventArgs(LuaDebug luaDebug)
{
LuaDebug = luaDebug;
}
/// <summary>
/// Lua Debug Information
/// </summary>
public LuaDebug LuaDebug { get; }
}
}

View File

@ -1,14 +0,0 @@
using System;
namespace NLua.Event
{
public class HookExceptionEventArgs : EventArgs
{
public Exception Exception { get; }
public HookExceptionEventArgs(Exception ex)
{
Exception = ex;
}
}
}

View File

@ -1,20 +0,0 @@
using System;
namespace NLua.Exceptions
{
/// <summary>
/// Exceptions thrown by the Lua runtime
/// </summary>
[Serializable]
public class LuaException : Exception
{
public LuaException (string message) : base(message)
{
}
public LuaException (string message, Exception innerException) : base(message, innerException)
{
}
}
}

View File

@ -1,52 +0,0 @@
using System;
namespace NLua.Exceptions
{
/// <summary>
/// Exceptions thrown by the Lua runtime because of errors in the script
/// </summary>
///
[Serializable]
public class LuaScriptException : LuaException
{
/// <summary>
/// Returns true if the exception has occured as the result of a .NET exception in user code
/// </summary>
public bool IsNetException { get; }
private readonly string _source;
/// <summary>
/// The position in the script where the exception was triggered.
/// </summary>
public override string Source => _source;
/// <summary>
/// Creates a new Lua-only exception.
/// </summary>
/// <param name="message">The message that describes the error.</param>
/// <param name="source">The position in the script where the exception was triggered.</param>
public LuaScriptException(string message, string source) : base(message)
{
_source = source;
}
/// <summary>
/// Creates a new .NET wrapping exception.
/// </summary>
/// <param name="innerException">The .NET exception triggered by user-code.</param>
/// <param name="source">The position in the script where the exception was triggered.</param>
public LuaScriptException(Exception innerException, string source)
: base("A .NET exception occured in user-code", innerException)
{
_source = source;
IsNetException = true;
}
public override string ToString()
{
// Prepend the error source
return GetType().FullName + ": " + _source + Message;
}
}
}

View File

@ -1,122 +0,0 @@

using System;
using System.Runtime.InteropServices;
using KeraLua;
using LuaState=KeraLua.Lua;
namespace NLua.Extensions
{
static class LuaExtensions
{
public static bool CheckMetaTable(this LuaState state, int index, IntPtr tag)
{
if (!state.GetMetaTable(index))
return false;
state.PushLightUserData(tag);
state.RawGet(-2);
bool isNotNil = !state.IsNil(-1);
state.SetTop(-3);
return isNotNil;
}
public static void PopGlobalTable(this LuaState luaState)
{
luaState.RawSetInteger(LuaRegistry.Index, (long) LuaRegistryIndex.Globals);
}
public static void GetRef (this LuaState luaState, int reference)
{
luaState.RawGetInteger(LuaRegistry.Index, reference);
}
// ReSharper disable once IdentifierTypo
public static void Unref (this LuaState luaState, int reference)
{
luaState.Unref(LuaRegistry.Index, reference);
}
public static bool AreEqual(this LuaState luaState, int ref1, int ref2)
{
return luaState.Compare(ref1, ref2, LuaCompare.Equal);
}
public static IntPtr CheckUData(this LuaState state, int ud, string name)
{
IntPtr p = state.ToUserData(ud);
if (p == IntPtr.Zero)
return IntPtr.Zero;
if (!state.GetMetaTable(ud))
return IntPtr.Zero;
state.GetField(LuaRegistry.Index, name);
bool isEqual = state.RawEqual(-1, -2);
state.Pop(2);
if (isEqual)
return p;
return IntPtr.Zero;
}
public static int ToNetObject(this LuaState state, int index, IntPtr tag)
{
if (state.Type(index) != LuaType.UserData)
return -1;
IntPtr userData;
if (state.CheckMetaTable(index, tag))
{
userData = state.ToUserData(index);
if (userData != IntPtr.Zero)
return Marshal.ReadInt32(userData);
}
userData = state.CheckUData(index, "luaNet_class");
if (userData != IntPtr.Zero)
return Marshal.ReadInt32(userData);
userData = state.CheckUData(index, "luaNet_searchbase");
if (userData != IntPtr.Zero)
return Marshal.ReadInt32(userData);
userData = state.CheckUData(index, "luaNet_function");
if (userData != IntPtr.Zero)
return Marshal.ReadInt32(userData);
return -1;
}
public static void NewUData(this LuaState state, int val)
{
IntPtr pointer = state.NewUserData(Marshal.SizeOf(typeof(int)));
Marshal.WriteInt32(pointer, val);
}
public static int RawNetObj(this LuaState state, int index)
{
IntPtr pointer = state.ToUserData(index);
if (pointer == IntPtr.Zero)
return -1;
return Marshal.ReadInt32(pointer);
}
public static int CheckUObject(this LuaState state, int index, string name)
{
IntPtr udata = state.CheckUData(index, name);
if (udata == IntPtr.Zero)
return -1;
return Marshal.ReadInt32(udata);
}
public static bool IsNumericType(this LuaState state, int index)
{
return state.Type(index) == LuaType.Number;
}
}
}

View File

@ -1,31 +0,0 @@
using System.Collections.Generic;
namespace NLua.Extensions
{
static class StringExtensions
{
public static IEnumerable<string> SplitWithEscape(this string input, char separator, char escapeCharacter)
{
int start = 0;
int index = 0;
while (index < input.Length)
{
index = input.IndexOf(separator, index);
if (index == -1)
break;
if (input[index - 1] == escapeCharacter)
{
input = input.Remove(index - 1, 1);
continue;
}
yield return input.Substring(start, index - start);
index++;
start = index;
}
yield return input.Substring(start);
}
}
}

View File

@ -1,137 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace NLua.Extensions
{
static class TypeExtensions
{
public static bool HasMethod(this Type t, string name)
{
var op = t.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
return op.Any(m => m.Name == name);
}
public static bool HasAdditionOperator(this Type t)
{
if (t.IsPrimitive)
return true;
return t.HasMethod("op_Addition");
}
public static bool HasSubtractionOperator(this Type t)
{
if (t.IsPrimitive)
return true;
return t.HasMethod("op_Subtraction");
}
public static bool HasMultiplyOperator(this Type t)
{
if (t.IsPrimitive)
return true;
return t.HasMethod("op_Multiply");
}
public static bool HasDivisionOperator(this Type t)
{
if (t.IsPrimitive)
return true;
return t.HasMethod("op_Division");
}
public static bool HasModulusOperator(this Type t)
{
if (t.IsPrimitive)
return true;
return t.HasMethod("op_Modulus");
}
public static bool HasUnaryNegationOperator(this Type t)
{
if (t.IsPrimitive)
return true;
// Unary - will always have only one version.
var op = t.GetMethod("op_UnaryNegation", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
return op != null;
}
public static bool HasEqualityOperator(this Type t)
{
if (t.IsPrimitive)
return true;
return t.HasMethod("op_Equality");
}
public static bool HasLessThanOperator(this Type t)
{
if (t.IsPrimitive)
return true;
return t.HasMethod("op_LessThan");
}
public static bool HasLessThanOrEqualOperator(this Type t)
{
if (t.IsPrimitive)
return true;
return t.HasMethod("op_LessThanOrEqual");
}
public static MethodInfo[] GetMethods(this Type t, string name, BindingFlags flags)
{
return t.GetMethods(flags).Where(m => m.Name == name).ToArray();
}
public static MethodInfo[] GetExtensionMethods(this Type type, string name, IEnumerable<Assembly> assemblies = null)
{
var types = new List<Type>();
types.AddRange(type.Assembly.GetTypes().Where(t => t.IsPublic));
if (assemblies != null)
{
foreach (Assembly item in assemblies)
{
if (item == type.Assembly)
continue;
types.AddRange(item.GetTypes().Where(t => t.IsPublic && t.IsClass && t.IsSealed && t.IsAbstract && !t.IsNested));
}
}
var query = types
.SelectMany(extensionType => extensionType.GetMethods(name, BindingFlags.Static | BindingFlags.Public),
(extensionType, method) => new {extensionType, method})
.Where(t => t.method.IsDefined(typeof(ExtensionAttribute), false))
.Where(t =>
t.method.GetParameters()[0].ParameterType == type ||
t.method.GetParameters()[0].ParameterType.IsAssignableFrom(type) ||
type.GetInterfaces().Contains(t.method.GetParameters()[0].ParameterType))
.Select(t => t.method);
return query.ToArray();
}
/// <summary>
/// Extends the System.Type-type to search for a given extended MethodeName.
/// </summary>
/// <param name="t"></param>
/// <param name="name"></param>
/// <param name="assemblies"></param>
/// <returns></returns>
public static MethodInfo GetExtensionMethod(this Type t, string name, IEnumerable<Assembly> assemblies = null)
{
var mi = t.GetExtensionMethods(name, assemblies).ToArray();
if (mi.Length == 0)
return null;
return mi[0];
}
}
}

View File

@ -1,22 +0,0 @@
using System;
using LuaState = KeraLua.Lua;
namespace NLua
{
class ClassGenerator
{
private readonly ObjectTranslator _translator;
private readonly Type _klass;
public ClassGenerator(ObjectTranslator objTranslator, Type typeClass)
{
_translator = objTranslator;
_klass = typeClass;
}
public object ExtractGenerated(LuaState luaState, int stackPos)
{
return CodeGeneration.Instance.GetClassInstance(_klass, _translator.GetTable(luaState, stackPos));
}
}
}

View File

@ -1,752 +0,0 @@
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;
using NLua.Method;
namespace NLua
{
class CodeGeneration
{
private readonly Dictionary<Type, LuaClassType> _classCollection = new Dictionary<Type, LuaClassType>();
private readonly Dictionary<Type, Type> _delegateCollection = new Dictionary<Type, Type>();
#if !NETSTANDARD && !WINDOWS_UWP
private Dictionary<Type, Type> eventHandlerCollection = new Dictionary<Type, Type>();
private Type eventHandlerParent = typeof(LuaEventHandler);
private Type delegateParent = typeof(LuaDelegate);
private Type classHelper = typeof(LuaClassHelper);
private AssemblyBuilder newAssembly;
private ModuleBuilder newModule;
private int luaClassNumber = 1;
#endif
static CodeGeneration()
{
}
private CodeGeneration()
{
// Create an assembly name
var assemblyName = new AssemblyName();
assemblyName.Name = "NLua_generatedcode";
// Create a new assembly with one module.
#if NETCOREAPP
newAssembly = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
newModule = newAssembly.DefineDynamicModule("NLua_generatedcode");
#elif !NETSTANDARD && !WINDOWS_UWP
newAssembly = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
newModule = newAssembly.DefineDynamicModule("NLua_generatedcode");
#endif
}
/*
* Singleton instance of the class
*/
public static CodeGeneration Instance { get; } = new CodeGeneration();
/*
* Generates an event handler that calls a Lua function
*/
private Type GenerateEvent(Type eventHandlerType)
{
#if NETSTANDARD || WINDOWS_UWP
throw new NotImplementedException(" Emit not available on .NET Standard ");
#else
string typeName;
lock (this)
{
typeName = "LuaGeneratedClass" + luaClassNumber;
luaClassNumber++;
}
// Define a public class in the assembly, called typeName
var myType = newModule.DefineType(typeName, TypeAttributes.Public, eventHandlerParent);
// Defines the handler method. Its signature is void(object, <subclassofEventArgs>)
var paramTypes = new Type[2];
paramTypes[0] = typeof(object);
paramTypes[1] = eventHandlerType;
var returnType = typeof(void);
var handleMethod = myType.DefineMethod("HandleEvent", MethodAttributes.Public | MethodAttributes.HideBySig, returnType, paramTypes);
// Emits the IL for the method. It loads the arguments
// and calls the handleEvent method of the base class
ILGenerator generator = handleMethod.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Ldarg_2);
var miGenericEventHandler = eventHandlerParent.GetMethod("HandleEvent");
generator.Emit(OpCodes.Call, miGenericEventHandler);
// returns
generator.Emit(OpCodes.Ret);
// creates the new type
return myType.CreateType();
#endif
}
/*
* Generates a type that can be used for instantiating a delegate
* of the provided type, given a Lua function.
*/
private Type GenerateDelegate(Type delegateType)
{
#if NETSTANDARD || WINDOWS_UWP
throw new NotImplementedException("GenerateDelegate is not available on Windows Store, please register your LuaDelegate type with Lua.RegisterLuaDelegateType( yourDelegate, theLuaDelegateHandler) ");
#else
string typeName;
lock (this)
{
typeName = "LuaGeneratedClass" + luaClassNumber;
luaClassNumber++;
}
// Define a public class in the assembly, called typeName
var myType = newModule.DefineType(typeName, TypeAttributes.Public, delegateParent);
// Defines the delegate method with the same signature as the
// Invoke method of delegateType
var invokeMethod = delegateType.GetMethod("Invoke");
var paramInfo = invokeMethod.GetParameters();
var paramTypes = new Type[paramInfo.Length];
var returnType = invokeMethod.ReturnType;
// Counts out and ref params, for use later
int nOutParams = 0;
int nOutAndRefParams = 0;
for (int i = 0; i < paramTypes.Length; i++)
{
paramTypes[i] = paramInfo[i].ParameterType;
if ((!paramInfo[i].IsIn) && paramInfo[i].IsOut)
nOutParams++;
if (paramTypes[i].IsByRef)
nOutAndRefParams++;
}
int[] refArgs = new int[nOutAndRefParams];
var delegateMethod = myType.DefineMethod("CallFunction", invokeMethod.Attributes, returnType, paramTypes);
// Generates the IL for the method
ILGenerator generator = delegateMethod.GetILGenerator();
generator.DeclareLocal(typeof(object[])); // original arguments
generator.DeclareLocal(typeof(object[])); // with out-only arguments removed
generator.DeclareLocal(typeof(int[])); // indexes of out and ref arguments
if (!(returnType == typeof(void))) // return value
generator.DeclareLocal(returnType);
else
generator.DeclareLocal(typeof(object));
// Initializes local variables
generator.Emit(OpCodes.Ldc_I4, paramTypes.Length);
generator.Emit(OpCodes.Newarr, typeof(object));
generator.Emit(OpCodes.Stloc_0);
generator.Emit(OpCodes.Ldc_I4, paramTypes.Length - nOutParams);
generator.Emit(OpCodes.Newarr, typeof(object));
generator.Emit(OpCodes.Stloc_1);
generator.Emit(OpCodes.Ldc_I4, nOutAndRefParams);
generator.Emit(OpCodes.Newarr, typeof(int));
generator.Emit(OpCodes.Stloc_2);
// Stores the arguments in the local variables
for (int iArgs = 0, iInArgs = 0, iOutArgs = 0; iArgs < paramTypes.Length; iArgs++)
{
generator.Emit(OpCodes.Ldloc_0);
generator.Emit(OpCodes.Ldc_I4, iArgs);
generator.Emit(OpCodes.Ldarg, iArgs + 1);
if (paramTypes[iArgs].IsByRef)
{
if (paramTypes[iArgs].GetElementType().IsValueType)
{
generator.Emit(OpCodes.Ldobj, paramTypes[iArgs].GetElementType());
generator.Emit(OpCodes.Box, paramTypes[iArgs].GetElementType());
}
else
generator.Emit(OpCodes.Ldind_Ref);
}
else
{
if (paramTypes[iArgs].IsValueType)
generator.Emit(OpCodes.Box, paramTypes[iArgs]);
}
generator.Emit(OpCodes.Stelem_Ref);
if (paramTypes[iArgs].IsByRef)
{
generator.Emit(OpCodes.Ldloc_2);
generator.Emit(OpCodes.Ldc_I4, iOutArgs);
generator.Emit(OpCodes.Ldc_I4, iArgs);
generator.Emit(OpCodes.Stelem_I4);
refArgs[iOutArgs] = iArgs;
iOutArgs++;
}
if (paramInfo[iArgs].IsIn || (!paramInfo[iArgs].IsOut))
{
generator.Emit(OpCodes.Ldloc_1);
generator.Emit(OpCodes.Ldc_I4, iInArgs);
generator.Emit(OpCodes.Ldarg, iArgs + 1);
if (paramTypes[iArgs].IsByRef)
{
if (paramTypes[iArgs].GetElementType().IsValueType)
{
generator.Emit(OpCodes.Ldobj, paramTypes[iArgs].GetElementType());
generator.Emit(OpCodes.Box, paramTypes[iArgs].GetElementType());
}
else
generator.Emit(OpCodes.Ldind_Ref);
}
else
{
if (paramTypes[iArgs].IsValueType)
generator.Emit(OpCodes.Box, paramTypes[iArgs]);
}
generator.Emit(OpCodes.Stelem_Ref);
iInArgs++;
}
}
// Calls the callFunction method of the base class
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldloc_0);
generator.Emit(OpCodes.Ldloc_1);
generator.Emit(OpCodes.Ldloc_2);
var miGenericEventHandler = delegateParent.GetMethod("CallFunction");
generator.Emit(OpCodes.Call, miGenericEventHandler);
// Stores return value
if (returnType == typeof(void))
{
generator.Emit(OpCodes.Pop);
generator.Emit(OpCodes.Ldnull);
}
else if (returnType.IsValueType)
{
generator.Emit(OpCodes.Unbox, returnType);
generator.Emit(OpCodes.Ldobj, returnType);
}
else
generator.Emit(OpCodes.Castclass, returnType);
generator.Emit(OpCodes.Stloc_3);
// Stores new value of out and ref params
for (int i = 0; i < refArgs.Length; i++)
{
generator.Emit(OpCodes.Ldarg, refArgs[i] + 1);
generator.Emit(OpCodes.Ldloc_0);
generator.Emit(OpCodes.Ldc_I4, refArgs[i]);
generator.Emit(OpCodes.Ldelem_Ref);
if (paramTypes[refArgs[i]].GetElementType().IsValueType)
{
generator.Emit(OpCodes.Unbox, paramTypes[refArgs[i]].GetElementType());
generator.Emit(OpCodes.Ldobj, paramTypes[refArgs[i]].GetElementType());
generator.Emit(OpCodes.Stobj, paramTypes[refArgs[i]].GetElementType());
}
else
{
generator.Emit(OpCodes.Castclass, paramTypes[refArgs[i]].GetElementType());
generator.Emit(OpCodes.Stind_Ref);
}
}
// Returns
if (!(returnType == typeof(void)))
generator.Emit(OpCodes.Ldloc_3);
generator.Emit(OpCodes.Ret);
return myType.CreateType(); // creates the new type
#endif
}
void GetReturnTypesFromClass(Type klass, out Type[][] returnTypes)
{
var classMethods = klass.GetMethods();
returnTypes = new Type[classMethods.Length][];
int i = 0;
foreach (var method in classMethods)
{
if (klass.IsInterface)
{
GetReturnTypesFromMethod(method, out returnTypes[i]);
i++;
}
else if (!method.IsPrivate && !method.IsFinal && method.IsVirtual)
{
GetReturnTypesFromMethod(method, out returnTypes[i]);
i++;
}
}
}
/*
* Generates an implementation of klass, if it is an interface, or
* a subclass of klass that delegates its virtual methods to a Lua table.
*/
public void GenerateClass(Type klass, out Type newType, out Type[][] returnTypes)
{
#if NETSTANDARD || WINDOWS_UWP
throw new NotImplementedException (" Emit not available on .NET Standard ");
#else
string typeName;
lock (this)
{
typeName = "LuaGeneratedClass" + luaClassNumber;
luaClassNumber++;
}
TypeBuilder myType;
// Define a public class in the assembly, called typeName
if (klass.IsInterface)
myType = newModule.DefineType(typeName, TypeAttributes.Public, typeof(object), new Type[] {
klass,
typeof(ILuaGeneratedType)
});
else
myType = newModule.DefineType(typeName, TypeAttributes.Public, klass, new Type[] { typeof(ILuaGeneratedType) });
// Field that stores the Lua table
var luaTableField = myType.DefineField("__luaInterface_luaTable", typeof(LuaTable), FieldAttributes.Public);
// Field that stores the return types array
var returnTypesField = myType.DefineField("__luaInterface_returnTypes", typeof(Type[][]), FieldAttributes.Public);
// Generates the constructor for the new type, it takes a Lua table and an array
// of return types and stores them in the respective fields
var constructor = myType.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] {
typeof(LuaTable),
typeof(Type[][])
});
ILGenerator generator = constructor.GetILGenerator();
generator.Emit(OpCodes.Ldarg_0);
if (klass.IsInterface)
generator.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
else
generator.Emit(OpCodes.Call, klass.GetConstructor(Type.EmptyTypes));
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_1);
generator.Emit(OpCodes.Stfld, luaTableField);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldarg_2);
generator.Emit(OpCodes.Stfld, returnTypesField);
generator.Emit(OpCodes.Ret);
// Generates overriden versions of the klass' public virtual methods
var classMethods = klass.GetMethods();
returnTypes = new Type[classMethods.Length][];
int i = 0;
foreach (var method in classMethods)
{
if (klass.IsInterface)
{
GenerateMethod(myType, method, MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.NewSlot,
i, luaTableField, returnTypesField, false, out returnTypes[i]);
i++;
}
else
{
if (!method.IsPrivate && !method.IsFinal && method.IsVirtual)
{
GenerateMethod(myType, method, (method.Attributes | MethodAttributes.NewSlot) ^ MethodAttributes.NewSlot, i,
luaTableField, returnTypesField, true, out returnTypes[i]);
i++;
}
}
}
// Generates an implementation of the luaInterfaceGetLuaTable method
var returnTableMethod = myType.DefineMethod("LuaInterfaceGetLuaTable",
MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual, typeof(LuaTable), new Type[0]);
myType.DefineMethodOverride(returnTableMethod, typeof(ILuaGeneratedType).GetMethod("LuaInterfaceGetLuaTable"));
generator = returnTableMethod.GetILGenerator();
generator.Emit(OpCodes.Ldfld, luaTableField);
generator.Emit(OpCodes.Ret);
newType = myType.CreateType(); // Creates the type
#endif
}
void GetReturnTypesFromMethod(MethodInfo method, out Type[] returnTypes)
{
var paramInfo = method.GetParameters();
var paramTypes = new Type[paramInfo.Length];
var returnTypesList = new List<Type>();
// Counts out and ref parameters, for later use,
// and creates the list of return types
int nOutParams = 0;
int nOutAndRefParams = 0;
var returnType = method.ReturnType;
returnTypesList.Add(returnType);
for (int i = 0; i < paramTypes.Length; i++)
{
paramTypes[i] = paramInfo[i].ParameterType;
if (!paramInfo[i].IsIn && paramInfo[i].IsOut)
{
nOutParams++;
}
if (paramTypes[i].IsByRef)
{
returnTypesList.Add(paramTypes[i].GetElementType());
nOutAndRefParams++;
}
}
returnTypes = returnTypesList.ToArray();
}
#if !NETSTANDARD && !WINDOWS_UWP
/*
* Generates an overriden implementation of method inside myType that delegates
* to a function in a Lua table with the same name, if the function exists. If it
* doesn't the method calls the base method (or does nothing, in case of interface
* implementations).
*/
private void GenerateMethod(TypeBuilder myType, MethodInfo method, MethodAttributes attributes, int methodIndex,
FieldInfo luaTableField, FieldInfo returnTypesField, bool generateBase, out Type[] returnTypes)
{
var paramInfo = method.GetParameters();
var paramTypes = new Type[paramInfo.Length];
var returnTypesList = new List<Type>();
// Counts out and ref parameters, for later use,
// and creates the list of return types
int nOutParams = 0;
int nOutAndRefParams = 0;
var returnType = method.ReturnType;
returnTypesList.Add(returnType);
for (int i = 0; i < paramTypes.Length; i++)
{
paramTypes[i] = paramInfo[i].ParameterType;
if (!paramInfo[i].IsIn && paramInfo[i].IsOut)
nOutParams++;
if (paramTypes[i].IsByRef)
{
returnTypesList.Add(paramTypes[i].GetElementType());
nOutAndRefParams++;
}
}
int[] refArgs = new int[nOutAndRefParams];
returnTypes = returnTypesList.ToArray();
// Generates a version of the method that calls the base implementation
// directly, for use by the base field of the table
if (generateBase)
{
var baseMethod = myType.DefineMethod("__luaInterface_base_" + method.Name,
MethodAttributes.Private | MethodAttributes.NewSlot | MethodAttributes.HideBySig,
returnType, paramTypes);
ILGenerator generatorBase = baseMethod.GetILGenerator();
generatorBase.Emit(OpCodes.Ldarg_0);
for (int i = 0; i < paramTypes.Length; i++)
generatorBase.Emit(OpCodes.Ldarg, i + 1);
generatorBase.Emit(OpCodes.Call, method);
if (returnType == typeof(void))
generatorBase.Emit(OpCodes.Pop);
generatorBase.Emit(OpCodes.Ret);
}
// Defines the method
var methodImpl = myType.DefineMethod(method.Name, attributes, returnType, paramTypes);
// If it's an implementation of an interface tells what method it
// is overriding
if (myType.BaseType.Equals(typeof(object)))
myType.DefineMethodOverride(methodImpl, method);
ILGenerator generator = methodImpl.GetILGenerator();
generator.DeclareLocal(typeof(object[])); // original arguments
generator.DeclareLocal(typeof(object[])); // with out-only arguments removed
generator.DeclareLocal(typeof(int[])); // indexes of out and ref arguments
if (!(returnType == typeof(void))) // return value
generator.DeclareLocal(returnType);
else
generator.DeclareLocal(typeof(object));
// Initializes local variables
generator.Emit(OpCodes.Ldc_I4, paramTypes.Length);
generator.Emit(OpCodes.Newarr, typeof(object));
generator.Emit(OpCodes.Stloc_0);
generator.Emit(OpCodes.Ldc_I4, paramTypes.Length - nOutParams + 1);
generator.Emit(OpCodes.Newarr, typeof(object));
generator.Emit(OpCodes.Stloc_1);
generator.Emit(OpCodes.Ldc_I4, nOutAndRefParams);
generator.Emit(OpCodes.Newarr, typeof(int));
generator.Emit(OpCodes.Stloc_2);
generator.Emit(OpCodes.Ldloc_1);
generator.Emit(OpCodes.Ldc_I4_0);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldfld, luaTableField);
generator.Emit(OpCodes.Stelem_Ref);
// Stores the arguments into the local variables, as needed
for (int iArgs = 0, iInArgs = 1, iOutArgs = 0; iArgs < paramTypes.Length; iArgs++)
{
generator.Emit(OpCodes.Ldloc_0);
generator.Emit(OpCodes.Ldc_I4, iArgs);
generator.Emit(OpCodes.Ldarg, iArgs + 1);
if (paramTypes[iArgs].IsByRef)
{
if (paramTypes[iArgs].GetElementType().IsValueType)
{
generator.Emit(OpCodes.Ldobj, paramTypes[iArgs].GetElementType());
generator.Emit(OpCodes.Box, paramTypes[iArgs].GetElementType());
}
else
generator.Emit(OpCodes.Ldind_Ref);
}
else
{
if (paramTypes[iArgs].IsValueType)
generator.Emit(OpCodes.Box, paramTypes[iArgs]);
}
generator.Emit(OpCodes.Stelem_Ref);
if (paramTypes[iArgs].IsByRef)
{
generator.Emit(OpCodes.Ldloc_2);
generator.Emit(OpCodes.Ldc_I4, iOutArgs);
generator.Emit(OpCodes.Ldc_I4, iArgs);
generator.Emit(OpCodes.Stelem_I4);
refArgs[iOutArgs] = iArgs;
iOutArgs++;
}
if (paramInfo[iArgs].IsIn || (!paramInfo[iArgs].IsOut))
{
generator.Emit(OpCodes.Ldloc_1);
generator.Emit(OpCodes.Ldc_I4, iInArgs);
generator.Emit(OpCodes.Ldarg, iArgs + 1);
if (paramTypes[iArgs].IsByRef)
{
if (paramTypes[iArgs].GetElementType().IsValueType)
{
generator.Emit(OpCodes.Ldobj, paramTypes[iArgs].GetElementType());
generator.Emit(OpCodes.Box, paramTypes[iArgs].GetElementType());
}
else
generator.Emit(OpCodes.Ldind_Ref);
}
else
{
if (paramTypes[iArgs].IsValueType)
generator.Emit(OpCodes.Box, paramTypes[iArgs]);
}
generator.Emit(OpCodes.Stelem_Ref);
iInArgs++;
}
}
// Gets the function the method will delegate to by calling
// the getTableFunction method of class LuaClassHelper
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldfld, luaTableField);
generator.Emit(OpCodes.Ldstr, method.Name);
generator.Emit(OpCodes.Call, classHelper.GetMethod("GetTableFunction"));
var lab1 = generator.DefineLabel();
generator.Emit(OpCodes.Dup);
generator.Emit(OpCodes.Brtrue_S, lab1);
// Function does not exist, call base method
generator.Emit(OpCodes.Pop);
if (!method.IsAbstract)
{
generator.Emit(OpCodes.Ldarg_0);
for (int i = 0; i < paramTypes.Length; i++)
generator.Emit(OpCodes.Ldarg, i + 1);
generator.Emit(OpCodes.Call, method);
if (returnType == typeof(void))
generator.Emit(OpCodes.Pop);
generator.Emit(OpCodes.Ret);
generator.Emit(OpCodes.Ldnull);
}
else
generator.Emit(OpCodes.Ldnull);
var lab2 = generator.DefineLabel();
generator.Emit(OpCodes.Br_S, lab2);
generator.MarkLabel(lab1);
// Function exists, call using method callFunction of LuaClassHelper
generator.Emit(OpCodes.Ldloc_0);
generator.Emit(OpCodes.Ldarg_0);
generator.Emit(OpCodes.Ldfld, returnTypesField);
generator.Emit(OpCodes.Ldc_I4, methodIndex);
generator.Emit(OpCodes.Ldelem_Ref);
generator.Emit(OpCodes.Ldloc_1);
generator.Emit(OpCodes.Ldloc_2);
generator.Emit(OpCodes.Call, classHelper.GetMethod("CallFunction"));
generator.MarkLabel(lab2);
// Stores the function return value
if (returnType == typeof(void))
{
generator.Emit(OpCodes.Pop);
generator.Emit(OpCodes.Ldnull);
}
else if (returnType.IsValueType)
{
generator.Emit(OpCodes.Unbox, returnType);
generator.Emit(OpCodes.Ldobj, returnType);
}
else
generator.Emit(OpCodes.Castclass, returnType);
generator.Emit(OpCodes.Stloc_3);
// Sets return values of out and ref parameters
for (int i = 0; i < refArgs.Length; i++)
{
generator.Emit(OpCodes.Ldarg, refArgs[i] + 1);
generator.Emit(OpCodes.Ldloc_0);
generator.Emit(OpCodes.Ldc_I4, refArgs[i]);
generator.Emit(OpCodes.Ldelem_Ref);
if (paramTypes[refArgs[i]].GetElementType().IsValueType)
{
generator.Emit(OpCodes.Unbox, paramTypes[refArgs[i]].GetElementType());
generator.Emit(OpCodes.Ldobj, paramTypes[refArgs[i]].GetElementType());
generator.Emit(OpCodes.Stobj, paramTypes[refArgs[i]].GetElementType());
}
else
{
generator.Emit(OpCodes.Castclass, paramTypes[refArgs[i]].GetElementType());
generator.Emit(OpCodes.Stind_Ref);
}
}
// Returns
if (!(returnType == typeof(void)))
generator.Emit(OpCodes.Ldloc_3);
generator.Emit(OpCodes.Ret);
}
#endif
/*
* Gets an event handler for the event type that delegates to the eventHandler Lua function.
* Caches the generated type.
*/
public LuaEventHandler GetEvent(Type eventHandlerType, LuaFunction eventHandler)
{
#if NETSTANDARD || WINDOWS_UWP
throw new NotImplementedException (" Emit not available on .NET Standard ");
#else
Type eventConsumerType;
if (eventHandlerCollection.ContainsKey(eventHandlerType))
eventConsumerType = eventHandlerCollection[eventHandlerType];
else
{
eventConsumerType = GenerateEvent(eventHandlerType);
eventHandlerCollection[eventHandlerType] = eventConsumerType;
}
var luaEventHandler = (LuaEventHandler)Activator.CreateInstance(eventConsumerType);
luaEventHandler.Handler = eventHandler;
return luaEventHandler;
#endif
}
public void RegisterLuaDelegateType(Type delegateType, Type luaDelegateType)
{
_delegateCollection[delegateType] = luaDelegateType;
}
public void RegisterLuaClassType(Type klass, Type luaClass)
{
var luaClassType = new LuaClassType();
luaClassType.klass = luaClass;
GetReturnTypesFromClass(klass, out luaClassType.returnTypes);
_classCollection[klass] = luaClassType;
}
/*
* Gets a delegate with delegateType that calls the luaFunc Lua function
* Caches the generated type.
*/
public Delegate GetDelegate(Type delegateType, LuaFunction luaFunc)
{
var returnTypes = new List<Type>();
Type luaDelegateType;
if (_delegateCollection.ContainsKey(delegateType))
{
luaDelegateType = _delegateCollection[delegateType];
}
else
{
luaDelegateType = GenerateDelegate(delegateType);
_delegateCollection[delegateType] = luaDelegateType;
}
var methodInfo = delegateType.GetMethod("Invoke");
returnTypes.Add(methodInfo.ReturnType);
foreach (ParameterInfo paramInfo in methodInfo.GetParameters())
{
if (paramInfo.ParameterType.IsByRef)
returnTypes.Add(paramInfo.ParameterType);
}
var luaDelegate = (LuaDelegate)Activator.CreateInstance(luaDelegateType);
luaDelegate.Function = luaFunc;
luaDelegate.ReturnTypes = returnTypes.ToArray();
return Delegate.CreateDelegate(delegateType, luaDelegate, "CallFunction");
}
/*
* Gets an instance of an implementation of the klass interface or
* subclass of klass that delegates public virtual methods to the
* luaTable table.
* Caches the generated type.
*/
public object GetClassInstance(Type klass, LuaTable luaTable)
{
LuaClassType luaClassType;
if (_classCollection.ContainsKey(klass))
luaClassType = _classCollection[klass];
else
{
luaClassType = new LuaClassType();
GenerateClass(klass, out luaClassType.klass, out luaClassType.returnTypes);
_classCollection[klass] = luaClassType;
}
return Activator.CreateInstance(luaClassType.klass, new object[] {
luaTable,
luaClassType.returnTypes
});
}
}
}

View File

@ -1,22 +0,0 @@
using System;
using LuaState = KeraLua.Lua;
namespace NLua
{
class DelegateGenerator
{
private readonly ObjectTranslator _translator;
private readonly Type _delegateType;
public DelegateGenerator(ObjectTranslator objectTranslator, Type type)
{
_translator = objectTranslator;
_delegateType = type;
}
public object ExtractGenerated(LuaState luaState, int stackPos)
{
return CodeGeneration.Instance.GetDelegate(_delegateType, _translator.GetFunction(luaState, stackPos));
}
}
}

View File

@ -1,11 +0,0 @@
namespace NLua
{
/*
* Common interface for types generated from tables. The method
* returns the table that overrides some or all of the type's methods.
*/
public interface ILuaGeneratedType
{
LuaTable LuaInterfaceGetLuaTable();
}
}

View File

@ -1,15 +0,0 @@
using System;
namespace NLua
{
/*
* Structure to store a type and the return types of
* its methods (the type of the returned value and out/ref
* parameters).
*/
struct LuaClassType
{
public Type klass;
public Type[][] returnTypes;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,86 +0,0 @@
using System;
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;
protected readonly int _Reference;
Lua _lua;
protected bool TryGet(out Lua lua)
{
if (_lua.State == null)
{
lua = null;
return false;
}
lua = _lua;
return true;
}
protected LuaBase(int reference, Lua lua)
{
_lua = lua;
_Reference = reference;
}
~LuaBase()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
void DisposeLuaReference(bool finalized)
{
if (_lua == null)
return;
Lua lua;
if (!TryGet(out lua))
return;
lua.DisposeInternal(_Reference, finalized);
}
public virtual void Dispose(bool disposeManagedResources)
{
if (_disposed)
return;
bool finalized = !disposeManagedResources;
if (_Reference != 0)
{
DisposeLuaReference(finalized);
}
_lua = null;
_disposed = true;
}
public override bool Equals(object o)
{
var reference = o as LuaBase;
if (reference == null)
return false;
Lua lua;
if (!TryGet(out lua))
return false;
return lua.CompareRef(reference._Reference, _Reference);
}
public override int GetHashCode()
{
return _Reference;
}
}
}

View File

@ -1,91 +0,0 @@
using System;
using KeraLua;
using LuaState = KeraLua.Lua;
using LuaNativeFunction = KeraLua.LuaFunction;
namespace NLua
{
public class LuaFunction : LuaBase
{
internal readonly LuaNativeFunction function;
public LuaFunction(int reference, Lua interpreter):base(reference, interpreter)
{
function = null;
}
public LuaFunction(LuaNativeFunction nativeFunction, Lua interpreter):base (0, interpreter)
{
function = nativeFunction;
}
/*
* Calls the function casting return values to the types
* in returnTypes
*/
internal object[] Call(object[] args, Type[] returnTypes)
{
Lua lua;
if (!TryGet(out lua))
return null;
return lua.CallFunction(this, args, returnTypes);
}
/*
* Calls the function and returns its return values inside
* an array
*/
public object[] Call(params object[] args)
{
Lua lua;
if (!TryGet(out lua))
return null;
return lua.CallFunction(this, args);
}
/*
* Pushes the function into the Lua stack
*/
internal void Push(LuaState luaState)
{
Lua lua;
if (!TryGet(out lua))
return;
if (_Reference != 0)
luaState.RawGetInteger(LuaRegistry.Index, _Reference);
else
lua.PushCSFunction(function);
}
public override string ToString()
{
return "function";
}
public override bool Equals(object o)
{
var l = o as LuaFunction;
if (l == null)
return false;
Lua lua;
if (!TryGet(out lua))
return false;
if (_Reference != 0 && l._Reference != 0)
return lua.CompareRef(l._Reference, _Reference);
return function == l.function;
}
public override int GetHashCode()
{
return _Reference != 0 ? _Reference : function.GetHashCode();
}
}
}

View File

@ -1,23 +0,0 @@
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; }
}
}

View File

@ -1,12 +0,0 @@
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
{
}
}

View File

@ -1,98 +0,0 @@
using System;
using System.Reflection;
using System.Diagnostics.CodeAnalysis;
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(nameof(lua));
if (o == null)
throw new ArgumentNullException(nameof(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(nameof(lua));
if (type == null)
throw new ArgumentNullException(nameof(type));
if (!type.IsClass)
throw new ArgumentException("The type must be a class!", nameof(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
/// <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)
{
if (lua == null)
throw new ArgumentNullException(nameof(lua));
Type type = typeof(T);
if (!type.IsEnum)
throw new ArgumentException("The type must be an enumeration!");
string[] names = Enum.GetNames(type);
var values = (T[])Enum.GetValues(type);
lua.NewTable(type.Name);
for (int i = 0; i < names.Length; i++)
{
string path = type.Name + "." + names[i];
lua.SetObjectToPath(path, values[i]);
}
}
}
}

View File

@ -1,120 +0,0 @@

using System;
using System.Collections;
using NLua.Extensions;
using LuaState = KeraLua.Lua;
namespace NLua
{
public class LuaTable : LuaBase
{
public LuaTable(int reference, Lua interpreter): base(reference, interpreter)
{
}
/*
* Indexer for string fields of the table
*/
public object this[string field] {
get
{
Lua lua;
if (!TryGet(out lua))
return null;
return lua.GetObject(_Reference, field);
}
set
{
Lua lua;
if (!TryGet(out lua))
return;
lua.SetObject(_Reference, field, value);
}
}
/*
* Indexer for numeric fields of the table
*/
public object this[object field] {
get
{
Lua lua;
if (!TryGet(out lua))
return null;
return lua.GetObject(_Reference, field);
}
set
{
Lua lua;
if (!TryGet(out lua))
return;
lua.SetObject(_Reference, field, value);
}
}
public IDictionaryEnumerator GetEnumerator()
{
Lua lua;
if (!TryGet(out lua))
return null;
return lua.GetTableDict(this).GetEnumerator();
}
public ICollection Keys
{
get
{
Lua lua;
if (!TryGet(out lua))
return null;
return lua.GetTableDict(this).Keys;
}
}
public ICollection Values
{
get
{
Lua lua;
if (!TryGet(out lua))
return null;
return lua.GetTableDict(this).Values;
}
}
/*
* Gets an string fields of a table ignoring its metatable,
* if it exists
*/
internal object RawGet(string field)
{
Lua lua;
if (!TryGet(out lua))
return null;
return lua.RawGetObject(_Reference, field);
}
/*
* Pushes this table into the Lua stack
*/
internal void Push(LuaState luaState)
{
luaState.GetRef(_Reference);
}
public override string ToString()
{
return "table";
}
}
}

View File

@ -1,74 +0,0 @@

using System;
namespace NLua
{
public class LuaUserData : LuaBase
{
public LuaUserData(int reference, Lua interpreter):base(reference, interpreter)
{
}
/*
* Indexer for string fields of the userdata
*/
public object this[string field] {
get
{
Lua lua;
if (!TryGet(out lua))
return null;
return lua.GetObject(_Reference, field);
}
set
{
Lua lua;
if (!TryGet(out lua))
return;
lua.SetObject(_Reference, field, value);
}
}
/*
* Indexer for numeric fields of the userdata
*/
public object this[object field] {
get
{
Lua lua;
if (!TryGet(out lua))
return null;
return lua.GetObject(_Reference, field);
}
set
{
Lua lua;
if (!TryGet(out lua))
return;
lua.SetObject(_Reference, field, value);
}
}
/*
* Calls the userdata and returns its return values inside
* an array
*/
public object[] Call(params object[] args)
{
Lua lua;
if (!TryGet(out lua))
return null;
return lua.CallFunction(this, args);
}
public override string ToString()
{
return "userdata";
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,36 +0,0 @@
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 readonly 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();
}
}
}

View File

@ -1,55 +0,0 @@
using System;
namespace NLua.Method
{
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;
var funcObj = luaTable.RawGet(name) as LuaFunction;
if (funcObj != null)
return funcObj;
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;
}
}
}

View File

@ -1,47 +0,0 @@
using System;
namespace NLua.Method
{
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;
}
}
}

View File

@ -1,12 +0,0 @@
namespace NLua.Method
{
public class LuaEventHandler
{
public LuaFunction Handler = null;
public void HandleEvent(object[] args)
{
Handler.Call(args);
}
}
}

View File

@ -1,355 +0,0 @@
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using NLua.Exceptions;
using NLua.Extensions;
using LuaState = KeraLua.Lua;
using LuaNativeFunction = KeraLua.LuaFunction;
namespace NLua.Method
{
/*
* Argument extraction with type-conversion function
*/
delegate object ExtractValue(LuaState luaState, int stackPos);
/*
* Wrapper class for methods/constructors accessed from Lua.
*
*/
class LuaMethodWrapper
{
internal LuaNativeFunction InvokeFunction;
readonly ObjectTranslator _translator;
readonly MethodBase _method;
readonly ExtractValue _extractTarget;
readonly object _target;
readonly bool _isStatic;
readonly string _methodName;
readonly MethodInfo[] _members;
private MethodCache _lastCalledMethod;
/*
* Constructs the wrapper for a known MethodBase instance
*/
public LuaMethodWrapper(ObjectTranslator translator, object target, ProxyType targetType, MethodBase method)
{
InvokeFunction = Call;
_translator = translator;
_target = target;
_extractTarget = translator.typeChecker.GetExtractor(targetType);
_lastCalledMethod = new MethodCache();
_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 = Call;
_translator = translator;
_methodName = methodName;
_extractTarget = translator.typeChecker.GetExtractor(targetType);
_lastCalledMethod = new MethodCache();
_isStatic = (bindingType & BindingFlags.Static) == BindingFlags.Static;
MethodInfo [] methods = GetMethodsRecursively(targetType.UnderlyingSystemType,
methodName,
bindingType | BindingFlags.Public);
_members = ReorderMethods(methods);
}
private static MethodInfo[] ReorderMethods(MethodInfo[] m)
{
int len = m.Length;
if (len < 2)
return m;
return m.
GroupBy(c => c.GetParameters().Length).
SelectMany(g => g.OrderByDescending(ci => ci.ToString())).
ToArray();
}
MethodInfo[] GetMethodsRecursively(Type type, string methodName, BindingFlags bindingType)
{
if (type == typeof(object))
return type.GetMethods(methodName, bindingType);
var methods = type.GetMethods(methodName, bindingType);
var baseMethods = GetMethodsRecursively(type.BaseType, methodName, bindingType);
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);
}
void FillMethodArguments(LuaState luaState, int numStackToSkip)
{
object[] args = _lastCalledMethod.args;
for (int i = 0; i < _lastCalledMethod.argTypes.Length; i++)
{
MethodArgs type = _lastCalledMethod.argTypes[i];
int index = i + 1 + numStackToSkip;
if (_lastCalledMethod.argTypes[i].IsParamsArray)
{
int count = _lastCalledMethod.argTypes.Length - i;
Array paramArray = _translator.TableToArray(luaState, type.ExtractValue, type.ParameterType, index, count);
args[_lastCalledMethod.argTypes[i].Index] = paramArray;
}
else
{
args[type.Index] = type.ExtractValue(luaState, index);
}
if (_lastCalledMethod.args[_lastCalledMethod.argTypes[i].Index] == null &&
!luaState.IsNil(i + 1 + numStackToSkip))
throw new LuaException(string.Format("Argument number {0} is invalid", (i + 1)));
}
}
int PushReturnValue(LuaState luaState)
{
int nReturnValues = 0;
// Pushes out and ref return values
for (int index = 0; index < _lastCalledMethod.outList.Length; index++)
{
nReturnValues++;
_translator.Push(luaState, _lastCalledMethod.args[_lastCalledMethod.outList[index]]);
}
// 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;
}
int CallInvoke(LuaState luaState, MethodBase method, object targetObject)
{
if (!luaState.CheckStack(_lastCalledMethod.outList.Length + 6))
throw new LuaException("Lua stack overflow");
try
{
object result;
if (method.IsConstructor)
result = ((ConstructorInfo)method).Invoke(_lastCalledMethod.args);
else
result = method.Invoke(targetObject, _lastCalledMethod.args);
_translator.Push(luaState, result);
}
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)
{
return SetPendingException(e);
}
return PushReturnValue(luaState);
}
bool IsMethodCached(LuaState luaState, int numArgsPassed, int skipParams)
{
if (_lastCalledMethod.cachedMethod == null)
return false;
if (numArgsPassed != _lastCalledMethod.argTypes.Length)
return false;
// If there is no method overloads, is ok to use the cached method
if (_members.Length == 1)
return true;
return _translator.MatchParameters(luaState, _lastCalledMethod.cachedMethod, _lastCalledMethod, skipParams);
}
int CallMethodFromName(LuaState luaState)
{
object targetObject = null;
if (!_isStatic)
targetObject = _extractTarget(luaState, 1);
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 = luaState.GetTop() - numStackToSkip;
// Cached?
if (IsMethodCached(luaState, numArgsPassed, numStackToSkip))
{
MethodBase method = _lastCalledMethod.cachedMethod;
if (!luaState.CheckStack(_lastCalledMethod.outList.Length + 6))
throw new LuaException("Lua stack overflow");
FillMethodArguments(luaState, numStackToSkip);
return CallInvoke(luaState, method, targetObject);
}
// 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));
return 1;
}
luaState.Remove(1); // Pops the receiver
}
bool hasMatch = false;
string candidateName = null;
foreach (var member in _members)
{
if (member.ReflectedType == null)
continue;
candidateName = member.ReflectedType.Name + "." + member.Name;
bool isMethod = _translator.MatchParameters(luaState, member, _lastCalledMethod, 0);
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);
return 1;
}
if (_lastCalledMethod.cachedMethod.ContainsGenericParameters)
return CallInvokeOnGenericMethod(luaState, (MethodInfo)_lastCalledMethod.cachedMethod, targetObject);
return CallInvoke(luaState, _lastCalledMethod.cachedMethod, targetObject);
}
int CallInvokeOnGenericMethod(LuaState luaState, MethodInfo methodToCall, object targetObject)
{
//need to make a concrete type of the generic method definition
var typeArgs = new List<Type>();
ParameterInfo [] parameters = methodToCall.GetParameters();
for (int i = 0; i < parameters.Length; i++)
{
ParameterInfo parameter = parameters[i];
if (!parameter.ParameterType.IsGenericParameter)
continue;
typeArgs.Add(_lastCalledMethod.args[i].GetType());
}
MethodInfo concreteMethod = methodToCall.MakeGenericMethod(typeArgs.ToArray());
_translator.Push(luaState, concreteMethod.Invoke(targetObject, _lastCalledMethod.args));
return PushReturnValue(luaState);
}
/*
* Calls the method. Receives the arguments from the Lua stack
* and returns values in it.
*/
int Call(IntPtr state)
{
var luaState = LuaState.FromIntPtr(state);
MethodBase methodToCall = _method;
object targetObject = _target;
if (!luaState.CheckStack(5))
throw new LuaException("Lua stack overflow");
SetPendingException(null);
// Method from name
if (methodToCall == null)
return CallMethodFromName(luaState);
// Method from MethodBase instance
if (!methodToCall.ContainsGenericParameters)
{
if (!methodToCall.IsStatic && !methodToCall.IsConstructor && targetObject == null)
{
targetObject = _extractTarget(luaState, 1);
luaState.Remove(1); // Pops the receiver
}
if (!_translator.MatchParameters(luaState, methodToCall, _lastCalledMethod, 0))
{
_translator.ThrowError(luaState, "Invalid arguments to method call");
return 1;
}
}
else
{
if (!methodToCall.IsGenericMethodDefinition)
{
_translator.ThrowError(luaState,
"Unable to invoke method on generic class as the current method is an open generic method");
return 1;
}
_translator.MatchParameters(luaState, methodToCall, _lastCalledMethod, 0);
return CallInvokeOnGenericMethod(luaState, (MethodInfo) methodToCall, targetObject);
}
if (_isStatic)
targetObject = null;
return CallInvoke(luaState, _lastCalledMethod.cachedMethod, targetObject);
}
}
}

View File

@ -1,18 +0,0 @@
using System;
namespace NLua.Method
{
/*
* Parameter information
*/
class MethodArgs
{
// Position of parameter
public int Index;
public Type ParameterType;
// Type-conversion function
public ExtractValue ExtractValue;
public bool IsParamsArray;
}
}

View File

@ -1,42 +0,0 @@
using System;
using System.Reflection;
using NLua.Extensions;
namespace NLua.Method
{
class MethodCache
{
public MethodCache()
{
args = new object[0];
argTypes = new MethodArgs[0];
outList = new int[0];
}
private MethodBase _cachedMethod;
public MethodBase cachedMethod {
get
{
return _cachedMethod;
}
set
{
_cachedMethod = value;
var mi = value as MethodInfo;
if (mi != null)
{
IsReturnVoid = mi.ReturnType == typeof(void);
}
}
}
public bool IsReturnVoid;
// List or arguments
public object[] args;
// Positions of out parameters
public int[] outList;
// Types of parameters
public MethodArgs[] argTypes;
}
}

View File

@ -1,53 +0,0 @@
using System;
using System.Reflection;
namespace NLua.Method
{
class RegisterEventHandler
{
private readonly EventHandlerContainer _pendingEvents;
private readonly EventInfo _eventInfo;
private readonly object _target;
public RegisterEventHandler(EventHandlerContainer pendingEvents, object target, EventInfo eventInfo)
{
_target = target;
_eventInfo = eventInfo;
_pendingEvents = pendingEvents;
}
/*
* Adds a new event handler
*/
public Delegate Add(LuaFunction function)
{
Delegate handlerDelegate = CodeGeneration.Instance.GetDelegate(_eventInfo.EventHandlerType, function);
return Add(handlerDelegate);
}
public Delegate Add(Delegate handlerDelegate)
{
_eventInfo.AddEventHandler(_target, handlerDelegate);
_pendingEvents.Add(handlerDelegate, this);
return handlerDelegate;
}
/*
* Removes an existing event handler
*/
public void Remove(Delegate handlerDelegate)
{
RemovePending(handlerDelegate);
_pendingEvents.Remove(handlerDelegate);
}
/*
* Removes an existing event handler (without updating the pending handlers list)
*/
internal void RemovePending(Delegate handlerDelegate)
{
_eventInfo.RemoveEventHandler(_target, handlerDelegate);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,44 +0,0 @@
using System;
using System.Collections.Concurrent;
using LuaState = KeraLua.Lua;
namespace NLua
{
internal class ObjectTranslatorPool
{
private static volatile ObjectTranslatorPool _instance = new ObjectTranslatorPool();
private ConcurrentDictionary<LuaState, ObjectTranslator> translators = new ConcurrentDictionary<LuaState, ObjectTranslator>();
public static ObjectTranslatorPool Instance => _instance;
public void Add(LuaState luaState, ObjectTranslator translator)
{
if(!translators.TryAdd(luaState, translator))
throw new ArgumentException("An item with the same key has already been added. ", "luaState");
}
public ObjectTranslator Find(LuaState luaState)
{
ObjectTranslator translator;
if(!translators.TryGetValue(luaState, out translator))
{
LuaState main = luaState.MainThread;
if (!translators.TryGetValue(main, out translator))
return null;
}
return translator;
}
public void Remove(LuaState luaState)
{
ObjectTranslator translator;
translators.TryRemove(luaState, out translator);
}
}
}

View File

@ -1,39 +0,0 @@
using System.Reflection;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
#if NETFRAMEWORK
[assembly: AssemblyTitle ("NLua (.NET Framework 4.5)")]
#elif WINDOWS_UWP
[assembly: AssemblyTitle ("NLua (Windows Universal)")]
#elif __ANDROID__
[assembly: AssemblyTitle ("NLua (Xamarin.Android)")]
#elif NETCOREAPP
[assembly: AssemblyTitle ("NLua (.NET Core)")]
#elif NETSTANDARD
[assembly: AssemblyTitle ("NLua (.NET Standard)")]
#elif __TVOS__
[assembly: AssemblyTitle ("NLua (Xamarin.tvOS)")]
#elif __WATCHOS__
[assembly: AssemblyTitle ("NLua (Xamarin.watchOS)")]
#elif __IOS__
[assembly: AssemblyTitle ("NLua (Xamarin.iOS)")]
#elif __MACOS__
[assembly: AssemblyTitle ("NLua (Xamarin.Mac)")]
#else
[assembly: AssemblyTitle ("NLua (.NET Framework)")]
#endif
[assembly: AssemblyDescription ("NLua library")]
[assembly: AssemblyCompany ("NLua.org")]
[assembly: AssemblyProduct ("NLua")]
[assembly: AssemblyCopyright ("Copyright © Vinicius Jarina 2020")]
[assembly: AssemblyCulture ("")]
[assembly: AssemblyVersion("1.4.1.0")]
[assembly: AssemblyInformationalVersion("1.0.7+Branch.master.Sha.80a328a64f12ed9032a0f14a75e6ecad967514d0")]
[assembly: AssemblyFileVersion("1.4.1.0")]

View File

@ -1,53 +0,0 @@
using System;
using System.Reflection;
namespace NLua
{
/// <summary>
/// Summary description for ProxyType.
/// </summary>
public class ProxyType
{
private readonly Type _proxy;
public ProxyType(Type proxy)
{
_proxy = proxy;
}
/// <summary>
/// Provide human readable short hand for this proxy object
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "ProxyType(" + UnderlyingSystemType + ")";
}
public Type UnderlyingSystemType => _proxy;
public override bool Equals(object obj)
{
if (obj is Type)
return _proxy == (Type)obj;
if (obj is ProxyType)
return _proxy == ((ProxyType)obj).UnderlyingSystemType;
return _proxy.Equals(obj);
}
public override int GetHashCode()
{
return _proxy.GetHashCode();
}
public MemberInfo[] GetMember(string name, BindingFlags bindingAttr)
{
return _proxy.GetMember(name, bindingAttr);
}
public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Type[] signature)
{
return _proxy.GetMethod(name, bindingAttr, null, signature, null);
}
}
}

View File

@ -20,42 +20,66 @@ namespace OpenSim.Region.ScriptEngine.Lua
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "LUAEngine")]
class LUAEngine : INonSharedRegionModule, IScriptModule, IScriptEngine
{
private IConfigSource m_config = null;
private Scene m_scene = null;
private bool m_enable = true;
private bool m_sandbox = true;
public event ScriptRemoved OnScriptRemoved;
public event ObjectRemoved OnObjectRemoved;
#region INonSharedRegionModule
public string Name => throw new NotImplementedException();
public Type ReplaceableInterface => throw new NotImplementedException();
public void AddRegion(Scene scene)
public string Name
{
throw new NotImplementedException();
get { return "LUAEngine"; }
}
public void Close()
public Type ReplaceableInterface
{
throw new NotImplementedException();
get { return null; }
}
public void Initialise(IConfigSource source)
{
throw new NotImplementedException();
if (source.Configs["LUA"] == null)
return;
m_config = source;
m_enable = source.Configs["LUA"].GetBoolean("Enable", m_enable);
m_sandbox = source.Configs["LUA"].GetBoolean("Sandbox", m_sandbox);
}
public void RegionLoaded(Scene scene)
public void AddRegion(Scene scene)
{
throw new NotImplementedException();
if (m_scene == null)
m_scene = scene;
}
public void RemoveRegion(Scene scene)
{
throw new NotImplementedException();
m_scene = null;
}
public void Close()
{
m_scene = null;
}
public void RegionLoaded(Scene scene)
{
if (m_scene == null)
m_scene = scene;
}
#endregion
#region IScriptModule
public string ScriptEngineName => throw new NotImplementedException();
public event ScriptRemoved OnScriptRemoved;
public event ObjectRemoved OnObjectRemoved;
public string ScriptEngineName
{
get { return "LUAEngine"; }
}
public Dictionary<uint, float> GetObjectScriptsExecutionTimes()
{
@ -125,15 +149,27 @@ namespace OpenSim.Region.ScriptEngine.Lua
#endregion
#region IScriptEngine
public Scene World => throw new NotImplementedException();
public Scene World
{
get { return m_scene; }
}
public IScriptModule ScriptModule => throw new NotImplementedException();
public IConfig Config => throw new NotImplementedException();
public IConfig Config
{
get { return m_config.Configs["LUA"]; }
}
public IConfigSource ConfigSource => throw new NotImplementedException();
public IConfigSource ConfigSource
{
get { return m_config; }
}
public string ScriptEnginePath => throw new NotImplementedException();
public string ScriptEnginePath
{
get { return "./LUAScriptEngine"; }
}
public string ScriptClassName => throw new NotImplementedException();

23
src/RunningScript.cs Normal file
View File

@ -0,0 +1,23 @@
using OpenMetaverse;
using OpenSim.Region.Framework.Scenes;
using NLua;
namespace OpenSim.Region.ScriptEngine.Lua
{
class RunningScript
{
private SceneObjectPart m_host = null;
private InventoryItem m_item = null;
private Lua m_runtime = null;
private RunningScript(InventoryItem item, SceneObjectPart host)
{
m_host = host;
m_item = item;
m_runtime = new Lua();
}
}
}