/Assets/LUA/NLua/GenerateEventAssembly/CodeGeneration.cs
C# | 626 lines | 574 code | 18 blank | 34 comment | 79 complexity | ffebd9afecb52c47243cd31de0a7a17e MD5 | raw file
- using System;
- using System.Threading;
- using System.Reflection;
- #if !MONOTOUCH
- using System.Reflection.Emit;
- #endif
- using System.Collections.Generic;
- using NLua.Method;
- namespace NLua
- {
- class CodeGeneration
- {
- private Dictionary<Type, LuaClassType> _classCollection = new Dictionary<Type, LuaClassType>();
- private Dictionary<Type, Type> _delegateCollection = new Dictionary<Type, Type>();
- private static readonly CodeGeneration _instance = new CodeGeneration();
- private AssemblyName _assemblyName;
- #if !MONOTOUCH && !SILVERLIGHT
- private Dictionary<Type, Type> _eventHandlerCollection = new Dictionary<Type, Type>();
- private Type _eventHandlerParent = typeof(LuaEventHandler);
- private Type _delegateParent = typeof(LuaDelegate);
- private Type _classHelper = typeof(LuaClassHelper);
- private AssemblyBuilder _newAssembly;
- private ModuleBuilder _newModule;
- private int _luaClassNumber = 1;
- #endif
- static CodeGeneration() { }
- private CodeGeneration()
- {
- _assemblyName = new AssemblyName();
- _assemblyName.Name = "NLua_generatedcode";
- #if !MONOTOUCH && !SILVERLIGHT
- _newAssembly = Thread.GetDomain().DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.Run);
- _newModule = _newAssembly.DefineDynamicModule("NLua_generatedcode");
- #endif
- }
- /*
- * 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 _event_handler_type)
- {
- #if MONOTOUCH
- throw new NotImplementedException (" Emit not available on MonoTouch ");
- #elif SILVERLIGHT
- throw new NotImplementedException(" Emit not available on Silverlight ");
- #else
- string _type_name;
- lock (this)
- {
- _type_name = "LuaGeneratedClass" + _luaClassNumber.ToString();
- _luaClassNumber++;
- }
- var _my_type = _newModule.DefineType(_type_name, TypeAttributes.Public, _eventHandlerParent);
- var _param_types = new Type[2];
- _param_types[0] = typeof(object);
- _param_types[1] = _event_handler_type;
- var _return_type = typeof(void);
- var _handle_method = _my_type.DefineMethod("HandleEvent", MethodAttributes.Public | MethodAttributes.HideBySig, _return_type, _param_types);
- ILGenerator _generator = _handle_method.GetILGenerator();
- _generator.Emit(OpCodes.Ldarg_0);
- _generator.Emit(OpCodes.Ldarg_1);
- _generator.Emit(OpCodes.Ldarg_2);
- var _mi_generic_event_handler = _eventHandlerParent.GetMethod("HandleEvent");
- _generator.Emit(OpCodes.Call, _mi_generic_event_handler);
- _generator.Emit(OpCodes.Ret);
- return _my_type.CreateType();
- #endif
- }
- /*
- * Generates a type that can be used for instantiating a delegate
- * of the provided type, given a Lua function.
- */
- private Type GenerateDelegate(Type _delegate_type)
- {
- #if MONOTOUCH
- throw new NotImplementedException ("GenerateDelegate is not available on iOS, please register your LuaDelegate type with Lua.RegisterLuaDelegateType( yourDelegate, theLuaDelegateHandler) ");
- #elif SILVERLIGHT
- throw new NotImplementedException("GenerateDelegate is not available on Silverlight, please register your LuaDelegate type with Lua.RegisterLuaDelegateType( yourDelegate, theLuaDelegateHandler) ");
- #else
- string _type_name;
- lock (this)
- {
- _type_name = "LuaGeneratedClass" + _luaClassNumber.ToString();
- _luaClassNumber++;
- }
- var _my_type = _newModule.DefineType(_type_name, TypeAttributes.Public, _delegateParent);
- var _invoke_method = _delegate_type.GetMethod("Invoke");
- var _param_info = _invoke_method.GetParameters();
- var _param_types = new Type[_param_info.Length];
- var _return_type = _invoke_method.ReturnType;
- int _n_out_params = 0;
- int _n_out_and_ref_params = 0;
- for (int i = 0; i < _param_types.Length; i++)
- {
- _param_types[i] = _param_info[i].ParameterType;
- if ((!_param_info[i].IsIn) && _param_info[i].IsOut)
- _n_out_params++;
- if (_param_types[i].IsByRef)
- _n_out_and_ref_params++;
- }
- int[] _ref_args = new int[_n_out_and_ref_params];
- var _delegate_method = _my_type.DefineMethod("CallFunction", _invoke_method.Attributes, _return_type, _param_types);
- ILGenerator _generator = _delegate_method.GetILGenerator();
- _generator.DeclareLocal(typeof(object[]));
- _generator.DeclareLocal(typeof(object[]));
- _generator.DeclareLocal(typeof(int[]));
- if (!(_return_type == typeof(void)))
- _generator.DeclareLocal(_return_type);
- else
- _generator.DeclareLocal(typeof(object));
- _generator.Emit(OpCodes.Ldc_I4, _param_types.Length);
- _generator.Emit(OpCodes.Newarr, typeof(object));
- _generator.Emit(OpCodes.Stloc_0);
- _generator.Emit(OpCodes.Ldc_I4, _param_types.Length - _n_out_params);
- _generator.Emit(OpCodes.Newarr, typeof(object));
- _generator.Emit(OpCodes.Stloc_1);
- _generator.Emit(OpCodes.Ldc_I4, _n_out_and_ref_params);
- _generator.Emit(OpCodes.Newarr, typeof(int));
- _generator.Emit(OpCodes.Stloc_2);
- for (int _i_args = 0, _i_in_args = 0, _i_out_args = 0; _i_args < _param_types.Length; _i_args++)
- {
- _generator.Emit(OpCodes.Ldloc_0);
- _generator.Emit(OpCodes.Ldc_I4, _i_args);
- _generator.Emit(OpCodes.Ldarg, _i_args + 1);
- if (_param_types[_i_args].IsByRef)
- {
- if (_param_types[_i_args].GetElementType().IsValueType)
- {
- _generator.Emit(OpCodes.Ldobj, _param_types[_i_args].GetElementType());
- _generator.Emit(OpCodes.Box, _param_types[_i_args].GetElementType());
- }
- else
- _generator.Emit(OpCodes.Ldind_Ref);
- }
- else
- {
- if (_param_types[_i_args].IsValueType)
- _generator.Emit(OpCodes.Box, _param_types[_i_args]);
- }
- _generator.Emit(OpCodes.Stelem_Ref);
- if (_param_types[_i_args].IsByRef)
- {
- _generator.Emit(OpCodes.Ldloc_2);
- _generator.Emit(OpCodes.Ldc_I4, _i_out_args);
- _generator.Emit(OpCodes.Ldc_I4, _i_args);
- _generator.Emit(OpCodes.Stelem_I4);
- _ref_args[_i_out_args] = _i_args;
- _i_out_args++;
- }
- if (_param_info[_i_args].IsIn || (!_param_info[_i_args].IsOut))
- {
- _generator.Emit(OpCodes.Ldloc_1);
- _generator.Emit(OpCodes.Ldc_I4, _i_in_args);
- _generator.Emit(OpCodes.Ldarg, _i_args + 1);
- if (_param_types[_i_args].IsByRef)
- {
- if (_param_types[_i_args].GetElementType().IsValueType)
- {
- _generator.Emit(OpCodes.Ldobj, _param_types[_i_args].GetElementType());
- _generator.Emit(OpCodes.Box, _param_types[_i_args].GetElementType());
- }
- else
- _generator.Emit(OpCodes.Ldind_Ref);
- }
- else
- {
- if (_param_types[_i_args].IsValueType)
- _generator.Emit(OpCodes.Box, _param_types[_i_args]);
- }
- _generator.Emit(OpCodes.Stelem_Ref);
- _i_in_args++;
- }
- }
- _generator.Emit(OpCodes.Ldarg_0);
- _generator.Emit(OpCodes.Ldloc_0);
- _generator.Emit(OpCodes.Ldloc_1);
- _generator.Emit(OpCodes.Ldloc_2);
- var _mi_generic_event_handler = _delegateParent.GetMethod("CallFunction");
- _generator.Emit(OpCodes.Call, _mi_generic_event_handler);
- if (_return_type == typeof(void))
- {
- _generator.Emit(OpCodes.Pop);
- _generator.Emit(OpCodes.Ldnull);
- }
- else if (_return_type.IsValueType)
- {
- _generator.Emit(OpCodes.Unbox, _return_type);
- _generator.Emit(OpCodes.Ldobj, _return_type);
- }
- else
- _generator.Emit(OpCodes.Castclass, _return_type);
- _generator.Emit(OpCodes.Stloc_3);
- for (int i = 0; i < _ref_args.Length; i++)
- {
- _generator.Emit(OpCodes.Ldarg, _ref_args[i] + 1);
- _generator.Emit(OpCodes.Ldloc_0);
- _generator.Emit(OpCodes.Ldc_I4, _ref_args[i]);
- _generator.Emit(OpCodes.Ldelem_Ref);
- if (_param_types[_ref_args[i]].GetElementType().IsValueType)
- {
- _generator.Emit(OpCodes.Unbox, _param_types[_ref_args[i]].GetElementType());
- _generator.Emit(OpCodes.Ldobj, _param_types[_ref_args[i]].GetElementType());
- _generator.Emit(OpCodes.Stobj, _param_types[_ref_args[i]].GetElementType());
- }
- else
- {
- _generator.Emit(OpCodes.Castclass, _param_types[_ref_args[i]].GetElementType());
- _generator.Emit(OpCodes.Stind_Ref);
- }
- }
- if (!(_return_type == typeof(void)))
- _generator.Emit(OpCodes.Ldloc_3);
- _generator.Emit(OpCodes.Ret);
- return _my_type.CreateType();
- #endif
- }
- void GetReturnTypesFromClass(Type _class, out Type[][] _return_types)
- {
- var _class_methods = _class.GetMethods();
- _return_types = new Type[_class_methods.Length][];
- int i = 0;
- foreach (var _method in _class_methods)
- {
- if (_class.IsInterface)
- {
- GetReturnTypesFromMethod(_method, out _return_types[i]);
- i++;
- }
- else
- {
- if (!_method.IsPrivate && !_method.IsFinal && _method.IsVirtual)
- {
- GetReturnTypesFromMethod(_method, out _return_types[i]);
- i++;
- }
- }
- }
- }
- /*
- * Generates an implementation of klass, if it is an interface, or
- * a subclass of klass that delegates its virtual methods to a Lua table.
- */
- public void GenerateClass(Type _class, out Type _new_type, out Type[][] _return_types)
- {
- #if MONOTOUCH
- throw new NotImplementedException (" Emit not available on MonoTouch ");
- #elif SILVERLIGHT
- throw new NotImplementedException (" Emit not available on Silverlight ");
- #else
- string _type_name;
- lock (this)
- {
- _type_name = "LuaGeneratedClass" + _luaClassNumber.ToString();
- _luaClassNumber++;
- }
- TypeBuilder _my_type;
- if (_class.IsInterface)
- _my_type = _newModule.DefineType(_type_name, TypeAttributes.Public, typeof(object), new Type[] { _class, typeof(ILuaGeneratedType) });
- else
- _my_type = _newModule.DefineType(_type_name, TypeAttributes.Public, _class, new Type[] { typeof(ILuaGeneratedType) });
- var _lua_table_field = _my_type.DefineField("__luaInterface_luaTable", typeof(LuaTable), FieldAttributes.Public);
- var _return_types_field = _my_type.DefineField("__luaInterface_returnTypes", typeof(Type[][]), FieldAttributes.Public);
- var _constructor = _my_type.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(LuaTable), typeof(Type[][]) });
- ILGenerator _generator = _constructor.GetILGenerator();
- _generator.Emit(OpCodes.Ldarg_0);
- if (_class.IsInterface)
- _generator.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes));
- else
- _generator.Emit(OpCodes.Call, _class.GetConstructor(Type.EmptyTypes));
- _generator.Emit(OpCodes.Ldarg_0);
- _generator.Emit(OpCodes.Ldarg_1);
- _generator.Emit(OpCodes.Stfld, _lua_table_field);
- _generator.Emit(OpCodes.Ldarg_0);
- _generator.Emit(OpCodes.Ldarg_2);
- _generator.Emit(OpCodes.Stfld, _return_types_field);
- _generator.Emit(OpCodes.Ret);
- var _class_methods = _class.GetMethods();
- _return_types = new Type[_class_methods.Length][];
- int i = 0;
- foreach (var _method in _class_methods)
- {
- if (_class.IsInterface)
- {
- GenerateMethod(_my_type, _method, MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.NewSlot, i, _lua_table_field, _return_types_field, false, out _return_types[i]);
- i++;
- }
- else
- {
- if (!_method.IsPrivate && !_method.IsFinal && _method.IsVirtual)
- {
- GenerateMethod(_my_type, _method, (_method.Attributes | MethodAttributes.NewSlot) ^ MethodAttributes.NewSlot, i, _lua_table_field, _return_types_field, true, out _return_types[i]);
- i++;
- }
- }
- }
- var _return_table_method = _my_type.DefineMethod("LuaInterfaceGetLuaTable", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual, typeof(LuaTable), new Type[0]);
- _my_type.DefineMethodOverride(_return_table_method, typeof(ILuaGeneratedType).GetMethod("LuaInterfaceGetLuaTable"));
- _generator = _return_table_method.GetILGenerator();
- _generator.Emit(OpCodes.Ldfld, _lua_table_field);
- _generator.Emit(OpCodes.Ret);
- _new_type = _my_type.CreateType();
- #endif
- }
- void GetReturnTypesFromMethod(MethodInfo _method, out Type[] _return_types)
- {
- var _param_info = _method.GetParameters();
- var _param_types = new Type[_param_info.Length];
- var _return_types_list = new List<Type>();
- int _n_out_params = 0;
- int _n_out_and_ref_params = 0;
- var _return_type = _method.ReturnType;
- _return_types_list.Add(_return_type);
- for (int i = 0; i < _param_types.Length; i++)
- {
- _param_types[i] = _param_info[i].ParameterType;
- #if SILVERLIGHT
- if (_param_info[i].IsOut)
- #else
- if ((!_param_info[i].IsIn) && _param_info[i].IsOut)
- #endif
- _n_out_params++;
- if (_param_types[i].IsByRef)
- {
- _return_types_list.Add(_param_types[i].GetElementType());
- _n_out_and_ref_params++;
- }
- }
- _return_types = _return_types_list.ToArray();
- }
- #if !MONOTOUCH && !SILVERLIGHT
- /*
- * Generates an overriden implementation of method inside myType that delegates
- * to a function in a Lua table with the same name, if the function exists. If it
- * doesn't the method calls the base method (or does nothing, in case of interface
- * implementations).
- */
- private void GenerateMethod(TypeBuilder _my_type, MethodInfo _method, MethodAttributes _attributes, int _method_index, FieldInfo _lua_table_field, FieldInfo _return_types_field, bool _generate_base, out Type[] _return_types)
- {
- var _param_info = _method.GetParameters();
- var _param_types = new Type[_param_info.Length];
- var _return_types_list = new List<Type>();
- int _n_out_params = 0;
- int _n_out_and_ref_params = 0;
- var _return_type = _method.ReturnType;
- _return_types_list.Add(_return_type);
- for (int i = 0; i < _param_types.Length; i++)
- {
- _param_types[i] = _param_info[i].ParameterType;
- if ((!_param_info[i].IsIn) && _param_info[i].IsOut)
- _n_out_params++;
- if (_param_types[i].IsByRef)
- {
- _return_types_list.Add(_param_types[i].GetElementType());
- _n_out_and_ref_params++;
- }
- }
- int[] _ref_args = new int[_n_out_and_ref_params];
- _return_types = _return_types_list.ToArray();
- if (_generate_base)
- {
- var _base_method = _my_type.DefineMethod("__luaInterface_base_" + _method.Name, MethodAttributes.Private | MethodAttributes.NewSlot | MethodAttributes.HideBySig, _return_type, _param_types);
- ILGenerator _generator_base = _base_method.GetILGenerator();
- _generator_base.Emit(OpCodes.Ldarg_0);
- for (int i = 0; i < _param_types.Length; i++)
- _generator_base.Emit(OpCodes.Ldarg, i + 1);
- _generator_base.Emit(OpCodes.Call, _method);
- if (_return_type == typeof(void))
- _generator_base.Emit(OpCodes.Pop);
- _generator_base.Emit(OpCodes.Ret);
- }
- var _method_impl = _my_type.DefineMethod(_method.Name, _attributes, _return_type, _param_types);
- if (_my_type.BaseType.Equals(typeof(object)))
- _my_type.DefineMethodOverride(_method_impl, _method);
- ILGenerator _generator = _method_impl.GetILGenerator();
- _generator.DeclareLocal(typeof(object[]));
- _generator.DeclareLocal(typeof(object[]));
- _generator.DeclareLocal(typeof(int[]));
- if (!(_return_type == typeof(void)))
- _generator.DeclareLocal(_return_type);
- else
- _generator.DeclareLocal(typeof(object));
- _generator.Emit(OpCodes.Ldc_I4, _param_types.Length);
- _generator.Emit(OpCodes.Newarr, typeof(object));
- _generator.Emit(OpCodes.Stloc_0);
- _generator.Emit(OpCodes.Ldc_I4, _param_types.Length - _n_out_params + 1);
- _generator.Emit(OpCodes.Newarr, typeof(object));
- _generator.Emit(OpCodes.Stloc_1);
- _generator.Emit(OpCodes.Ldc_I4, _n_out_and_ref_params);
- _generator.Emit(OpCodes.Newarr, typeof(int));
- _generator.Emit(OpCodes.Stloc_2);
- _generator.Emit(OpCodes.Ldloc_1);
- _generator.Emit(OpCodes.Ldc_I4_0);
- _generator.Emit(OpCodes.Ldarg_0);
- _generator.Emit(OpCodes.Ldfld, _lua_table_field);
- _generator.Emit(OpCodes.Stelem_Ref);
- for (int _i_args = 0, _i_in_args = 1, _i_out_args = 0; _i_args < _param_types.Length; _i_args++)
- {
- _generator.Emit(OpCodes.Ldloc_0);
- _generator.Emit(OpCodes.Ldc_I4, _i_args);
- _generator.Emit(OpCodes.Ldarg, _i_args + 1);
- if (_param_types[_i_args].IsByRef)
- {
- if (_param_types[_i_args].GetElementType().IsValueType)
- {
- _generator.Emit(OpCodes.Ldobj, _param_types[_i_args].GetElementType());
- _generator.Emit(OpCodes.Box, _param_types[_i_args].GetElementType());
- }
- else
- _generator.Emit(OpCodes.Ldind_Ref);
- }
- else
- {
- if (_param_types[_i_args].IsValueType)
- _generator.Emit(OpCodes.Box, _param_types[_i_args]);
- }
- _generator.Emit(OpCodes.Stelem_Ref);
- if (_param_types[_i_args].IsByRef)
- {
- _generator.Emit(OpCodes.Ldloc_2);
- _generator.Emit(OpCodes.Ldc_I4, _i_out_args);
- _generator.Emit(OpCodes.Ldc_I4, _i_args);
- _generator.Emit(OpCodes.Stelem_I4);
- _ref_args[_i_out_args] = _i_args;
- _i_out_args++;
- }
- if (_param_info[_i_args].IsIn || (!_param_info[_i_args].IsOut))
- {
- _generator.Emit(OpCodes.Ldloc_1);
- _generator.Emit(OpCodes.Ldc_I4, _i_in_args);
- _generator.Emit(OpCodes.Ldarg, _i_args + 1);
- if (_param_types[_i_args].IsByRef)
- {
- if (_param_types[_i_args].GetElementType().IsValueType)
- {
- _generator.Emit(OpCodes.Ldobj, _param_types[_i_args].GetElementType());
- _generator.Emit(OpCodes.Box, _param_types[_i_args].GetElementType());
- }
- else
- _generator.Emit(OpCodes.Ldind_Ref);
- }
- else
- {
- if (_param_types[_i_args].IsValueType)
- _generator.Emit(OpCodes.Box, _param_types[_i_args]);
- }
- _generator.Emit(OpCodes.Stelem_Ref);
- _i_in_args++;
- }
- }
- _generator.Emit(OpCodes.Ldarg_0);
- _generator.Emit(OpCodes.Ldfld, _lua_table_field);
- _generator.Emit(OpCodes.Ldstr, _method.Name);
- _generator.Emit(OpCodes.Call, _classHelper.GetMethod("GetTableFunction"));
- var _lab_1 = _generator.DefineLabel();
- _generator.Emit(OpCodes.Dup);
- _generator.Emit(OpCodes.Brtrue_S, _lab_1);
- _generator.Emit(OpCodes.Pop);
- if (!_method.IsAbstract)
- {
- _generator.Emit(OpCodes.Ldarg_0);
- for (int i = 0; i < _param_types.Length; i++)
- _generator.Emit(OpCodes.Ldarg, i + 1);
- _generator.Emit(OpCodes.Call, _method);
- if (_return_type == typeof(void))
- _generator.Emit(OpCodes.Pop);
- _generator.Emit(OpCodes.Ret);
- _generator.Emit(OpCodes.Ldnull);
- }
- else
- _generator.Emit(OpCodes.Ldnull);
- var _lab_2 = _generator.DefineLabel();
- _generator.Emit(OpCodes.Br_S, _lab_2);
- _generator.MarkLabel(_lab_1);
- _generator.Emit(OpCodes.Ldloc_0);
- _generator.Emit(OpCodes.Ldarg_0);
- _generator.Emit(OpCodes.Ldfld, _return_types_field);
- _generator.Emit(OpCodes.Ldc_I4, _method_index);
- _generator.Emit(OpCodes.Ldelem_Ref);
- _generator.Emit(OpCodes.Ldloc_1);
- _generator.Emit(OpCodes.Ldloc_2);
- _generator.Emit(OpCodes.Call, _classHelper.GetMethod("CallFunction"));
- _generator.MarkLabel(_lab_2);
- if (_return_type == typeof(void))
- {
- _generator.Emit(OpCodes.Pop);
- _generator.Emit(OpCodes.Ldnull);
- }
- else if (_return_type.IsValueType)
- {
- _generator.Emit(OpCodes.Unbox, _return_type);
- _generator.Emit(OpCodes.Ldobj, _return_type);
- }
- else
- _generator.Emit(OpCodes.Castclass, _return_type);
- _generator.Emit(OpCodes.Stloc_3);
- for (int i = 0; i < _ref_args.Length; i++)
- {
- _generator.Emit(OpCodes.Ldarg, _ref_args[i] + 1);
- _generator.Emit(OpCodes.Ldloc_0);
- _generator.Emit(OpCodes.Ldc_I4, _ref_args[i]);
- _generator.Emit(OpCodes.Ldelem_Ref);
- if (_param_types[_ref_args[i]].GetElementType().IsValueType)
- {
- _generator.Emit(OpCodes.Unbox, _param_types[_ref_args[i]].GetElementType());
- _generator.Emit(OpCodes.Ldobj, _param_types[_ref_args[i]].GetElementType());
- _generator.Emit(OpCodes.Stobj, _param_types[_ref_args[i]].GetElementType());
- }
- else
- {
- _generator.Emit(OpCodes.Castclass, _param_types[_ref_args[i]].GetElementType());
- _generator.Emit(OpCodes.Stind_Ref);
- }
- }
- if (!(_return_type == typeof(void)))
- _generator.Emit(OpCodes.Ldloc_3);
- _generator.Emit(OpCodes.Ret);
- }
- #endif
- /*
- * Gets an event handler for the event type that delegates to the eventHandler Lua function.
- * Caches the generated type.
- */
- public LuaEventHandler GetEvent(Type _event_handler_type, LuaFunction _event_handler)
- {
- #if MONOTOUCH
- throw new NotImplementedException (" Emit not available on MonoTouch ");
- #elif SILVERLIGHT
- throw new NotImplementedException (" Emit not available on Silverlight ");
- #else
- Type _event_consumer_type;
- if (_eventHandlerCollection.ContainsKey(_event_handler_type))
- _event_consumer_type = _eventHandlerCollection[_event_handler_type];
- else
- {
- _event_consumer_type = GenerateEvent(_event_handler_type);
- _eventHandlerCollection[_event_handler_type] = _event_consumer_type;
- }
- var _lua_event_handler = (LuaEventHandler)Activator.CreateInstance(_event_consumer_type);
- _lua_event_handler.handler = _event_handler;
- return _lua_event_handler;
- #endif
- }
- public void RegisterLuaDelegateType(Type _delegate_type, Type _lua_delegate_type)
- {
- _delegateCollection[_delegate_type] = _lua_delegate_type;
- }
- public void RegisterLuaClassType(Type _class, Type _lua_class)
- {
- LuaClassType _lua_class_type = new LuaClassType();
- _lua_class_type.klass = _lua_class;
- GetReturnTypesFromClass(_class, out _lua_class_type.returnTypes);
- _classCollection[_class] = _lua_class_type;
- }
- /*
- * Gets a delegate with delegateType that calls the luaFunc Lua function
- * Caches the generated type.
- */
- public Delegate GetDelegate(Type _delegate_type, LuaFunction _lua_func)
- {
- var _return_types = new List<Type>();
- Type _lua_delegate_type;
- if (_delegateCollection.ContainsKey(_delegate_type))
- _lua_delegate_type = _delegateCollection[_delegate_type];
- else
- {
- _lua_delegate_type = GenerateDelegate(_delegate_type);
- _delegateCollection[_delegate_type] = _lua_delegate_type;
- }
- var _method_info = _delegate_type.GetMethod("Invoke");
- _return_types.Add(_method_info.ReturnType);
- foreach (ParameterInfo _param_info in _method_info.GetParameters())
- if (_param_info.ParameterType.IsByRef)
- _return_types.Add(_param_info.ParameterType);
- var _lua_delegate = (LuaDelegate)Activator.CreateInstance(_lua_delegate_type);
- _lua_delegate.function = _lua_func;
- _lua_delegate.returnTypes = _return_types.ToArray();
- return Delegate.CreateDelegate(_delegate_type, _lua_delegate, "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 _class, LuaTable _lua_table)
- {
- LuaClassType _lua_class_type;
- if (_classCollection.ContainsKey(_class))
- _lua_class_type = _classCollection[_class];
- else
- {
- _lua_class_type = new LuaClassType();
- GenerateClass(_class, out _lua_class_type.klass, out _lua_class_type.returnTypes);
- _classCollection[_class] = _lua_class_type;
- }
- return Activator.CreateInstance(_lua_class_type.klass, new object[] {
- _lua_table,
- _lua_class_type.returnTypes
- });
- }
- }
- }