diff --git a/LuaInterface/AssemblyInfo.cs b/LuaInterface/AssemblyInfo.cs deleted file mode 100644 index 70db5f2c9b..0000000000 --- a/LuaInterface/AssemblyInfo.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Security.Permissions; - -// -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -// -[assembly: AssemblyTitle("LuaInterface")] -[assembly: AssemblyDescription("Bridge between the Lua runtime and the CLR")] -[assembly: AssemblyCopyright("Copyright 2003-2008 Fabio Mascarenhas, Kevin Hester")] -[assembly: CLSCompliant(false)] - -// -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: - -[assembly: AssemblyVersion("2.0.4.*")] - -// -// In order to sign your assembly you must specify a key to use. Refer to the -// Microsoft .NET Framework documentation for more information on assembly signing. -// -// Use the attributes below to control which key is used for signing. -// -// Notes: -// (*) If no key is specified, the assembly is not signed. -// (*) KeyName refers to a key that has been installed in the Crypto Service -// Provider (CSP) on your machine. KeyFile refers to a file which contains -// a key. -// (*) If the KeyFile and the KeyName values are both specified, the -// following processing occurs: -// (1) If the KeyName can be found in the CSP, that key is used. -// (2) If the KeyName does not exist and the KeyFile does exist, the key -// in the KeyFile is installed into the CSP and used. -// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. -// When specifying the KeyFile, the location of the KeyFile should be -// relative to the project output directory which is -// %Project Directory%\obj\. For example, if your KeyFile is -// located in the project directory, you would specify the AssemblyKeyFile -// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] -// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework -// documentation for more information on this. -// - -// We call native DLLs (lua50) and we don't want to be fucked with or validated -// [assembly: SecurityPermission(RequestMinimum, UnmanagedCode = true)] diff --git a/LuaInterface/CheckType.cs b/LuaInterface/CheckType.cs deleted file mode 100644 index 6fda337278..0000000000 --- a/LuaInterface/CheckType.cs +++ /dev/null @@ -1,314 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; - -namespace LuaInterface -{ - /* - * Type checking and conversion functions. - * - * Author: Fabio Mascarenhas - * Version: 1.0 - */ - class CheckType - { - private ObjectTranslator translator; - - ExtractValue extractNetObject; - Dictionary extractValues = new Dictionary(); - - public CheckType(ObjectTranslator translator) - { - this.translator = translator; - - extractValues.Add(typeof(object).TypeHandle.Value.ToInt64(), new ExtractValue(getAsObject)); - extractValues.Add(typeof(sbyte).TypeHandle.Value.ToInt64(), new ExtractValue(getAsSbyte)); - extractValues.Add(typeof(byte).TypeHandle.Value.ToInt64(), new ExtractValue(getAsByte)); - extractValues.Add(typeof(short).TypeHandle.Value.ToInt64(), new ExtractValue(getAsShort)); - extractValues.Add(typeof(ushort).TypeHandle.Value.ToInt64(), new ExtractValue(getAsUshort)); - extractValues.Add(typeof(int).TypeHandle.Value.ToInt64(), new ExtractValue(getAsInt)); - extractValues.Add(typeof(uint).TypeHandle.Value.ToInt64(), new ExtractValue(getAsUint)); - extractValues.Add(typeof(long).TypeHandle.Value.ToInt64(), new ExtractValue(getAsLong)); - extractValues.Add(typeof(ulong).TypeHandle.Value.ToInt64(), new ExtractValue(getAsUlong)); - extractValues.Add(typeof(double).TypeHandle.Value.ToInt64(), new ExtractValue(getAsDouble)); - extractValues.Add(typeof(char).TypeHandle.Value.ToInt64(), new ExtractValue(getAsChar)); - extractValues.Add(typeof(float).TypeHandle.Value.ToInt64(), new ExtractValue(getAsFloat)); - extractValues.Add(typeof(decimal).TypeHandle.Value.ToInt64(), new ExtractValue(getAsDecimal)); - extractValues.Add(typeof(bool).TypeHandle.Value.ToInt64(), new ExtractValue(getAsBoolean)); - extractValues.Add(typeof(string).TypeHandle.Value.ToInt64(), new ExtractValue(getAsString)); - extractValues.Add(typeof(LuaFunction).TypeHandle.Value.ToInt64(), new ExtractValue(getAsFunction)); - extractValues.Add(typeof(LuaTable).TypeHandle.Value.ToInt64(), new ExtractValue(getAsTable)); - extractValues.Add(typeof(LuaUserData).TypeHandle.Value.ToInt64(), new ExtractValue(getAsUserdata)); - - extractNetObject = new ExtractValue(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(IReflect paramType) - { - return getExtractor(paramType.UnderlyingSystemType); - } - internal ExtractValue getExtractor(Type paramType) - { - if(paramType.IsByRef) paramType=paramType.GetElementType(); - - long runtimeHandleValue = paramType.TypeHandle.Value.ToInt64(); - - if(extractValues.ContainsKey(runtimeHandleValue)) - return extractValues[runtimeHandleValue]; - else - return extractNetObject; - } - - internal ExtractValue checkType(IntPtr luaState,int stackPos,Type paramType) - { - LuaTypes luatype = LuaDLL.lua_type(luaState, stackPos); - - if(paramType.IsByRef) paramType=paramType.GetElementType(); - - Type underlyingType = Nullable.GetUnderlyingType(paramType); - if (underlyingType != null) - { - paramType = underlyingType; // Silently convert nullable types to their non null requics - } - - long runtimeHandleValue = paramType.TypeHandle.Value.ToInt64(); - - if (paramType.Equals(typeof(object))) - return extractValues[runtimeHandleValue]; - - /* - //CP: Added support for generic parameters - if (paramType.IsGenericParameter) - { - if (luatype == LuaTypes.LUA_TBOOLEAN) - return extractValues[typeof(bool).TypeHandle.Value.ToInt64()]; - else if (luatype == LuaTypes.LUA_TSTRING) - return extractValues[typeof(string).TypeHandle.Value.ToInt64()]; - else if (luatype == LuaTypes.LUA_TTABLE) - return extractValues[typeof(LuaTable).TypeHandle.Value.ToInt64()]; - else if (luatype == LuaTypes.LUA_TUSERDATA) - return extractValues[typeof(object).TypeHandle.Value.ToInt64()]; - else if (luatype == LuaTypes.LUA_TFUNCTION) - return extractValues[typeof(LuaFunction).TypeHandle.Value.ToInt64()]; - else if (luatype == LuaTypes.LUA_TNUMBER) - return extractValues[typeof(double).TypeHandle.Value.ToInt64()]; - //else // suppress CS0642 - ;//an unsupported type was encountered - } - */ - - if (LuaDLL.lua_isnumber(luaState, stackPos)) - return extractValues[runtimeHandleValue]; - - if (paramType == typeof(bool)) - { - if (LuaDLL.lua_isboolean(luaState, stackPos)) - return extractValues[runtimeHandleValue]; - } - else if (paramType == typeof(string)) - { - if (LuaDLL.lua_isstring(luaState, stackPos)) - return extractValues[runtimeHandleValue]; - else if (luatype == LuaTypes.LUA_TNIL) - return extractNetObject; // kevinh - silently convert nil to a null string pointer - } - else if (paramType == typeof(LuaTable)) - { - if (luatype == LuaTypes.LUA_TTABLE) - return extractValues[runtimeHandleValue]; - else if (luatype == LuaTypes.LUA_TNIL) - return extractNetObject; // tkopal - silently convert nil to a null table - } - else if (paramType == typeof(LuaUserData)) - { - if (luatype == LuaTypes.LUA_TUSERDATA) - return extractValues[runtimeHandleValue]; - } - else if (paramType == typeof(LuaFunction)) - { - if (luatype == LuaTypes.LUA_TFUNCTION) - return extractValues[runtimeHandleValue]; - else if (luatype == LuaTypes.LUA_TNIL) - return extractNetObject; // elisee - silently convert nil to a null string pointer - } - else if (typeof(Delegate).IsAssignableFrom(paramType) && luatype == LuaTypes.LUA_TFUNCTION) - { - return new ExtractValue(new DelegateGenerator(translator, paramType).extractGenerated); - } - else if (paramType.IsInterface && luatype == LuaTypes.LUA_TTABLE) - { - return new ExtractValue(new ClassGenerator(translator, paramType).extractGenerated); - } - else if ((paramType.IsInterface || paramType.IsClass) && luatype == LuaTypes.LUA_TNIL) - { - // kevinh - allow nil to be silently converted to null - extractNetObject will return null when the item ain't found - return extractNetObject; - } - else if (LuaDLL.lua_type(luaState, stackPos) == LuaTypes.LUA_TTABLE) - { - if (LuaDLL.luaL_getmetafield(luaState, stackPos, "__index")) - { - object obj = translator.getNetObject(luaState, -1); - LuaDLL.lua_settop(luaState, -2); - if (obj != null && paramType.IsAssignableFrom(obj.GetType())) - return extractNetObject; - } - else - return null; - } - else - { - object obj = translator.getNetObject(luaState, stackPos); - if (obj != null && paramType.IsAssignableFrom(obj.GetType())) - 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(IntPtr luaState,int stackPos) - { - sbyte retVal=(sbyte)LuaDLL.lua_tonumber(luaState,stackPos); - if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; - return retVal; - } - private object getAsByte(IntPtr luaState,int stackPos) - { - byte retVal=(byte)LuaDLL.lua_tonumber(luaState,stackPos); - if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; - return retVal; - } - private object getAsShort(IntPtr luaState,int stackPos) - { - short retVal=(short)LuaDLL.lua_tonumber(luaState,stackPos); - if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; - return retVal; - } - private object getAsUshort(IntPtr luaState,int stackPos) - { - ushort retVal=(ushort)LuaDLL.lua_tonumber(luaState,stackPos); - if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; - return retVal; - } - private object getAsInt(IntPtr luaState,int stackPos) - { - int retVal=(int)LuaDLL.lua_tonumber(luaState,stackPos); - if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; - return retVal; - } - private object getAsUint(IntPtr luaState,int stackPos) - { - uint retVal=(uint)LuaDLL.lua_tonumber(luaState,stackPos); - if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; - return retVal; - } - private object getAsLong(IntPtr luaState,int stackPos) - { - long retVal=(long)LuaDLL.lua_tonumber(luaState,stackPos); - if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; - return retVal; - } - private object getAsUlong(IntPtr luaState,int stackPos) - { - ulong retVal=(ulong)LuaDLL.lua_tonumber(luaState,stackPos); - if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; - return retVal; - } - private object getAsDouble(IntPtr luaState,int stackPos) - { - double retVal=LuaDLL.lua_tonumber(luaState,stackPos); - if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; - return retVal; - } - private object getAsChar(IntPtr luaState,int stackPos) - { - char retVal=(char)LuaDLL.lua_tonumber(luaState,stackPos); - if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; - return retVal; - } - private object getAsFloat(IntPtr luaState,int stackPos) - { - float retVal=(float)LuaDLL.lua_tonumber(luaState,stackPos); - if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; - return retVal; - } - private object getAsDecimal(IntPtr luaState,int stackPos) - { - decimal retVal=(decimal)LuaDLL.lua_tonumber(luaState,stackPos); - if(retVal==0 && !LuaDLL.lua_isnumber(luaState,stackPos)) return null; - return retVal; - } - private object getAsBoolean(IntPtr luaState,int stackPos) - { - return LuaDLL.lua_toboolean(luaState,stackPos); - } - private object getAsString(IntPtr luaState,int stackPos) - { - string retVal=LuaDLL.lua_tostring(luaState,stackPos); - if(retVal=="" && !LuaDLL.lua_isstring(luaState,stackPos)) return null; - return retVal; - } - private object getAsTable(IntPtr luaState,int stackPos) - { - return translator.getTable(luaState,stackPos); - } - private object getAsFunction(IntPtr luaState,int stackPos) - { - return translator.getFunction(luaState,stackPos); - } - private object getAsUserdata(IntPtr luaState,int stackPos) - { - return translator.getUserData(luaState,stackPos); - } - public object getAsObject(IntPtr luaState,int stackPos) - { - if(LuaDLL.lua_type(luaState,stackPos)==LuaTypes.LUA_TTABLE) - { - if(LuaDLL.luaL_getmetafield(luaState,stackPos,"__index")) - { - if(LuaDLL.luaL_checkmetatable(luaState,-1)) - { - LuaDLL.lua_insert(luaState,stackPos); - LuaDLL.lua_remove(luaState,stackPos+1); - } - else - { - LuaDLL.lua_settop(luaState,-2); - } - } - } - object obj=translator.getObject(luaState,stackPos); - return obj; - } - public object getAsNetObject(IntPtr luaState,int stackPos) - { - object obj=translator.getNetObject(luaState,stackPos); - if(obj==null && LuaDLL.lua_type(luaState,stackPos)==LuaTypes.LUA_TTABLE) - { - if(LuaDLL.luaL_getmetafield(luaState,stackPos,"__index")) - { - if(LuaDLL.luaL_checkmetatable(luaState,-1)) - { - LuaDLL.lua_insert(luaState,stackPos); - LuaDLL.lua_remove(luaState,stackPos+1); - obj=translator.getNetObject(luaState,stackPos); - } - else - { - LuaDLL.lua_settop(luaState,-2); - } - } - } - return obj; - } - } -} diff --git a/LuaInterface/GenerateEventAssembly.cs b/LuaInterface/GenerateEventAssembly.cs deleted file mode 100644 index 775b62a2cb..0000000000 --- a/LuaInterface/GenerateEventAssembly.cs +++ /dev/null @@ -1,683 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -using System.Reflection.Emit; -using System.Threading; - -namespace LuaInterface -{ - /* - * 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; - } - - /* - * 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 __luaInterface_getLuaTable(); - } - - /* - * Class used for generating delegates that get a function from the Lua - * stack as a delegate of a specific type. - * - * Author: Fabio Mascarenhas - * Version: 1.0 - */ - class DelegateGenerator - { - private ObjectTranslator translator; - private Type delegateType; - - public DelegateGenerator(ObjectTranslator translator,Type delegateType) - { - this.translator=translator; - this.delegateType=delegateType; - } - public object extractGenerated(IntPtr luaState,int stackPos) - { - return CodeGeneration.Instance.GetDelegate(delegateType,translator.getFunction(luaState,stackPos)); - } - } - - /* - * Class used for generating delegates that get a table from the Lua - * stack as a an object of a specific type. - * - * Author: Fabio Mascarenhas - * Version: 1.0 - */ - class ClassGenerator - { - private ObjectTranslator translator; - private Type klass; - - public ClassGenerator(ObjectTranslator translator,Type klass) - { - this.translator=translator; - this.klass=klass; - } - public object extractGenerated(IntPtr luaState,int stackPos) - { - return CodeGeneration.Instance.GetClassInstance(klass,translator.getTable(luaState,stackPos)); - } - } - - /* - * Dynamically generates new types from existing types and - * Lua function and table values. Generated types are event handlers, - * delegates, interface implementations and subclasses. - * - * Author: Fabio Mascarenhas - * Version: 1.0 - */ - class CodeGeneration - { - private Type eventHandlerParent=typeof(LuaEventHandler); - private Dictionary eventHandlerCollection=new Dictionary(); - - private Type delegateParent=typeof(LuaDelegate); - private Dictionary delegateCollection=new Dictionary(); - - private Type classHelper=typeof(LuaClassHelper); - private Dictionary classCollection=new Dictionary(); - - private AssemblyName assemblyName; - private AssemblyBuilder newAssembly; - private ModuleBuilder newModule; - private int luaClassNumber=1; - private static readonly CodeGeneration instance = new CodeGeneration(); - - static CodeGeneration() - { - } - - private CodeGeneration() - { - // Create an assembly name - assemblyName=new AssemblyName( ); - assemblyName.Name="LuaInterface_generatedcode"; - // Create a new assembly with one module. - newAssembly=Thread.GetDomain().DefineDynamicAssembly( - assemblyName, AssemblyBuilderAccess.Run); - newModule=newAssembly.DefineDynamicModule("LuaInterface_generatedcode"); - } - - /* - * Singleton instance of the class - */ - public static CodeGeneration Instance - { - get - { - return instance; - } - } - - /* - * Generates an event handler that calls a Lua function - */ - private Type GenerateEvent(Type eventHandlerType) - { - string typeName; - lock(this) - { - typeName = "LuaGeneratedClass" + luaClassNumber; - luaClassNumber++; - } - // Define a public class in the assembly, called typeName - TypeBuilder myType=newModule.DefineType(typeName,TypeAttributes.Public,eventHandlerParent); - - // Defines the handler method. Its signature is void(object,) - Type[] paramTypes = new Type[2]; - paramTypes[0]=typeof(object); - paramTypes[1]=eventHandlerType; - Type returnType=typeof(void); - MethodBuilder 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); - MethodInfo miGenericEventHandler; - miGenericEventHandler=eventHandlerParent.GetMethod("handleEvent"); - generator.Emit(OpCodes.Call,miGenericEventHandler); - // returns - generator.Emit(OpCodes.Ret); - - // creates the new type - return myType.CreateType(); - } - - /* - * Generates a type that can be used for instantiating a delegate - * of the provided type, given a Lua function. - */ - private Type GenerateDelegate(Type delegateType) - { - string typeName; - lock(this) - { - typeName = "LuaGeneratedClass" + luaClassNumber; - luaClassNumber++; - } - // Define a public class in the assembly, called typeName - TypeBuilder myType=newModule.DefineType(typeName,TypeAttributes.Public,delegateParent); - - // Defines the delegate method with the same signature as the - // Invoke method of delegateType - MethodInfo invokeMethod=delegateType.GetMethod("Invoke"); - ParameterInfo[] paramInfo=invokeMethod.GetParameters(); - Type[] paramTypes=new Type[paramInfo.Length]; - Type returnType=invokeMethod.ReturnType; - - // Counts out and ref params, for use later - int nOutParams=0; int nOutAndRefParams=0; - for(int i=0;i returnTypesList=new List(); - - // Counts out and ref parameters, for later use, - // and creates the list of return types - int nOutParams=0; int nOutAndRefParams=0; - Type returnType=method.ReturnType; - returnTypesList.Add(returnType); - for(int i=0;i returnTypes=new List(); - Type luaDelegateType; - if (delegateCollection.ContainsKey(delegateType)) - { - luaDelegateType=delegateCollection[delegateType]; - } - else - { - luaDelegateType=GenerateDelegate(delegateType); - delegateCollection[delegateType] = luaDelegateType; - } - MethodInfo methodInfo=delegateType.GetMethod("Invoke"); - returnTypes.Add(methodInfo.ReturnType); - foreach(ParameterInfo paramInfo in methodInfo.GetParameters()) - if(paramInfo.ParameterType.IsByRef) - returnTypes.Add(paramInfo.ParameterType); - LuaDelegate 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,luaTable); - classCollection[klass] = luaClassType; - } - return Activator.CreateInstance(luaClassType.klass,new object[] {luaTable,luaClassType.returnTypes}); - } - } -} diff --git a/LuaInterface/Lua.cs b/LuaInterface/Lua.cs deleted file mode 100644 index cc5ba42077..0000000000 --- a/LuaInterface/Lua.cs +++ /dev/null @@ -1,761 +0,0 @@ - -namespace LuaInterface -{ - using System; - using System.IO; - using System.Collections; - using System.Collections.Generic; - using System.Collections.Specialized; - using System.Reflection; - using System.Threading; - using OpenRA; - using System.Text; - - /* - * Main class of LuaInterface - * Object-oriented wrapper to Lua API - * - * Author: Fabio Mascarenhas - * Version: 1.0 - * - * // steffenj: important changes in Lua class: - * - removed all Open*Lib() functions - * - all libs automatically open in the Lua class constructor (just assign nil to unwanted libs) - * */ - public class Lua : IDisposable - { - /*readonly */ IntPtr luaState; - ObjectTranslator translator; - - LuaFunctionCallback panicCallback; - LuaCSFunction tracebackFunction; - // lockCallback, unlockCallback; used by debug code commented out for now - - public Lua() - { - luaState = LuaDLL.luaL_newstate(); // steffenj: Lua 5.1.1 API change (lua_open is gone) - - // Load libraries - LuaDLL.luaL_openlibs(luaState); - - // Add LuaInterface marker - LuaDLL.lua_pushstring(luaState, "LUAINTERFACE LOADED"); - LuaDLL.lua_pushboolean(luaState, true); - LuaDLL.lua_settable(luaState, (int) LuaIndexes.LUA_REGISTRYINDEX); - - translator=new ObjectTranslator(this,luaState); - - tracebackFunction = new LuaCSFunction(traceback); - - // We need to keep this in a managed reference so the delegate doesn't get garbage collected - panicCallback = new LuaFunctionCallback(PanicCallback); - LuaDLL.lua_atpanic(luaState, panicCallback); - } - - private bool _StatePassed; - - /* - * CAUTION: LuaInterface.Lua instances can't share the same lua state! - */ - public Lua( Int64 luaState ) - { - // Check for existing LuaInterface marker - IntPtr lState = new IntPtr(luaState); - LuaDLL.lua_pushstring(lState, "LUAINTERFACE LOADED"); - LuaDLL.lua_gettable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX); - - if(LuaDLL.lua_toboolean(lState,-1)) - { - LuaDLL.lua_settop(lState,-2); - throw new LuaException("There is already a LuaInterface.Lua instance associated with this Lua state"); - } - else - { - // Add LuaInterface marker - LuaDLL.lua_settop(lState,-2); - LuaDLL.lua_pushstring(lState, "LUAINTERFACE LOADED"); - LuaDLL.lua_pushboolean(lState, true); - LuaDLL.lua_settable(lState, (int)LuaIndexes.LUA_REGISTRYINDEX); - - this.luaState = lState; - LuaDLL.lua_pushvalue(lState, (int)LuaIndexes.LUA_GLOBALSINDEX); - - translator = new ObjectTranslator(this, this.luaState); - } - - _StatePassed = true; - } - - public void Close() - { - if (_StatePassed) - return; - - if (luaState != IntPtr.Zero) - LuaDLL.lua_close(luaState); - //luaState = IntPtr.Zero; <- suggested by Christopher Cebulski http://luaforge.net/forum/forum.php?thread_id=44593&forum_id=146 - } - - static int PanicCallback(IntPtr luaState) - { - // string desc = LuaDLL.lua_tostring(luaState, 1); - string reason = String.Format("unprotected error in call to Lua API ({0})", LuaDLL.lua_tostring(luaState, -1)); - - // lua_tostring(L, -1); - - throw new LuaException(reason); - } - - - - /// - /// Assuming we have a Lua error string sitting on the stack, throw a C# exception out to the user's app - /// - /// Thrown if the script caused an exception - void ThrowExceptionFromError(int oldTop) - { - object err = translator.getObject(luaState, -1); - LuaDLL.lua_settop(luaState, oldTop); - - // A pre-wrapped exception - just rethrow it (stack trace of InnerException will be preserved) - LuaScriptException luaEx = err as LuaScriptException; - if (luaEx != null) throw luaEx; - - // A non-wrapped Lua error (best interpreted as a string) - wrap it and throw it - if (err == null) err = "Unknown Lua Error"; - throw new LuaScriptException(err.ToString(), ""); - } - - - - /// - /// Convert C# exceptions into Lua errors - /// - /// num of things on stack - /// null for no pending exception - internal int SetPendingException(Exception e) - { - Exception caughtExcept = e; - - if (caughtExcept != null) - { - translator.throwError(luaState, caughtExcept); - LuaDLL.lua_pushnil(luaState); - - return 1; - } - else - return 0; - } - - private bool executing; - - /// - /// True while a script is being executed - /// - public bool IsExecuting { get { return executing; } } - - /// - /// - /// - /// - /// - /// - public LuaFunction LoadString(string chunk, string name) - { - int oldTop = LuaDLL.lua_gettop(luaState); - - executing = true; - - // Somehow, on OS X, we need to use the UTF-8 byte count rather than the string length - // Adapted for OpenRA - var chunkLength = Platform.CurrentPlatform != PlatformType.Windows - ? Encoding.UTF8.GetByteCount(chunk) - : chunk.Length; - - try - { - if (LuaDLL.luaL_loadbuffer(luaState, chunk, chunkLength, name) != 0) - ThrowExceptionFromError(oldTop); - } - finally { executing = false; } - - LuaFunction result = translator.getFunction(luaState, -1); - translator.popValues(luaState, oldTop); - - return result; - } - - /// - /// - /// - /// - /// - public LuaFunction LoadFile(string fileName) - { - int oldTop = LuaDLL.lua_gettop(luaState); - if (LuaDLL.luaL_loadfile(luaState, fileName) != 0) - ThrowExceptionFromError(oldTop); - - LuaFunction result = translator.getFunction(luaState, -1); - translator.popValues(luaState, oldTop); - - return result; - } - - - /* - * Excutes a Lua chunk and returns all the chunk's return - * values in an array - */ - public object[] DoString(string chunk) - { - return DoString(chunk,"chunk"); - } - - /// - /// Executes a Lua chnk and returns all the chunk's return values in an array. - /// - /// Chunk to execute - /// Name to associate with the chunk - /// - public object[] DoString(string chunk, string chunkName) - { - int oldTop = LuaDLL.lua_gettop(luaState); - executing = true; - - // Somehow, on OS X, we need to use the UTF-8 byte count rather than the string length - // Adapted for OpenRA - var chunkLength = Platform.CurrentPlatform != PlatformType.Windows - ? Encoding.UTF8.GetByteCount(chunk) - : chunk.Length; - - if (LuaDLL.luaL_loadbuffer(luaState, chunk, chunkLength, chunkName) == 0) - { - try - { - if (LuaDLL.lua_pcall(luaState, 0, -1, 0) == 0) - return translator.popValues(luaState, oldTop); - else - ThrowExceptionFromError(oldTop); - } - finally { executing = false; } - } - else - ThrowExceptionFromError(oldTop); - - return null; // Never reached - keeps compiler happy - } - - private int traceback(IntPtr luaState) - { - LuaDLL.lua_getglobal(luaState,"debug"); - LuaDLL.lua_getfield(luaState,-1,"traceback"); - LuaDLL.lua_pushvalue(luaState,1); - LuaDLL.lua_pushnumber(luaState,2); - LuaDLL.lua_call (luaState,2,1); - return 1; - } - - /* - * Excutes a Lua file and returns all the chunk's return - * values in an array - */ - public object[] DoFile(string fileName) - { - LuaDLL.lua_pushstdcallcfunction(luaState,tracebackFunction); - int oldTop=LuaDLL.lua_gettop(luaState); - if(LuaDLL.luaL_loadfile(luaState,fileName)==0) - { - executing = true; - try - { - if (LuaDLL.lua_pcall(luaState, 0, -1, -2) == 0) - return translator.popValues(luaState, oldTop); - else - ThrowExceptionFromError(oldTop); - } - finally { executing = false; } - } - else - ThrowExceptionFromError(oldTop); - - return null; // Never reached - keeps compiler happy - } - - - public void CollectGarbage() - { - LuaDLL.lua_gc( luaState, LuaGCOptions.LUA_GCCOLLECT, 0 ); - } - - /* - * Indexer for global variables from the LuaInterpreter - * Supports navigation of tables by using . operator - */ - public object this[string fullPath] - { - get - { - object returnValue=null; - int oldTop=LuaDLL.lua_gettop(luaState); - string[] path=fullPath.Split(new char[] { '.' }); - LuaDLL.lua_getglobal(luaState,path[0]); - returnValue=translator.getObject(luaState,-1); - if(path.Length>1) - { - string[] remainingPath=new string[path.Length-1]; - Array.Copy(path,1,remainingPath,0,path.Length-1); - returnValue=getObject(remainingPath); - } - LuaDLL.lua_settop(luaState,oldTop); - return returnValue; - } - set - { - int oldTop=LuaDLL.lua_gettop(luaState); - string[] path=fullPath.Split(new char[] { '.' }); - if(path.Length==1) - { - translator.push(luaState,value); - LuaDLL.lua_setglobal(luaState,fullPath); - } - else - { - LuaDLL.lua_getglobal(luaState,path[0]); - string[] remainingPath=new string[path.Length-1]; - Array.Copy(path,1,remainingPath,0,path.Length-1); - setObject(remainingPath,value); - } - LuaDLL.lua_settop(luaState,oldTop); - - // Globals auto-complete - if (value == null) - { - // Remove now obsolete entries - globals.Remove(fullPath); - } - else - { - // Add new entries - if (!globals.Contains(fullPath)) - registerGlobal(fullPath, value.GetType(), 0); - } - } - } - - #region Globals auto-complete - private readonly List globals = new List(); - private bool globalsSorted; - - /// - /// An alphabetically sorted list of all globals (objects, methods, etc.) externally added to this Lua instance - /// - /// Members of globals are also listed. The formatting is optimized for text input auto-completion. - public IEnumerable Globals - { - get - { - // Only sort list when necessary - if (!globalsSorted) - { - globals.Sort(); - globalsSorted = true; - } - - return globals; - } - } - - /// - /// Adds an entry to (recursivley handles 2 levels of members) - /// - /// The index accessor path ot the entry - /// The type of the entry - /// How deep have we gone with recursion? - private void registerGlobal(string path, Type type, int recursionCounter) - { - // If the type is a global method, list it directly - if (type == typeof(LuaCSFunction)) - { - // Format for easy method invocation - globals.Add(path + "("); - } - // If the type is a class or an interface and recursion hasn't been running too long, list the members - else if ((type.IsClass || type.IsInterface) && type != typeof(string) && recursionCounter < 2) - { - #region Methods - foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance)) - { - if ( - // Check that the LuaHideAttribute and LuaGlobalAttribute were not applied - (method.GetCustomAttributes(typeof(LuaHideAttribute), false).Length == 0) && - (method.GetCustomAttributes(typeof(LuaGlobalAttribute), false).Length == 0) && - // Exclude some generic .NET methods that wouldn't be very usefull in Lua - method.Name != "GetType" && method.Name != "GetHashCode" && method.Name != "Equals" && - method.Name != "ToString" && method.Name != "Clone" && method.Name != "Dispose" && - method.Name != "GetEnumerator" && method.Name != "CopyTo" && - !method.Name.StartsWith("get_", StringComparison.Ordinal) && - !method.Name.StartsWith("set_", StringComparison.Ordinal) && - !method.Name.StartsWith("add_", StringComparison.Ordinal) && - !method.Name.StartsWith("remove_", StringComparison.Ordinal)) - { - // Format for easy method invocation - string command = path + ":" + method.Name + "("; - if (method.GetParameters().Length == 0) command += ")"; - globals.Add(command); - } - } - #endregion - - #region Fields - foreach (FieldInfo field in type.GetFields(BindingFlags.Public | BindingFlags.Instance)) - { - if ( - // Check that the LuaHideAttribute and LuaGlobalAttribute were not applied - (field.GetCustomAttributes(typeof(LuaHideAttribute), false).Length == 0) && - (field.GetCustomAttributes(typeof(LuaGlobalAttribute), false).Length == 0)) - { - // Go into recursion for members - registerGlobal(path + "." + field.Name, field.FieldType, recursionCounter + 1); - } - } - #endregion - - #region Properties - foreach (PropertyInfo property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) - { - if ( - // Check that the LuaHideAttribute and LuaGlobalAttribute were not applied - (property.GetCustomAttributes(typeof(LuaHideAttribute), false).Length == 0) && - (property.GetCustomAttributes(typeof(LuaGlobalAttribute), false).Length == 0) - // Exclude some generic .NET properties that wouldn't be very usefull in Lua - && property.Name != "Item") - { - // Go into recursion for members - registerGlobal(path + "." + property.Name, property.PropertyType, recursionCounter + 1); - } - } - #endregion - } - // Otherwise simply add the element to the list - else globals.Add(path); - - // List will need to be sorted on next access - globalsSorted = false; - } - #endregion - - /* - * Navigates a table in the top of the stack, returning - * the value of the specified field - */ - internal object getObject(string[] remainingPath) - { - object returnValue=null; - for(int i=0;i - /// Base class to provide consistent disposal flow across lua objects. Uses code provided by Yves Duhoux and suggestions by Hans Schmeidenbacher and Qingrui Li - /// - public abstract class LuaBase : IDisposable - { - private bool _Disposed; - protected int _Reference; - 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.dispose(_Reference); - } - _Interpreter = null; - _Disposed = true; - } - } - - public override bool Equals(object o) - { - if (o is LuaBase) - { - LuaBase l = (LuaBase)o; - return _Interpreter.compareRef(l._Reference, _Reference); - } - else return false; - } - - public override int GetHashCode() - { - return _Reference; - } - } -} diff --git a/LuaInterface/LuaDLL.cs b/LuaInterface/LuaDLL.cs deleted file mode 100644 index 3156a67dc9..0000000000 --- a/LuaInterface/LuaDLL.cs +++ /dev/null @@ -1,456 +0,0 @@ -namespace LuaInterface -{ - - using System; - using System.Runtime.InteropServices; - using System.Reflection; - using System.Collections; - using System.Text; - using System.Security; - - /* - * Lua types for the API, returned by lua_type function - */ - public enum LuaTypes - { - LUA_TNONE=-1, - LUA_TNIL=0, - LUA_TNUMBER=3, - LUA_TSTRING=4, - LUA_TBOOLEAN=1, - LUA_TTABLE=5, - LUA_TFUNCTION=6, - LUA_TUSERDATA=7, - LUA_TLIGHTUSERDATA=2 - } - - // steffenj: BEGIN lua garbage collector options - /* - * Lua Garbage Collector options (param "what") - */ - public enum LuaGCOptions - { - LUA_GCSTOP = 0, - LUA_GCRESTART = 1, - LUA_GCCOLLECT = 2, - LUA_GCCOUNT = 3, - LUA_GCCOUNTB = 4, - LUA_GCSTEP = 5, - LUA_GCSETPAUSE = 6, - LUA_GCSETSTEPMUL = 7, - } - /* - sealed class LuaGCOptions - { - public static int LUA_GCSTOP = 0; - public static int LUA_GCRESTART = 1; - public static int LUA_GCCOLLECT = 2; - public static int LUA_GCCOUNT = 3; - public static int LUA_GCCOUNTB = 4; - public static int LUA_GCSTEP = 5; - public static int LUA_GCSETPAUSE = 6; - public static int LUA_GCSETSTEPMUL = 7; - }; - */ - // steffenj: END lua garbage collector options - - /* - * Special stack indexes - */ - sealed class LuaIndexes - { - public static int LUA_REGISTRYINDEX=-10000; - public static int LUA_ENVIRONINDEX=-10001; // steffenj: added environindex - public static int LUA_GLOBALSINDEX=-10002; // steffenj: globalsindex previously was -10001 - } - - /* - * Structure used by the chunk reader - */ - [ StructLayout( LayoutKind.Sequential )] - public struct ReaderInfo - { - public String chunkData; - public bool finished; - } - - /* - * Delegate for functions passed to Lua as function pointers - */ - public delegate int LuaCSFunction(IntPtr luaState); - - /* - * Delegate for chunk readers used with lua_load - */ - public delegate string LuaChunkReader(IntPtr luaState,ref ReaderInfo data,ref uint size); - - - /// - /// Used to handle Lua panics - /// - /// - /// - public delegate int LuaFunctionCallback(IntPtr luaState); - - /* - * P/Invoke wrapper of the Lua API - * - * Author: Fabio Mascarenhas - * Version: 1.0 - * - * // steffenj: noteable changes in the LuaDLL API: - * - luaopen_* functions are gone - * (however Lua class constructor already calls luaL_openlibs now, so just remove these calls) - * - deprecated functions: lua_open, lua_strlen, lua_dostring - * (they still work but may be removed with next Lua version) - * - * list of functions of the Lua 5.1.1 C API that are not in LuaDLL - * i thought this may come in handy for the next Lua version upgrade and for anyone to see - * what the differences are in the APIs (C API vs LuaDLL API) - lua_concat (use System.String concatenation or similar) - lua_cpcall (no point in calling C functions) - lua_dump (would write to unmanaged memory via lua_Writer) - lua_getallocf (no C functions/pointers) - lua_isthread (no threads) - lua_newstate (use luaL_newstate) - lua_newthread (no threads) - lua_pushcclosure (no C functions/pointers) - lua_pushcfunction (no C functions/pointers) - lua_pushfstring (use lua_pushstring) - lua_pushthread (no threads) - lua_pushvfstring (use lua_pushstring) - lua_register (all libs already opened, use require in scripts for external libs) - lua_resume (no threads) - lua_setallocf (no C functions/pointers) - lua_status (no threads) - lua_tointeger (use System.Convert) - lua_tolstring (use lua_tostring) - lua_topointer (no C functions/pointers) - lua_tothread (no threads) - lua_xmove (no threads) - lua_yield (no threads) - - luaL_add* (use System.String concatenation or similar) - luaL_argcheck (function argument checking unnecessary) - luaL_argerror (function argument checking unnecessary) - luaL_buffinit (use System.String concatenation or similar) - luaL_checkany (function argument checking unnecessary) - luaL_checkint (function argument checking unnecessary) - luaL_checkinteger (function argument checking unnecessary) - luaL_checklong (function argument checking unnecessary) - luaL_checklstring (function argument checking unnecessary) - luaL_checknumber (function argument checking unnecessary) - luaL_checkoption (function argument checking unnecessary) - luaL_checkstring (function argument checking unnecessary) - luaL_checktype (function argument checking unnecessary) - luaL_prepbuffer (use System.String concatenation or similar) - luaL_pushresult (use System.String concatenation or similar) - luaL_register (all libs already opened, use require in scripts for external libs) - luaL_typerror (function argument checking unnecessary) - - (complete lua_Debug interface omitted) - lua_gethook*** - lua_getinfo - lua_getlocal - lua_getstack - lua_getupvalue - lua_sethook - lua_setlocal - lua_setupvalue - */ - public class LuaDLL - { - // for debugging - // const string BASEPATH = @"C:\development\software\dotnet\tools\PulseRecognizer\PulseRecognizer\bin\Debug\"; - // const string BASEPATH = @"C:\development\software\ThirdParty\lua\Built\"; - const string LUADLL = "lua51.dll"; - const string LUALIBDLL = LUADLL; - const string STUBDLL = LUADLL; - - // steffenj: BEGIN additional Lua API functions new in Lua 5.1 - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern int lua_gc(IntPtr luaState, LuaGCOptions what, int data); - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern string lua_typename(IntPtr luaState, LuaTypes type); - public static string luaL_typename(IntPtr luaState, int stackPos) - { - return LuaDLL.lua_typename(luaState, LuaDLL.lua_type(luaState, stackPos)); - } - - [DllImport(LUALIBDLL, CallingConvention = CallingConvention.Cdecl)] - public static extern void luaL_error(IntPtr luaState, string message); - [DllImport(LUALIBDLL, CallingConvention = CallingConvention.Cdecl)] - public static extern string luaL_gsub(IntPtr luaState, string str, string pattern, string replacement); - - // the functions below are still untested - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern void lua_getfenv(IntPtr luaState, int stackPos); - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern int lua_isfunction(IntPtr luaState, int stackPos); - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern int lua_islightuserdata(IntPtr luaState, int stackPos); - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern int lua_istable(IntPtr luaState, int stackPos); - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern int lua_isuserdata(IntPtr luaState, int stackPos); - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern int lua_lessthan(IntPtr luaState, int stackPos1, int stackPos2); - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern int lua_rawequal(IntPtr luaState, int stackPos1, int stackPos2); - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern int lua_setfenv(IntPtr luaState, int stackPos); - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern void lua_setfield(IntPtr luaState, int stackPos, string name); - [DllImport(LUALIBDLL, CallingConvention = CallingConvention.Cdecl)] - public static extern int luaL_callmeta(IntPtr luaState, int stackPos, string name); - // steffenj: END additional Lua API functions new in Lua 5.1 - - // steffenj: BEGIN Lua 5.1.1 API change (lua_open replaced by luaL_newstate) - [DllImport(LUALIBDLL, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr luaL_newstate(); - /// DEPRECATED - use luaL_newstate() instead! - public static IntPtr lua_open() - { - return LuaDLL.luaL_newstate(); - } - // steffenj: END Lua 5.1.1 API change (lua_open replaced by luaL_newstate) - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern void lua_close(IntPtr luaState); - // steffenj: BEGIN Lua 5.1.1 API change (new function luaL_openlibs) - [DllImport(LUALIBDLL, CallingConvention = CallingConvention.Cdecl)] - public static extern void luaL_openlibs(IntPtr luaState); - /* - [DllImport(LUALIBDLL, CallingConvention = CallingConvention.Cdecl)] - public static extern void luaopen_base(IntPtr luaState); - [DllImport(LUALIBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void luaopen_io(IntPtr luaState); - [DllImport(LUALIBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void luaopen_table(IntPtr luaState); - [DllImport(LUALIBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void luaopen_string(IntPtr luaState); - [DllImport(LUALIBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void luaopen_math(IntPtr luaState); - [DllImport(LUALIBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void luaopen_debug(IntPtr luaState); - [DllImport(LUALIBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void luaopen_loadlib(IntPtr luaState); - */ - // steffenj: END Lua 5.1.1 API change (new function luaL_openlibs) - // steffenj: BEGIN Lua 5.1.1 API change (lua_strlen is now lua_objlen) - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern int lua_objlen(IntPtr luaState, int stackPos); - /// DEPRECATED - use lua_objlen(IntPtr luaState, int stackPos) instead! - public static int lua_strlen(IntPtr luaState, int stackPos) - { - return lua_objlen(luaState, stackPos); - } - // steffenj: END Lua 5.1.1 API change (lua_strlen is now lua_objlen) - // steffenj: BEGIN Lua 5.1.1 API change (lua_dostring is now a macro luaL_dostring) - [DllImport(LUALIBDLL, CallingConvention = CallingConvention.Cdecl)] - public static extern int luaL_loadstring(IntPtr luaState, string chunk); - public static int luaL_dostring(IntPtr luaState, string chunk) - { - int result = LuaDLL.luaL_loadstring(luaState, chunk); - if (result != 0) - return result; - - return LuaDLL.lua_pcall(luaState, 0, -1, 0); - } - /// DEPRECATED - use luaL_dostring(IntPtr luaState, string chunk) instead! - public static int lua_dostring(IntPtr luaState, string chunk) - { - return LuaDLL.luaL_dostring(luaState, chunk); - } - // steffenj: END Lua 5.1.1 API change (lua_dostring is now a macro luaL_dostring) - // steffenj: BEGIN Lua 5.1.1 API change (lua_newtable is gone, lua_createtable is new) - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern void lua_createtable(IntPtr luaState, int narr, int nrec); - public static void lua_newtable(IntPtr luaState) - { - LuaDLL.lua_createtable(luaState, 0, 0); - } - // steffenj: END Lua 5.1.1 API change (lua_newtable is gone, lua_createtable is new) - // steffenj: BEGIN Lua 5.1.1 API change (lua_dofile now in LuaLib as luaL_dofile macro) - //[DllImport(LUALIBDLL, CallingConvention = CallingConvention.Cdecl)] - public static int luaL_dofile(IntPtr luaState, string fileName) - { - int result = LuaDLL.luaL_loadfile(luaState, fileName); - if (result != 0) - return result; - - return LuaDLL.lua_pcall(luaState, 0, -1, 0); - } - // steffenj: END Lua 5.1.1 API change (lua_dofile now in LuaLib as luaL_dofile) - public static void lua_getglobal(IntPtr luaState, string name) - { - LuaDLL.lua_pushstring(luaState,name); - LuaDLL.lua_gettable(luaState,LuaIndexes.LUA_GLOBALSINDEX); - } - public static void lua_setglobal(IntPtr luaState, string name) - { - LuaDLL.lua_pushstring(luaState,name); - LuaDLL.lua_insert(luaState,-2); - LuaDLL.lua_settable(luaState,LuaIndexes.LUA_GLOBALSINDEX); - } - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_settop(IntPtr luaState, int newTop); - // steffenj: BEGIN added lua_pop "macro" - public static void lua_pop(IntPtr luaState, int amount) - { - LuaDLL.lua_settop(luaState, -(amount) - 1); - } - // steffenj: END added lua_pop "macro" - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern void lua_insert(IntPtr luaState, int newTop); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_remove(IntPtr luaState, int index); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_gettable(IntPtr luaState, int index); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_rawget(IntPtr luaState, int index); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_settable(IntPtr luaState, int index); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_rawset(IntPtr luaState, int index); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_setmetatable(IntPtr luaState, int objIndex); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int lua_getmetatable(IntPtr luaState, int objIndex); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int lua_equal(IntPtr luaState, int index1, int index2); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_pushvalue(IntPtr luaState, int index); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_replace(IntPtr luaState, int index); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int lua_gettop(IntPtr luaState); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern LuaTypes lua_type(IntPtr luaState, int index); - public static bool lua_isnil(IntPtr luaState, int index) - { - return (LuaDLL.lua_type(luaState,index)==LuaTypes.LUA_TNIL); - } - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern bool lua_isnumber(IntPtr luaState, int index); - public static bool lua_isboolean(IntPtr luaState, int index) - { - return LuaDLL.lua_type(luaState,index)==LuaTypes.LUA_TBOOLEAN; - } - [DllImport(LUALIBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int luaL_ref(IntPtr luaState, int registryIndex); - public static int lua_ref(IntPtr luaState, int lockRef) - { - if(lockRef!=0) - { - return LuaDLL.luaL_ref(luaState,LuaIndexes.LUA_REGISTRYINDEX); - } - else return 0; - } - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_rawgeti(IntPtr luaState, int tableIndex, int index); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_rawseti(IntPtr luaState, int tableIndex, int index); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern IntPtr lua_newuserdata(IntPtr luaState, int size); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern IntPtr lua_touserdata(IntPtr luaState, int index); - public static void lua_getref(IntPtr luaState, int reference) - { - LuaDLL.lua_rawgeti(luaState,LuaIndexes.LUA_REGISTRYINDEX,reference); - } - [DllImport(LUALIBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void luaL_unref(IntPtr luaState, int registryIndex, int reference); - public static void lua_unref(IntPtr luaState, int reference) - { - LuaDLL.luaL_unref(luaState,LuaIndexes.LUA_REGISTRYINDEX,reference); - } - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern bool lua_isstring(IntPtr luaState, int index); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern bool lua_iscfunction(IntPtr luaState, int index); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_pushnil(IntPtr luaState); - [DllImport(STUBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_pushstdcallcfunction(IntPtr luaState, [MarshalAs(UnmanagedType.FunctionPtr)]LuaCSFunction function); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int lua_call(IntPtr luaState, int nArgs, int nResults); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int lua_pcall(IntPtr luaState, int nArgs, int nResults, int errfunc); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int lua_rawcall(IntPtr luaState, int nArgs, int nResults); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern IntPtr lua_tocfunction(IntPtr luaState, int index); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern double lua_tonumber(IntPtr luaState, int index); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern bool lua_toboolean(IntPtr luaState, int index); - - [DllImport(LUADLL,CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr lua_tolstring(IntPtr luaState, int index, out int strLen); - - public static string lua_tostring(IntPtr luaState, int index) - { - int strlen; - - IntPtr str = lua_tolstring(luaState, index, out strlen); - if (str != IntPtr.Zero) - return Marshal.PtrToStringAnsi(str, strlen); - else - return null; // treat lua nulls to as C# nulls - } - - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern void lua_atpanic(IntPtr luaState, LuaFunctionCallback panicf); - - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_pushnumber(IntPtr luaState, double number); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_pushboolean(IntPtr luaState, bool value); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_pushlstring(IntPtr luaState, string str, int size); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_pushstring(IntPtr luaState, string str); - [DllImport(LUALIBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int luaL_newmetatable(IntPtr luaState, string meta); - // steffenj: BEGIN Lua 5.1.1 API change (luaL_getmetatable is now a macro using lua_getfield) - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern void lua_getfield(IntPtr luaState, int stackPos, string meta); - public static void luaL_getmetatable(IntPtr luaState, string meta) - { - LuaDLL.lua_getfield(luaState, LuaIndexes.LUA_REGISTRYINDEX, meta); - } - // steffenj: END Lua 5.1.1 API change (luaL_getmetatable is now a macro using lua_getfield) - [DllImport(LUALIBDLL, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr luaL_checkudata(IntPtr luaState, int stackPos, string meta); - [DllImport(LUALIBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern bool luaL_getmetafield(IntPtr luaState, int stackPos, string field); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int lua_load(IntPtr luaState, LuaChunkReader chunkReader, ref ReaderInfo data, string chunkName); - [DllImport(LUALIBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int luaL_loadbuffer(IntPtr luaState, string buff, int size, string name); - [DllImport(LUALIBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int luaL_loadfile(IntPtr luaState, string filename); - [DllImport(STUBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern bool luaL_checkmetatable(IntPtr luaState,int obj); - [DllImport(STUBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int luanet_tonetobject(IntPtr luaState,int obj); - [DllImport(STUBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int luanet_newudata(IntPtr luaState,int val); - [DllImport(STUBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int luanet_rawnetobj(IntPtr luaState,int obj); - [DllImport(STUBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int luanet_checkudata(IntPtr luaState,int obj,string meta); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_error(IntPtr luaState); - [DllImport(LUADLL, CallingConvention = CallingConvention.Cdecl)] - public static extern bool lua_checkstack(IntPtr luaState,int extra); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern int lua_next(IntPtr luaState,int index); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void lua_pushlightuserdata(IntPtr luaState, IntPtr udata); - [DllImport(STUBDLL,CallingConvention=CallingConvention.Cdecl)] - public static extern IntPtr luanet_gettag(); - [DllImport(LUADLL,CallingConvention=CallingConvention.Cdecl)] - public static extern void luaL_where (IntPtr luaState, int level); - } -} diff --git a/LuaInterface/LuaException.cs b/LuaInterface/LuaException.cs deleted file mode 100644 index 1393e6a989..0000000000 --- a/LuaInterface/LuaException.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace LuaInterface -{ - /// - /// Exceptions thrown by the Lua runtime - /// - [Serializable] - public class LuaException : Exception - { - public LuaException() - {} - - public LuaException(string message) : base(message) - {} - - public LuaException(string message, Exception innerException) : base(message, innerException) - {} - - protected LuaException(SerializationInfo info, StreamingContext context) : base(info, context) - {} - - public override string ToString() - { - return Message; - } - } -} diff --git a/LuaInterface/LuaFunction.cs b/LuaInterface/LuaFunction.cs deleted file mode 100644 index 2ef89a1ab4..0000000000 --- a/LuaInterface/LuaFunction.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace LuaInterface -{ - public class LuaFunction : LuaBase - { - //private Lua interpreter; - internal LuaCSFunction function; - //internal int reference; - - public LuaFunction(int reference, Lua interpreter) - { - _Reference = reference; - this.function = null; - _Interpreter = interpreter; - } - - public LuaFunction(LuaCSFunction function, Lua interpreter) - { - _Reference = 0; - this.function = function; - _Interpreter = interpreter; - } - - //~LuaFunction() - //{ - // if (reference != 0) - // interpreter.dispose(reference); - //} - - //bool disposed = false; - //~LuaFunction() - //{ - // Dispose(false); - //} - - //public void Dispose() - //{ - // Dispose(true); - // GC.SuppressFinalize(this); - //} - - //public virtual void Dispose(bool disposeManagedResources) - //{ - // if (!this.disposed) - // { - // if (disposeManagedResources) - // { - // if (_Reference != 0) - // _Interpreter.dispose(_Reference); - // } - - // disposed = true; - // } - //} - - - /* - * 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(IntPtr luaState) - { - if (_Reference != 0) - LuaDLL.lua_getref(luaState, _Reference); - else - _Interpreter.pushCSFunction(function); - } - public override string ToString() - { - return "function"; - } - public override bool Equals(object o) - { - if (o is LuaFunction) - { - LuaFunction 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() - { - if (_Reference != 0) - // elisee: Used to return _Reference - // which doesn't make sense as you can have different refs - // to the same function - return 0; - else - return function.GetHashCode(); - } - } - -} diff --git a/LuaInterface/LuaGlobalAttribute.cs b/LuaInterface/LuaGlobalAttribute.cs deleted file mode 100644 index f444f10ec1..0000000000 --- a/LuaInterface/LuaGlobalAttribute.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; - -namespace LuaInterface -{ - /// - /// Marks a method for global usage in Lua scripts - /// - /// - /// - [AttributeUsage(AttributeTargets.Method)] - public sealed class LuaGlobalAttribute : Attribute - { - /// - /// An alternative name to use for calling the function in Lua - leave empty for CLR name - /// - public string Name { get; set; } - - /// - /// A description of the function - /// - public string Description { get; set; } - } -} diff --git a/LuaInterface/LuaHideAttribute.cs b/LuaInterface/LuaHideAttribute.cs deleted file mode 100644 index 854f5de78b..0000000000 --- a/LuaInterface/LuaHideAttribute.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace LuaInterface -{ - /// - /// Marks a method, field or property to be hidden from Lua auto-completion - /// - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] - public sealed class LuaHideAttribute : Attribute - {} -} diff --git a/LuaInterface/LuaInterface.csproj b/LuaInterface/LuaInterface.csproj deleted file mode 100644 index 9098fd212a..0000000000 --- a/LuaInterface/LuaInterface.csproj +++ /dev/null @@ -1,47 +0,0 @@ - - - - {E915A0A4-2641-4F7E-8A88-8F123FA88BF1} - v3.5 - Client - - - ..\ - - - Library - - - - - - - - - - - - - - - - - - - - - - - - - - - - {bdaeab25-991e-46a7-af1e-4f0e03358daa} - OpenRA.FileFormats - - - - - - \ No newline at end of file diff --git a/LuaInterface/LuaRegistrationHelper.cs b/LuaInterface/LuaRegistrationHelper.cs deleted file mode 100644 index 9e3fc0fa5a..0000000000 --- a/LuaInterface/LuaRegistrationHelper.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Reflection; - -namespace LuaInterface -{ - public static class LuaRegistrationHelper - { - #region Tagged instance methods - /// - /// Registers all public instance methods in an object tagged with as Lua global functions - /// - /// The Lua VM to add the methods to - /// The object to get the methods from - 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 (MethodInfo 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 - /// - /// Registers all public static methods in a class tagged with as Lua global functions - /// - /// The Lua VM to add the methods to - /// The class type to get the methods from - 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 (MethodInfo 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 - /// - /// Registers an enumeration's values for usage as a Lua variable table - /// - /// The enum type to register - /// The Lua VM to add the enum to - [SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "The type parameter is used to select an enum type")] - public static void Enumeration(Lua lua) - { - #region Sanity checks - if (lua == null) throw new ArgumentNullException("lua"); - #endregion - - Type type = typeof(T); - if (!type.IsEnum) throw new ArgumentException("The type must be an enumeration!"); - - string[] names = Enum.GetNames(type); - T[] values = (T[])Enum.GetValues(type); - - lua.NewTable(type.Name); - for (int i = 0; i < names.Length; i++) - { - string path = type.Name + "." + names[i]; - lua[path] = values[i]; - } - } - #endregion - } -} diff --git a/LuaInterface/LuaScriptException.cs b/LuaInterface/LuaScriptException.cs deleted file mode 100644 index 6b45a0ca7e..0000000000 --- a/LuaInterface/LuaScriptException.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; - -namespace LuaInterface -{ - /// - /// Exceptions thrown by the Lua runtime because of errors in the script - /// - public class LuaScriptException : LuaException - { - /// - /// Returns true if the exception has occured as the result of a .NET exception in user code - /// - public bool IsNetException { get; private set; } - - private readonly string source; - - /// - /// The position in the script where the exception was triggered. - /// - public override string Source { get { return source; } } - - /// - /// Creates a new Lua-only exception. - /// - /// The message that describes the error. - /// The position in the script where the exception was triggered. - public LuaScriptException(string message, string source) : base(message) - { - this.source = source; - } - - /// - /// Creates a new .NET wrapping exception. - /// - /// The .NET exception triggered by user-code. - /// The position in the script where the exception was triggered. - public LuaScriptException(Exception innerException, string source) - : base(innerException.Message, innerException) - { - this.source = source; - this.IsNetException = true; - } - - public override string ToString() - { - // Prepend the error source - return GetType().FullName + ": " + source + Message; - } - } -} diff --git a/LuaInterface/LuaTable.cs b/LuaInterface/LuaTable.cs deleted file mode 100644 index d9fb67c47d..0000000000 --- a/LuaInterface/LuaTable.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Collections; - -namespace LuaInterface -{ - /* - * Wrapper class for Lua tables - * - * Author: Fabio Mascarenhas - * Version: 1.0 - */ - public class LuaTable : LuaBase - { - public bool IsOrphaned; - - //internal int _Reference; - //private Lua _Interpreter; - public LuaTable(int reference, Lua interpreter) - { - _Reference = reference; - _Interpreter = interpreter; - } - - //bool disposed = false; - //~LuaTable() - //{ - // Dispose(false); - //} - - //public void Dispose() - //{ - // Dispose(true); - // GC.SuppressFinalize(this); - //} - - //public virtual void Dispose(bool disposeManagedResources) - //{ - // if (!this.disposed) - // { - // if (disposeManagedResources) - // { - // if (_Reference != 0) - // _Interpreter.dispose(_Reference); - // } - - // disposed = true; - // } - //} - //~LuaTable() - //{ - // _Interpreter.dispose(_Reference); - //} - /* - * 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); - } - - internal object rawgetFunction(string field) - { - object obj = _Interpreter.rawGetObject(_Reference, field); - - if (obj is LuaCSFunction) - return new LuaFunction((LuaCSFunction)obj, _Interpreter); - else - return obj; - } - - /* - * Pushes this table into the Lua stack - */ - internal void push(IntPtr luaState) - { - LuaDLL.lua_getref(luaState, _Reference); - } - public override string ToString() - { - return "table"; - } - - //public override bool Equals(object o) - //{ - // if (o is LuaTable) - // { - // LuaTable l = (LuaTable)o; - // return _Interpreter.compareRef(l._Reference, _Reference); - // } - // else return false; - //} - //public override int GetHashCode() - //{ - // return _Reference; - //} - } -} diff --git a/LuaInterface/LuaUserData.cs b/LuaInterface/LuaUserData.cs deleted file mode 100644 index 17b3e75505..0000000000 --- a/LuaInterface/LuaUserData.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace LuaInterface -{ - public class LuaUserData : LuaBase - { - //internal int _Reference; - //private Lua _Interpreter; - public LuaUserData(int reference, Lua interpreter) - { - _Reference = reference; - _Interpreter = interpreter; - } - //~LuaUserData() - //{ - // if (_Reference != 0) - // _Interpreter.dispose(_Reference); - //} - /* - * 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); - } - /* - * Pushes the userdata into the Lua stack - */ - internal void push(IntPtr luaState) - { - LuaDLL.lua_getref(luaState, _Reference); - } - public override string ToString() - { - return "userdata"; - } - //public override bool Equals(object o) - //{ - // if (o is LuaUserData) - // { - // LuaUserData l = (LuaUserData)o; - // return _Interpreter.compareRef(l._Reference, _Reference); - // } - // else return false; - //} - //public override int GetHashCode() - //{ - // return _Reference; - //} - } -} diff --git a/LuaInterface/Metatables.cs b/LuaInterface/Metatables.cs deleted file mode 100644 index 630ea6791e..0000000000 --- a/LuaInterface/Metatables.cs +++ /dev/null @@ -1,935 +0,0 @@ -namespace LuaInterface -{ - using System; - using System.IO; - using System.Collections; - using System.Reflection; - using System.Diagnostics; - using System.Collections.Generic; - using System.Runtime.InteropServices; - - /* - * Functions used in the metatables of userdata representing - * CLR objects - * - * Author: Fabio Mascarenhas - * Version: 1.0 - */ - class MetaFunctions - { - /* - * __index metafunction for CLR objects. Implemented in Lua. - */ - internal static string luaIndexFunction = - @" - local function index(obj,name) - local meta=getmetatable(obj) - local cached=meta.cache[name] - if cached then - return cached - else - local value,isFunc = get_object_member(obj,name) - if value==nil and type(isFunc)=='string' then error(isFunc,2) end - if isFunc then - meta.cache[name]=value - end - return value - end - end - return index"; - - private ObjectTranslator translator; - private Hashtable memberCache = new Hashtable(); - internal LuaCSFunction gcFunction, indexFunction, newindexFunction, - baseIndexFunction, classIndexFunction, classNewindexFunction, - execDelegateFunction, callConstructorFunction, toStringFunction; - - public MetaFunctions(ObjectTranslator translator) - { - this.translator = translator; - gcFunction = new LuaCSFunction(this.collectObject); - toStringFunction = new LuaCSFunction(this.toString); - indexFunction = new LuaCSFunction(this.getMethod); - newindexFunction = new LuaCSFunction(this.setFieldOrProperty); - baseIndexFunction = new LuaCSFunction(this.getBaseMethod); - callConstructorFunction = new LuaCSFunction(this.callConstructor); - classIndexFunction = new LuaCSFunction(this.getClassMethod); - classNewindexFunction = new LuaCSFunction(this.setClassFieldOrProperty); - execDelegateFunction = new LuaCSFunction(this.runFunctionDelegate); - } - - /* - * __call metafunction of CLR delegates, retrieves and calls the delegate. - */ - private int runFunctionDelegate(IntPtr luaState) - { - LuaCSFunction func = (LuaCSFunction)translator.getRawNetObject(luaState, 1); - LuaDLL.lua_remove(luaState, 1); - return func(luaState); - } - /* - * __gc metafunction of CLR objects. - */ - private int collectObject(IntPtr luaState) - { - int udata = LuaDLL.luanet_rawnetobj(luaState, 1); - if (udata != -1) - { - translator.collectObject(udata); - } - else - { - // Debug.WriteLine("not found: " + udata); - } - return 0; - } - /* - * __tostring metafunction of CLR objects. - */ - private int toString(IntPtr luaState) - { - object obj = translator.getRawNetObject(luaState, 1); - if (obj != null) - { - translator.push(luaState, obj.ToString() + ": " + obj.GetHashCode()); - } - else LuaDLL.lua_pushnil(luaState); - return 1; - } - - - /// - /// Debug tool to dump the lua stack - /// - /// FIXME, move somewhere else - public static void dumpStack(ObjectTranslator translator, IntPtr luaState) - { - int depth = LuaDLL.lua_gettop(luaState); - - Debug.WriteLine("lua stack depth: " + depth); - for (int i = 1; i <= depth; i++) - { - LuaTypes type = LuaDLL.lua_type(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.LUA_TTABLE) ? "table" : LuaDLL.lua_typename(luaState, type); - - string strrep = LuaDLL.lua_tostring(luaState, i); - if (type == LuaTypes.LUA_TUSERDATA) - { - object obj = translator.getRawNetObject(luaState, i); - strrep = obj.ToString(); - } - - Debug.Print("{0}: ({1}) {2}", i, typestr, strrep); - } - } - - /* - * 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. - */ - private int getMethod(IntPtr luaState) - { - object obj = translator.getRawNetObject(luaState, 1); - if (obj == null) - { - translator.throwError(luaState, "trying to index an invalid object reference"); - LuaDLL.lua_pushnil(luaState); - return 1; - } - - object index = translator.getObject(luaState, 2); - - string methodName = index as string; // will be null if not a string arg - Type objType = obj.GetType(); - - // 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 (methodName != null && isMemberPresent(objType, methodName)) - return getMember(luaState, objType, obj, methodName, BindingFlags.Instance | BindingFlags.IgnoreCase); - } - catch { } - bool failed = true; - - // 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); - Array aa = obj as Array; - if (intIndex >= aa.Length) { - return translator.pushError(luaState,"array index out of bounds: "+intIndex + " " + aa.Length); - } - object val = aa.GetValue(intIndex); - translator.push (luaState,val); - failed = false; - } - else - { - // Try to use get_Item to index into this .net object - //MethodInfo getter = objType.GetMethod("get_Item"); - // issue here is that there may be multiple indexers.. - MethodInfo[] methods = objType.GetMethods(); - - foreach (MethodInfo mInfo in methods) - { - if (mInfo.Name == "get_Item") - { - //check if the signature matches the input - if (mInfo.GetParameters().Length == 1) - { - MethodInfo getter = mInfo; - ParameterInfo[] actualParms = (getter != null) ? getter.GetParameters() : null; - if (actualParms == null || actualParms.Length != 1) - { - return translator.pushError(luaState, "method not found (or no indexer): " + index); - } - else - { - // Get the index in a form acceptable to the getter - index = translator.getAsType(luaState, 2, actualParms[0].ParameterType); - // Just call the indexer - if out of bounds an exception will happen - try - { - object result = getter.Invoke(obj, new object[]{index}); - translator.push(luaState, result); - failed = false; - } - catch (TargetInvocationException e) - { - // Provide a more readable description for the common case of key not found - if (e.InnerException is KeyNotFoundException) - return translator.pushError(luaState, "key '" + index + "' not found "); - else - return translator.pushError(luaState, "exception indexing '" + index + "' " + e.Message); - - - } - } - } - } - } - - - } - if (failed) { - return translator.pushError(luaState,"cannot find " + index); - } - LuaDLL.lua_pushboolean(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. - */ - private int getBaseMethod(IntPtr luaState) - { - object obj = translator.getRawNetObject(luaState, 1); - if (obj == null) - { - translator.throwError(luaState, "trying to index an invalid object reference"); - LuaDLL.lua_pushnil(luaState); - LuaDLL.lua_pushboolean(luaState, false); - return 2; - } - string methodName = LuaDLL.lua_tostring(luaState, 2); - if (methodName == null) - { - LuaDLL.lua_pushnil(luaState); - LuaDLL.lua_pushboolean(luaState, false); - return 2; - } - getMember(luaState, obj.GetType(), obj, "__luaInterface_base_" + methodName, BindingFlags.Instance | BindingFlags.IgnoreCase); - LuaDLL.lua_settop(luaState, -2); - if (LuaDLL.lua_type(luaState, -1) == LuaTypes.LUA_TNIL) - { - LuaDLL.lua_settop(luaState, -2); - return getMember(luaState, obj.GetType(), obj, methodName, BindingFlags.Instance | BindingFlags.IgnoreCase); - } - LuaDLL.lua_pushboolean(luaState, false); - return 2; - } - - - /// - /// Does this method exist as either an instance or static? - /// - /// - /// - /// - bool isMemberPresent(IReflect objType, string methodName) - { - object cachedMember = checkMemberCache(memberCache, objType, methodName); - - if (cachedMember != null) - return true; - - //CP: Removed NonPublic binding search - MemberInfo[] members = objType.GetMember(methodName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.IgnoreCase/* | BindingFlags.NonPublic*/); - return (members.Length > 0); - } - - /* - * 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). - */ - private int getMember(IntPtr luaState, IReflect objType, object obj, string methodName, BindingFlags bindingType) - { - bool implicitStatic = false; - MemberInfo member = null; - object cachedMember = checkMemberCache(memberCache, objType, methodName); - //object cachedMember=null; - if (cachedMember is LuaCSFunction) - { - translator.pushFunction(luaState, (LuaCSFunction)cachedMember); - translator.push(luaState, true); - return 2; - } - else if (cachedMember != null) - { - member = (MemberInfo)cachedMember; - } - else - { - //CP: Removed NonPublic binding search - MemberInfo[] members = objType.GetMember(methodName, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*| BindingFlags.NonPublic*/); - 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 - // lookups for fields/properties/events -kevinh - //CP: Removed NonPublic binding search and made case insensitive - members = objType.GetMember(methodName, bindingType | BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase/*| BindingFlags.NonPublic*/); - - if (members.Length > 0) - { - member = members[0]; - implicitStatic = true; - } - } - } - if (member != null) - { - if (member.MemberType == MemberTypes.Field) - { - FieldInfo field = (FieldInfo)member; - if (cachedMember == null) setMemberCache(memberCache, objType, methodName, member); - try - { - translator.push(luaState, field.GetValue(obj)); - } - catch - { - LuaDLL.lua_pushnil(luaState); - } - } - else if (member.MemberType == MemberTypes.Property) - { - PropertyInfo property = (PropertyInfo)member; - if (cachedMember == null) setMemberCache(memberCache, objType, methodName, member); - try - { - object val = property.GetValue(obj, null); - - translator.push(luaState, val); - } - 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 is Type && !(((Type)objType) == typeof(object))) - return getMember(luaState, ((Type)objType).BaseType, obj, methodName, bindingType); - else - LuaDLL.lua_pushnil(luaState); - } - catch (TargetInvocationException e) // Convert this exception into a Lua error - { - ThrowError(luaState, e); - LuaDLL.lua_pushnil(luaState); - } - } - else if (member.MemberType == MemberTypes.Event) - { - EventInfo eventInfo = (EventInfo)member; - if (cachedMember == null) setMemberCache(memberCache, objType, methodName, member); - translator.push(luaState, new RegisterEventHandler(translator.pendingEvents, obj, eventInfo)); - } - else if (!implicitStatic) - { - if (member.MemberType == MemberTypes.NestedType) - { - // 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; - Type dectype = member.DeclaringType; - - // Build a new long name and try to find the type by name - string longname = dectype.FullName + "+" + name; - Type nestedType = translator.FindType(longname); - - translator.pushType(luaState, nestedType); - } - else - { - // Member type must be 'method' - LuaCSFunction wrapper = new LuaCSFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call); - - 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); - - LuaDLL.lua_pushnil(luaState); - } - } - else - { - // 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); - - LuaDLL.lua_pushnil(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. - */ - private object checkMemberCache(Hashtable memberCache, IReflect objType, string memberName) - { - Hashtable members = (Hashtable)memberCache[objType]; - if (members != null) - return members[memberName]; - else - return null; - } - /* - * Stores a MemberInfo object in the member cache. - */ - private void setMemberCache(Hashtable memberCache, IReflect objType, string memberName, object member) - { - Hashtable members = (Hashtable)memberCache[objType]; - if (members == null) - { - members = new Hashtable(); - 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. - */ - private int setFieldOrProperty(IntPtr luaState) - { - object target = translator.getRawNetObject(luaState, 1); - if (target == null) - { - translator.throwError(luaState, "trying to index and invalid object reference"); - return 0; - } - Type type = target.GetType(); - - // First try to look up the parameter as a property name - string detailMessage; - bool didMember = trySetMember(luaState, type, target, BindingFlags.Instance | BindingFlags.IgnoreCase, 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 && LuaDLL.lua_isnumber(luaState, 2)) - { - int index = (int)LuaDLL.lua_tonumber(luaState, 2); - - Array 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 - MethodInfo setter = type.GetMethod("set_Item"); - if (setter != null) - { - ParameterInfo[] args = setter.GetParameters(); - Type valueType = args[1].ParameterType; - - // The new val ue the user specified - object val = translator.getAsType(luaState, 3, valueType); - - Type 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 - } - } - } - catch (SEHException) - { - // If we are seeing a C++ exception - this must actually be for Lua's private use. Let it handle it - throw; - } - catch (Exception e) - { - ThrowError(luaState, e); - } - return 0; - } - - /// - /// Tries to set a named property or field - /// - /// - /// - /// - /// - /// false if unable to find the named member, true for success - private bool trySetMember(IntPtr luaState, IReflect 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 (LuaDLL.lua_type(luaState, 2) != LuaTypes.LUA_TSTRING) - { - detailMessage = "property names must be strings"; - return false; - } - - // We only look up property names by string - string fieldName = LuaDLL.lua_tostring(luaState, 2); - 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 - MemberInfo member = (MemberInfo)checkMemberCache(memberCache, targetType, fieldName); - if (member == null) - { - //CP: Removed NonPublic binding search and made case insensitive - MemberInfo[] members = targetType.GetMember(fieldName, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*| BindingFlags.NonPublic*/); - if (members.Length > 0) - { - member = members[0]; - setMemberCache(memberCache, targetType, fieldName, member); - } - else - { - detailMessage = "field or property '" + fieldName + "' does not exist"; - return false; - } - } - - if (member.MemberType == MemberTypes.Field) - { - FieldInfo 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; - } - else if (member.MemberType == MemberTypes.Property) - { - PropertyInfo 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(IntPtr luaState, IReflect targetType, object target, BindingFlags bindingType) - { - string detail; - bool success = trySetMember(luaState, targetType, target, bindingType, out detail); - - if (!success) - translator.throwError(luaState, detail); - - return 0; - } - - /// - /// Convert a C# exception into a Lua error - /// - /// - /// We try to look into the exception to give the most meaningful description - void ThrowError(IntPtr luaState, Exception e) - { - // If we got inside a reflection show what really happened - TargetInvocationException te = e as TargetInvocationException; - - if (te != null) - e = te.InnerException; - - translator.throwError(luaState, e); - } - - /* - * __index metafunction of type references, works on static members. - */ - private int getClassMethod(IntPtr luaState) - { - IReflect klass; - object obj = translator.getRawNetObject(luaState, 1); - if (obj == null || !(obj is IReflect)) - { - translator.throwError(luaState, "trying to index an invalid type reference"); - LuaDLL.lua_pushnil(luaState); - return 1; - } - else klass = (IReflect)obj; - if (LuaDLL.lua_isnumber(luaState, 2)) - { - int size = (int)LuaDLL.lua_tonumber(luaState, 2); - translator.push(luaState, Array.CreateInstance(klass.UnderlyingSystemType, size)); - return 1; - } - else - { - string methodName = LuaDLL.lua_tostring(luaState, 2); - if (methodName == null) - { - LuaDLL.lua_pushnil(luaState); - return 1; - } //CP: Ignore case - else return getMember(luaState, klass, null, methodName, BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.IgnoreCase); - } - } - /* - * __newindex function of type references, works on static members. - */ - private int setClassFieldOrProperty(IntPtr luaState) - { - IReflect target; - object obj = translator.getRawNetObject(luaState, 1); - if (obj == null || !(obj is IReflect)) - { - translator.throwError(luaState, "trying to index an invalid type reference"); - return 0; - } - else target = (IReflect)obj; - return setMember(luaState, target, null, BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.IgnoreCase); - } - /* - * __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. - */ - private int callConstructor(IntPtr luaState) - { - MethodCache validConstructor = new MethodCache(); - IReflect klass; - object obj = translator.getRawNetObject(luaState, 1); - if (obj == null || !(obj is IReflect)) - { - translator.throwError(luaState, "trying to call constructor on an invalid type reference"); - LuaDLL.lua_pushnil(luaState); - return 1; - } - else klass = (IReflect)obj; - LuaDLL.lua_remove(luaState, 1); - ConstructorInfo[] constructors = klass.UnderlyingSystemType.GetConstructors(); - foreach (ConstructorInfo 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); - LuaDLL.lua_pushnil(luaState); - } - catch - { - LuaDLL.lua_pushnil(luaState); - } - 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)); - LuaDLL.lua_pushnil(luaState); - return 1; - } - - private static bool IsInteger(double x) { - return Math.Ceiling(x) == x; - } - - - internal Array TableToArray(object luaParamValue, Type paramArrayType) { - Array paramArray; - - 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 o = tableEnumerator.Value; - if (paramArrayType == typeof(object)) { - if (o != null && o.GetType() == typeof(double) && IsInteger((double)o)) - o = Convert.ToInt32((double)o); - } - paramArray.SetValue(Convert.ChangeType(o, paramArrayType), paramArrayIndex); - paramArrayIndex++; - } - } else { - paramArray = Array.CreateInstance(paramArrayType, 1); - paramArray.SetValue(luaParamValue, 0); - } - - return paramArray; - - } - - /* - * Matches a method against its arguments in the Lua stack. Returns - * if the match was succesful. It it was also returns the information - * necessary to invoke the method. - */ - internal bool matchParameters(IntPtr luaState, MethodBase method, ref MethodCache methodCache) - { - ExtractValue extractValue; - bool isMethod = true; - ParameterInfo[] paramInfo = method.GetParameters(); - int currentLuaParam = 1; - int nLuaParams = LuaDLL.lua_gettop(luaState); - ArrayList paramList = new ArrayList(); - List outList = new List(); - List argTypes = new List(); - foreach (ParameterInfo currentNetParam in paramInfo) - { - if (!currentNetParam.IsIn && currentNetParam.IsOut) // Skips out params - { - outList.Add(paramList.Add(null)); - } - else if (currentLuaParam > nLuaParams) // Adds optional parameters - { - if (currentNetParam.IsOptional) - { - paramList.Add(currentNetParam.DefaultValue); - } - else - { - isMethod = false; - break; - } - } - else if (_IsTypeCorrect(luaState, currentLuaParam, currentNetParam, out extractValue)) // Type checking - { - int index = paramList.Add(extractValue(luaState, currentLuaParam)); - - MethodArgs methodArg = new MethodArgs(); - methodArg.index = index; - methodArg.extractValue = extractValue; - argTypes.Add(methodArg); - - if (currentNetParam.ParameterType.IsByRef) - outList.Add(index); - currentLuaParam++; - } // Type does not match, ignore if the parameter is optional - else if (_IsParamsArray(luaState, currentLuaParam, currentNetParam, out extractValue)) - { - object luaParamValue = extractValue(luaState, currentLuaParam); - Type paramArrayType = currentNetParam.ParameterType.GetElementType(); - - Array paramArray = TableToArray(luaParamValue, paramArrayType); - int index = paramList.Add(paramArray); - - MethodArgs methodArg = new MethodArgs(); - methodArg.index = index; - methodArg.extractValue = extractValue; - methodArg.isParamsArray = true; - methodArg.paramsArrayType = paramArrayType; - argTypes.Add(methodArg); - - currentLuaParam++; - } - 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; - } - - /// - /// CP: Fix for operator overloading failure - /// Returns true if the type is set and assigns the extract value - /// - /// - /// - /// - /// - /// - private bool _IsTypeCorrect(IntPtr luaState, int currentLuaParam, ParameterInfo currentNetParam, out ExtractValue extractValue) - { - try - { - return (extractValue = translator.typeChecker.checkType(luaState, currentLuaParam, currentNetParam.ParameterType)) != null; - } - catch - { - extractValue = null; - Debug.WriteLine("Type wasn't correct"); - return false; - } - } - - private bool _IsParamsArray(IntPtr luaState, int currentLuaParam, ParameterInfo currentNetParam, out ExtractValue extractValue) - { - extractValue = null; - - if (currentNetParam.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0) - { - LuaTypes luaType; - - try - { - luaType = LuaDLL.lua_type(luaState, currentLuaParam); - } - catch (Exception ex) - { - Debug.WriteLine("Could not retrieve lua type while attempting to determine params Array Status."+ ex.ToString()); - Debug.WriteLine(ex.Message); - extractValue = null; - return false; - } - - if (luaType == LuaTypes.LUA_TTABLE) - { - 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." + ex.ToString()); - } - - if (extractValue != null) - { - return true; - } - } - else - { - Type paramElementType = currentNetParam.ParameterType.GetElementType(); - - try - { - extractValue = translator.typeChecker.checkType(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:{1}", paramElementType.FullName,ex.ToString())); - } - - if (extractValue != null) - { - return true; - } - } - } - - Debug.WriteLine("Type wasn't Params object."); - - return false; - } - } -} diff --git a/LuaInterface/MethodWrapper.cs b/LuaInterface/MethodWrapper.cs deleted file mode 100644 index f572420729..0000000000 --- a/LuaInterface/MethodWrapper.cs +++ /dev/null @@ -1,595 +0,0 @@ -namespace LuaInterface -{ - using System; - using System.IO; - using System.Collections; - using System.Reflection; - using System.Collections.Generic; - using System.Diagnostics; - - /* - * Cached method - */ - struct MethodCache - { - private MethodBase _cachedMethod; - - public MethodBase cachedMethod - { - get - { - return _cachedMethod; - } - set - { - _cachedMethod = value; - MethodInfo mi = value as MethodInfo; - if (mi != null) - { - //SJD this is guaranteed to be correct irrespective of actual name used for type.. - 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; - } - - /* - * Parameter information - */ - struct MethodArgs - { - // Position of parameter - public int index; - // Type-conversion function - public ExtractValue extractValue; - - public bool isParamsArray; - - public Type paramsArrayType; - } - - /* - * Argument extraction with type-conversion function - */ - delegate object ExtractValue(IntPtr luaState, int stackPos); - - /* - * Wrapper class for methods/constructors accessed from Lua. - * - * Author: Fabio Mascarenhas - * Version: 1.0 - */ - class LuaMethodWrapper - { - private ObjectTranslator _Translator; - private MethodBase _Method; - private MethodCache _LastCalledMethod = new MethodCache(); - private string _MethodName; - private MemberInfo[] _Members; - private ExtractValue _ExtractTarget; - private object _Target; - private BindingFlags _BindingType; - - /* - * Constructs the wrapper for a known MethodBase instance - */ - public LuaMethodWrapper(ObjectTranslator translator, object target, IReflect targetType, MethodBase method) - { - _Translator = translator; - _Target = target; - if (targetType != null) - _ExtractTarget = translator.typeChecker.getExtractor(targetType); - _Method = method; - _MethodName = method.Name; - - if (method.IsStatic) - { _BindingType = BindingFlags.Static; } - else - { _BindingType = BindingFlags.Instance; } - } - /* - * Constructs the wrapper for a known method name - */ - public LuaMethodWrapper(ObjectTranslator translator, IReflect targetType, string methodName, BindingFlags bindingType) - { - _Translator = translator; - _MethodName = methodName; - - if (targetType != null) - _ExtractTarget = translator.typeChecker.getExtractor(targetType); - - _BindingType = bindingType; - - //CP: Removed NonPublic binding search and added IgnoreCase - _Members = targetType.UnderlyingSystemType.GetMember(methodName, MemberTypes.Method, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase/*|BindingFlags.NonPublic*/); - } - - - /// - /// Convert C# exceptions into Lua errors - /// - /// num of things on stack - /// null for no pending exception - int SetPendingException(Exception e) - { - return _Translator.interpreter.SetPendingException(e); - } - - private static bool IsInteger(double x) { - return Math.Ceiling(x) == x; - } - - - /* - * Calls the method. Receives the arguments from the Lua stack - * and returns values in it. - */ - public int call(IntPtr luaState) - { - MethodBase methodToCall = _Method; - object targetObject = _Target; - bool failedCall = true; - int nReturnValues = 0; - - if (!LuaDLL.lua_checkstack(luaState, 5)) - throw new LuaException("Lua stack overflow"); - - bool isStatic = (_BindingType & BindingFlags.Static) == BindingFlags.Static; - - SetPendingException(null); - - if (methodToCall == null) // Method from name - { - if (isStatic) - targetObject = null; - else - targetObject = _ExtractTarget(luaState, 1); - - //LuaDLL.lua_remove(luaState,1); // Pops the receiver - 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 = LuaDLL.lua_gettop(luaState) - numStackToSkip; - MethodBase method = _LastCalledMethod.cachedMethod; - - if (numArgsPassed == _LastCalledMethod.argTypes.Length) // No. of args match? - { - if (!LuaDLL.lua_checkstack(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]; - object luaParamValue = type.extractValue(luaState, i + 1 + numStackToSkip); - if (_LastCalledMethod.argTypes[i].isParamsArray) - { - args[type.index] = _Translator.tableToArray(luaParamValue,type.paramsArrayType); - } - else - { - args[type.index] = luaParamValue; - } - - if (args[type.index] == null && - !LuaDLL.lua_isnil(luaState, i + 1 + numStackToSkip)) - { - throw new LuaException("argument number " + (i + 1) + " is invalid"); - } - } - if ((_BindingType & BindingFlags.Static) == BindingFlags.Static) - { - _Translator.push(luaState, method.Invoke(null, args)); - } - else - { - if (_LastCalledMethod.cachedMethod.IsConstructor) - _Translator.push(luaState, ((ConstructorInfo)method).Invoke(args)); - else - _Translator.push(luaState, method.Invoke(targetObject,args)); - } - failedCall = false; - } - catch (TargetInvocationException e) - { - // Failure of method invocation - 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)); - LuaDLL.lua_pushnil(luaState); - return 1; - } - - LuaDLL.lua_remove(luaState, 1); // Pops the receiver - } - - bool hasMatch = false; - string candidateName = null; - - foreach (MemberInfo member in _Members) - { - candidateName = member.ReflectedType.Name + "." + member.Name; - - MethodBase 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: " + _MethodName - : ("invalid arguments to method: " + candidateName); - - _Translator.throwError(luaState, msg); - LuaDLL.lua_pushnil(luaState); - return 1; - } - } - } - else // Method from MethodBase instance - { - if (methodToCall.ContainsGenericParameters) - { - // bool isMethod = //* not used - _Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod); - - if (methodToCall.IsGenericMethodDefinition) - { - //need to make a concrete type of the generic method definition - List typeArgs = new List(); - - foreach (object arg in _LastCalledMethod.args) - typeArgs.Add(arg.GetType()); - - MethodInfo 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"); - LuaDLL.lua_pushnil(luaState); - return 1; - } - } - else - { - if (!methodToCall.IsStatic && !methodToCall.IsConstructor && targetObject == null) - { - targetObject = _ExtractTarget(luaState, 1); - LuaDLL.lua_remove(luaState, 1); // Pops the receiver - } - - if (!_Translator.matchParameters(luaState, methodToCall, ref _LastCalledMethod)) - { - _Translator.throwError(luaState, string.Format("invalid arguments to method call {0} of type {1}", methodToCall, methodToCall.ReflectedType)); - LuaDLL.lua_pushnil(luaState); - return 1; - } - } - } - - if (failedCall) - { - if (!LuaDLL.lua_checkstack(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 - { - object returnValue = _LastCalledMethod.cachedMethod.Invoke( targetObject, _LastCalledMethod.args ); - _Translator.push(luaState, returnValue ); - - LuaTable returnValueLuaBase = returnValue as LuaTable; - if( returnValueLuaBase != null && returnValueLuaBase.IsOrphaned ) - { - returnValueLuaBase.Dispose(); - } - } - } - } - catch (TargetInvocationException e) - { - 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++; - - object outArg = _LastCalledMethod.args[_LastCalledMethod.outList[index]]; - - _Translator.push(luaState, outArg ); - - LuaTable outArgLuaBase = outArg as LuaTable; - if( outArgLuaBase != null && outArgLuaBase.IsOrphaned ) - { - outArgLuaBase.Dispose(); - } - } - - //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; - } - } - - - - - /// - /// We keep track of what delegates we have auto attached to an event - to allow us to cleanly exit a LuaInterface session - /// - class EventHandlerContainer : IDisposable - { - Dictionary dict = new Dictionary(); - - public void Add(Delegate handler, RegisterEventHandler eventInfo) - { - dict.Add(handler, eventInfo); - } - - public void Remove(Delegate handler) - { - bool found = dict.Remove(handler); - Debug.Assert(found); - } - - /// - /// Remove any still registered handlers - /// - public void Dispose() - { - foreach (KeyValuePair pair in dict) - { - pair.Value.RemovePending(pair.Key); - } - - dict.Clear(); - } - } - - - /* - * Wrapper class for events that does registration/deregistration - * of event handlers. - * - * Author: Fabio Mascarenhas - * Version: 1.0 - */ - class RegisterEventHandler - { - object target; - EventInfo eventInfo; - EventHandlerContainer pendingEvents; - - public RegisterEventHandler(EventHandlerContainer pendingEvents, object target, EventInfo eventInfo) - { - this.target = target; - this.eventInfo = eventInfo; - this.pendingEvents = pendingEvents; - } - - - /* - * Adds a new event handler - */ - public Delegate Add(LuaFunction function) - { - //CP: Fix by Ben Bryant for event handling with one parameter - //link: http://luaforge.net/forum/message.php?msg_id=9266 - Delegate handlerDelegate = CodeGeneration.Instance.GetDelegate(eventInfo.EventHandlerType, function); - eventInfo.AddEventHandler(target, handlerDelegate); - pendingEvents.Add(handlerDelegate, this); - - return handlerDelegate; - - - //MethodInfo mi = eventInfo.EventHandlerType.GetMethod("Invoke"); - //ParameterInfo[] pi = mi.GetParameters(); - //LuaEventHandler handler=CodeGeneration.Instance.GetEvent(pi[1].ParameterType,function); - - //Delegate handlerDelegate=Delegate.CreateDelegate(eventInfo.EventHandlerType,handler,"HandleEvent"); - //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); - } - } - - /* - * 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]); - //} - } - - /* - * 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 Type[] returnTypes; - public LuaFunction function; - 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; - } - } - - /* - * 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) - { - 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; - } - } -} diff --git a/LuaInterface/ObjectTranslator.cs b/LuaInterface/ObjectTranslator.cs deleted file mode 100644 index a28c73e236..0000000000 --- a/LuaInterface/ObjectTranslator.cs +++ /dev/null @@ -1,870 +0,0 @@ -namespace LuaInterface -{ - using System; - using System.IO; - using System.Collections; - using System.Reflection; - using System.Collections.Generic; - using System.Diagnostics; - - /* - * Passes objects from the CLR to Lua and vice-versa - * - * Author: Fabio Mascarenhas - * Version: 1.0 - */ - public class ObjectTranslator - { - internal CheckType typeChecker; - - // object # to object (FIXME - it should be possible to get object address as an object #) - public readonly Dictionary objects = new Dictionary(); - // object to object # - public readonly Dictionary objectsBackMap = new Dictionary(); - internal Lua interpreter; - private MetaFunctions metaFunctions; - private List assemblies; - private LuaCSFunction getMethodSigFunction, getConstructorSigFunction, ctypeFunction, enumFromIntFunction; - - internal EventHandlerContainer pendingEvents = new EventHandlerContainer(); - - public ObjectTranslator(Lua interpreter,IntPtr luaState) - { - this.interpreter = interpreter; - typeChecker = new CheckType(this); - metaFunctions = new MetaFunctions(this); - assemblies = new List(); - - getMethodSigFunction= getMethodSignature; - getConstructorSigFunction= getConstructorSignature; - - ctypeFunction = ctype; - enumFromIntFunction = enumFromInt; - - createLuaObjectList(luaState); - createIndexingMetaFunction(luaState); - createBaseClassMetatable(luaState); - createClassMetatable(luaState); - createFunctionMetatable(luaState); - setGlobalFunctions(luaState); - } - - /* - * Sets up the list of objects in the Lua side - */ - private void createLuaObjectList(IntPtr luaState) - { - LuaDLL.lua_pushstring(luaState,"luaNet_objects"); - LuaDLL.lua_newtable(luaState); - LuaDLL.lua_newtable(luaState); - LuaDLL.lua_pushstring(luaState,"__mode"); - LuaDLL.lua_pushstring(luaState,"v"); - LuaDLL.lua_settable(luaState,-3); - LuaDLL.lua_setmetatable(luaState,-2); - LuaDLL.lua_settable(luaState, (int) LuaIndexes.LUA_REGISTRYINDEX); - } - /* - * Registers the indexing function of CLR objects - * passed to Lua - */ - private void createIndexingMetaFunction(IntPtr luaState) - { - LuaDLL.lua_pushstring(luaState,"luaNet_indexfunction"); - LuaDLL.luaL_dostring(luaState,MetaFunctions.luaIndexFunction); // steffenj: lua_dostring renamed to luaL_dostring - //LuaDLL.lua_pushstdcallcfunction(luaState,indexFunction); - LuaDLL.lua_rawset(luaState, (int) LuaIndexes.LUA_REGISTRYINDEX); - } - /* - * Creates the metatable for superclasses (the base - * field of registered tables) - */ - private void createBaseClassMetatable(IntPtr luaState) - { - LuaDLL.luaL_newmetatable(luaState,"luaNet_searchbase"); - LuaDLL.lua_pushstring(luaState,"__gc"); - LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction); - LuaDLL.lua_settable(luaState,-3); - LuaDLL.lua_pushstring(luaState,"__tostring"); - LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction); - LuaDLL.lua_settable(luaState,-3); - LuaDLL.lua_pushstring(luaState,"__index"); - LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.baseIndexFunction); - LuaDLL.lua_settable(luaState,-3); - LuaDLL.lua_pushstring(luaState,"__newindex"); - LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.newindexFunction); - LuaDLL.lua_settable(luaState,-3); - LuaDLL.lua_settop(luaState,-2); - } - /* - * Creates the metatable for type references - */ - private void createClassMetatable(IntPtr luaState) - { - LuaDLL.luaL_newmetatable(luaState,"luaNet_class"); - LuaDLL.lua_pushstring(luaState,"__gc"); - LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction); - LuaDLL.lua_settable(luaState,-3); - LuaDLL.lua_pushstring(luaState,"__tostring"); - LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.toStringFunction); - LuaDLL.lua_settable(luaState,-3); - LuaDLL.lua_pushstring(luaState,"__index"); - LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.classIndexFunction); - LuaDLL.lua_settable(luaState,-3); - LuaDLL.lua_pushstring(luaState,"__newindex"); - LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.classNewindexFunction); - LuaDLL.lua_settable(luaState,-3); - LuaDLL.lua_pushstring(luaState,"__call"); - LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.callConstructorFunction); - LuaDLL.lua_settable(luaState,-3); - LuaDLL.lua_settop(luaState,-2); - } - /* - * Registers the global functions used by LuaInterface - */ - private void setGlobalFunctions(IntPtr luaState) - { - LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.indexFunction); - LuaDLL.lua_setglobal(luaState,"get_object_member"); - /*LuaDLL.lua_pushstdcallcfunction(luaState,importTypeFunction); - LuaDLL.lua_setglobal(luaState,"import_type"); - LuaDLL.lua_pushstdcallcfunction(luaState,loadAssemblyFunction); - LuaDLL.lua_setglobal(luaState,"load_assembly"); - LuaDLL.lua_pushstdcallcfunction(luaState,registerTableFunction); - LuaDLL.lua_setglobal(luaState,"make_object"); - LuaDLL.lua_pushstdcallcfunction(luaState,unregisterTableFunction); - LuaDLL.lua_setglobal(luaState,"free_object");*/ - LuaDLL.lua_pushstdcallcfunction(luaState,getMethodSigFunction); - LuaDLL.lua_setglobal(luaState,"get_method_bysig"); - LuaDLL.lua_pushstdcallcfunction(luaState,getConstructorSigFunction); - LuaDLL.lua_setglobal(luaState,"get_constructor_bysig"); - LuaDLL.lua_pushstdcallcfunction(luaState,ctypeFunction); - LuaDLL.lua_setglobal(luaState,"ctype"); - LuaDLL.lua_pushstdcallcfunction(luaState,enumFromIntFunction); - LuaDLL.lua_setglobal(luaState,"enum"); - - } - - /* - * Creates the metatable for delegates - */ - private void createFunctionMetatable(IntPtr luaState) - { - LuaDLL.luaL_newmetatable(luaState,"luaNet_function"); - LuaDLL.lua_pushstring(luaState,"__gc"); - LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.gcFunction); - LuaDLL.lua_settable(luaState,-3); - LuaDLL.lua_pushstring(luaState,"__call"); - LuaDLL.lua_pushstdcallcfunction(luaState,metaFunctions.execDelegateFunction); - LuaDLL.lua_settable(luaState,-3); - LuaDLL.lua_settop(luaState,-2); - } - /* - * Passes errors (argument e) to the Lua interpreter - */ - internal void throwError(IntPtr luaState, object e) - { - // We use this to remove anything pushed by luaL_where - int oldTop = LuaDLL.lua_gettop(luaState); - - // Stack frame #1 is our C# wrapper, so not very interesting to the user - // Stack frame #2 must be the lua code that called us, so that's what we want to use - LuaDLL.luaL_where(luaState, 1); - object[] curlev = popValues(luaState, oldTop); - - // Determine the position in the script where the exception was triggered - string errLocation = ""; - if (curlev.Length > 0) - errLocation = curlev[0].ToString(); - - string message = e as string; - if (message != null) - { - // Wrap Lua error (just a string) and store the error location - e = new LuaScriptException(message, errLocation); - } - else - { - Exception ex = e as Exception; - if (ex != null) - { - // Wrap generic .NET exception as an InnerException and store the error location - e = new LuaScriptException(ex, errLocation); - } - } - - push(luaState, e); - LuaDLL.lua_error(luaState); - } - /* - * Implementation of load_assembly. Throws an error - * if the assembly is not found. - */ - private int loadAssembly(IntPtr luaState) - { - try - { - string assemblyName = LuaDLL.lua_tostring(luaState,1); - - Assembly assembly = Assembly.Load(AssemblyName.GetAssemblyName(assemblyName)); - - if (assembly != null && !assemblies.Contains(assembly)) - { - assemblies.Add(assembly); - } - } - catch(Exception e) - { - throwError(luaState,e); - } - - return 0; - } - - internal Type FindType(string className) - { - foreach(Assembly assembly in assemblies) - { - Type klass=assembly.GetType(className); - if(klass!=null) - { - return klass; - } - } - return null; - } - - /* - * Implementation of import_type. Returns nil if the - * type is not found. - */ - private int importType(IntPtr luaState) - { - string className=LuaDLL.lua_tostring(luaState,1); - Type klass=FindType(className); - if(klass!=null) - pushType(luaState,klass); - else - LuaDLL.lua_pushnil(luaState); - return 1; - } - /* - * Implementation of make_object. Registers a table (first - * argument in the stack) as an object subclassing the - * type passed as second argument in the stack. - */ - private int registerTable(IntPtr luaState) - { - if(LuaDLL.lua_type(luaState,1)==LuaTypes.LUA_TTABLE) - { - LuaTable luaTable=getTable(luaState,1); - string superclassName = LuaDLL.lua_tostring(luaState, 2); - if (superclassName != null) - { - Type klass = FindType(superclassName); - if (klass != null) - { - // Creates and pushes the object in the stack, setting - // it as the metatable of the first argument - object obj = CodeGeneration.Instance.GetClassInstance(klass, luaTable); - pushObject(luaState, obj, "luaNet_metatable"); - LuaDLL.lua_newtable(luaState); - LuaDLL.lua_pushstring(luaState, "__index"); - LuaDLL.lua_pushvalue(luaState, -3); - LuaDLL.lua_settable(luaState, -3); - LuaDLL.lua_pushstring(luaState, "__newindex"); - LuaDLL.lua_pushvalue(luaState, -3); - LuaDLL.lua_settable(luaState, -3); - LuaDLL.lua_setmetatable(luaState, 1); - // Pushes the object again, this time as the base field - // of the table and with the luaNet_searchbase metatable - LuaDLL.lua_pushstring(luaState, "base"); - int index = addObject(obj); - pushNewObject(luaState, obj, index, "luaNet_searchbase"); - LuaDLL.lua_rawset(luaState, 1); - } - else - throwError(luaState, "register_table: can not find superclass '" + superclassName + "'"); - } - else - throwError(luaState, "register_table: superclass name can not be null"); - } - else throwError(luaState,"register_table: first arg is not a table"); - return 0; - } - /* - * Implementation of free_object. Clears the metatable and the - * base field, freeing the created object for garbage-collection - */ - private int unregisterTable(IntPtr luaState) - { - try - { - if(LuaDLL.lua_getmetatable(luaState,1)!=0) - { - LuaDLL.lua_pushstring(luaState,"__index"); - LuaDLL.lua_gettable(luaState,-2); - object obj=getRawNetObject(luaState,-1); - if(obj==null) throwError(luaState,"unregister_table: arg is not valid table"); - FieldInfo luaTableField=obj.GetType().GetField("__luaInterface_luaTable"); - if(luaTableField==null) throwError(luaState,"unregister_table: arg is not valid table"); - luaTableField.SetValue(obj,null); - LuaDLL.lua_pushnil(luaState); - LuaDLL.lua_setmetatable(luaState,1); - LuaDLL.lua_pushstring(luaState,"base"); - LuaDLL.lua_pushnil(luaState); - LuaDLL.lua_settable(luaState,1); - } - else throwError(luaState,"unregister_table: arg is not valid table"); - } - catch(Exception e) - { - throwError(luaState,e.Message); - } - return 0; - } - /* - * Implementation of get_method_bysig. Returns nil - * if no matching method is not found. - */ - private int getMethodSignature(IntPtr luaState) - { - IReflect klass; object target; - int udata=LuaDLL.luanet_checkudata(luaState,1,"luaNet_class"); - if(udata!=-1) - { - klass=(IReflect)objects[udata]; - target=null; - } - else - { - target=getRawNetObject(luaState,1); - if(target==null) - { - throwError(luaState,"get_method_bysig: first arg is not type or object reference"); - LuaDLL.lua_pushnil(luaState); - return 1; - } - klass=target.GetType(); - } - string methodName=LuaDLL.lua_tostring(luaState,2); - Type[] signature=new Type[LuaDLL.lua_gettop(luaState)-2]; - for(int i=0;i - /// Given the Lua int ID for an object remove it from our maps - /// - /// - internal void collectObject(int udata) - { - object o; - bool found = objects.TryGetValue(udata, out o); - - // The other variant of collectObject might have gotten here first, in that case we will silently ignore the missing entry - if (found) - { - // Debug.WriteLine("Removing " + o.ToString() + " @ " + udata); - - objects.Remove(udata); - objectsBackMap.Remove(o); - } - } - - - /// - /// Given an object reference, remove it from our maps - /// - /// - void collectObject(object o, int udata) - { - // Debug.WriteLine("Removing " + o.ToString() + " @ " + udata); - - objects.Remove(udata); - objectsBackMap.Remove(o); - } - - - /// - /// We want to ensure that objects always have a unique ID - /// - int nextObj = 0; - - int addObject(object obj) - { - // New object: inserts it in the list - int index = nextObj++; - - // Debug.WriteLine("Adding " + obj.ToString() + " @ " + index); - - objects[index] = obj; - objectsBackMap[obj] = index; - - return index; - } - - - - /* - * Gets an object from the Lua stack according to its Lua type. - */ - internal object getObject(IntPtr luaState,int index) - { - LuaTypes type=LuaDLL.lua_type(luaState,index); - switch(type) - { - case LuaTypes.LUA_TNUMBER: - { - return LuaDLL.lua_tonumber(luaState,index); - } - case LuaTypes.LUA_TSTRING: - { - return LuaDLL.lua_tostring(luaState,index); - } - case LuaTypes.LUA_TBOOLEAN: - { - return LuaDLL.lua_toboolean(luaState,index); - } - case LuaTypes.LUA_TTABLE: - { - return getTable(luaState,index); - } - case LuaTypes.LUA_TFUNCTION: - { - return getFunction(luaState,index); - } - case LuaTypes.LUA_TUSERDATA: - { - int udata=LuaDLL.luanet_tonetobject(luaState,index); - if(udata!=-1) - return objects[udata]; - else - return getUserData(luaState,index); - } - default: - return null; - } - } - /* - * Gets the table in the index positon of the Lua stack. - */ - internal LuaTable getTable(IntPtr luaState,int index) - { - LuaDLL.lua_pushvalue(luaState,index); - return new LuaTable(LuaDLL.lua_ref(luaState,1),interpreter); - } - /* - * Gets the userdata in the index positon of the Lua stack. - */ - internal LuaUserData getUserData(IntPtr luaState,int index) - { - LuaDLL.lua_pushvalue(luaState,index); - return new LuaUserData(LuaDLL.lua_ref(luaState,1),interpreter); - } - /* - * Gets the function in the index positon of the Lua stack. - */ - internal LuaFunction getFunction(IntPtr luaState,int index) - { - LuaDLL.lua_pushvalue(luaState,index); - return new LuaFunction(LuaDLL.lua_ref(luaState,1),interpreter); - } - /* - * Gets the CLR object in the index positon of the Lua stack. Returns - * delegates as Lua functions. - */ - internal object getNetObject(IntPtr luaState,int index) - { - int idx=LuaDLL.luanet_tonetobject(luaState,index); - if(idx!=-1) - return objects[idx]; - else - return null; - } - /* - * Gets the CLR object in the index positon of the Lua stack. Returns - * delegates as is. - */ - internal object getRawNetObject(IntPtr luaState,int index) - { - int udata=LuaDLL.luanet_rawnetobj(luaState,index); - if(udata!=-1) - { - return objects[udata]; - } - return null; - } - /* - * Pushes the entire array into the Lua stack and returns the number - * of elements pushed. - */ - internal int returnValues(IntPtr luaState, object[] returnValues) - { - if(LuaDLL.lua_checkstack(luaState,returnValues.Length+5)) - { - for(int i=0;i - /// Summary description for ProxyType. - /// - public class ProxyType : IReflect - { - - Type proxy; - - public ProxyType(Type proxy) - { - this.proxy = proxy; - } - - /// - /// Provide human readable short hand for this proxy object - /// - /// - public override string ToString() - { - return "ProxyType(" + UnderlyingSystemType + ")"; - } - - - public Type UnderlyingSystemType - { - get - { - return proxy; - } - } - - public FieldInfo GetField(string name, BindingFlags bindingAttr) - { - return proxy.GetField(name, bindingAttr); - } - - public FieldInfo[] GetFields(BindingFlags bindingAttr) - { - return proxy.GetFields(bindingAttr); - } - - public MemberInfo[] GetMember(string name, BindingFlags bindingAttr) - { - return proxy.GetMember(name, bindingAttr); - } - - public MemberInfo[] GetMembers(BindingFlags bindingAttr) - { - return proxy.GetMembers(bindingAttr); - } - - public MethodInfo GetMethod(string name, BindingFlags bindingAttr) - { - return proxy.GetMethod(name, bindingAttr); - } - - public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) - { - return proxy.GetMethod(name, bindingAttr, binder, types, modifiers); - } - - public MethodInfo[] GetMethods(BindingFlags bindingAttr) - { - return proxy.GetMethods(bindingAttr); - } - - public PropertyInfo GetProperty(string name, BindingFlags bindingAttr) - { - return proxy.GetProperty(name, bindingAttr); - } - - public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) - { - return proxy.GetProperty(name, bindingAttr, binder, returnType, types, modifiers); - } - - public PropertyInfo[] GetProperties(BindingFlags bindingAttr) - { - return proxy.GetProperties(bindingAttr); - } - - public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) - { - return proxy.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters); - } - - } -}