/*
  * 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;
 }
 public LuaDelegate()
 {
     function = null;
     returnTypes = null;
 }
 /*
  * Gets a delegate with delegateType that calls the luaFunc Lua function
  * Caches the generated type.
  */
 public Delegate GetDelegate( Type delegateType, LuaFunction luaFunc )
 {
     List<Type> returnTypes = new List<Type>();
     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" );
 }
        /*
         * 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;
        }
 /*
  * Gets an event handler for the event type that delegates to the eventHandler Lua function.
  * Caches the generated type.
  */
 public LuaEventHandler GetEvent( Type eventHandlerType, LuaFunction eventHandler )
 {
     Type eventConsumerType;
     if ( eventHandlerCollection.ContainsKey( eventHandlerType ) )
     {
         eventConsumerType = eventHandlerCollection[eventHandlerType];
     }
     else
     {
         eventConsumerType = GenerateEvent( eventHandlerType );
         eventHandlerCollection[eventHandlerType] = eventConsumerType;
     }
     LuaEventHandler luaEventHandler = (LuaEventHandler)Activator.CreateInstance( eventConsumerType );
     luaEventHandler.handler = eventHandler;
     return luaEventHandler;
 }