Xlua原理 二

打印 上一主题 下一主题

主题 512|帖子 512|积分 1536

一已经介绍了初步的lua与C#通讯的原理,和xlua的LuaEnv的初始化内容。
这边介绍下Wrap文件。
一.Wrap介绍


导入xlua后可以看到会多出上图菜单。
点击后生成一堆wrap文件,这些文件是lua调用C#时举行映射查找用的中间代码。如许就不需要去反射调用节约性能。

这里以Vector3Wrap文件为例:
先看一眼Wrap文件布局
  1.    public class UnityEngineVector3Wrap
  2.     {
  3.         public static void __Register(RealStatePtr L)
  4.         {
  5.                         ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  6.                         System.Type type = typeof(UnityEngine.Vector3);
  7.                         Utils.BeginObjectRegister(type, L, translator, 6, 6, 6, 3);
  8.                         Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__add", __AddMeta);
  9.             Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__sub", __SubMeta);
  10.             Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__unm", __UnmMeta);
  11.             Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__mul", __MulMeta);
  12.             Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__div", __DivMeta);
  13.             Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__eq", __EqMeta);
  14.             
  15.                         Utils.RegisterFunc(L, Utils.METHOD_IDX, "Set", _m_Set);
  16.                         Utils.RegisterFunc(L, Utils.METHOD_IDX, "Scale", _m_Scale);
  17.                         Utils.RegisterFunc(L, Utils.METHOD_IDX, "GetHashCode", _m_GetHashCode);
  18.                         Utils.RegisterFunc(L, Utils.METHOD_IDX, "Equals", _m_Equals);
  19.                         Utils.RegisterFunc(L, Utils.METHOD_IDX, "Normalize", _m_Normalize);
  20.                         Utils.RegisterFunc(L, Utils.METHOD_IDX, "ToString", _m_ToString);
  21.            ...
  22.         }
  23.         ...
  24.     }   
复制代码
  1. private void Demo4()
  2.         {
  3.             LuaEnv luaenv = new LuaEnv();
  4.             luaenv.DoString(@"local v1 = CS.UnityEngine.Vector3(10,10,10)
  5.                             local v2 = v1.normalized
  6.                             CS.UnityEngine.Debug.Log(v2.x)
  7.                             local v3 = v1 + v2
  8.                             local v4 = CS.UnityEngine.Vector3.Distance(v1,v2)
  9.                             v1:Set(5,6,7)
  10.                             CS.UnityEngine.Debug.Log(v1.x)
  11.                             ");
  12.             luaenv.Dispose();
  13.         }
复制代码
以调用到normalized为例
  1. Utils.RegisterFunc(L, Utils.GETTER_IDX, "normalized", _g_get_normalized);
  2. ....
  3. [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  4.         static int _g_get_normalized(RealStatePtr L)
  5.         {
  6.                     try {
  7.                 ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  8.                        
  9.                 UnityEngine.Vector3 gen_to_be_invoked;
  10.                 translator.Get(L, 1, out gen_to_be_invoked);
  11.                 translator.PushUnityEngineVector3(L, gen_to_be_invoked.normalized);
  12.             } catch(System.Exception gen_e) {
  13.                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  14.             }
  15.             return 1;
  16.         }
复制代码
上面那步在lua假造机注册normalized,对应是C#里的函数。
函数中先获得Vector3变量然后调用C#中的normalized,末了再举行压栈操作供lua利用。
这块看出来,实际上lua还是去调用C#的代码,而且伴随压栈出栈操作。这就是为什么我们的lua的代码减少 . 如许的调用能节约一些性能的缘故原由。
再换个函数Set
  1.        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  2.         static int _m_Set(RealStatePtr L)
  3.         {
  4.                     try {
  5.             
  6.                 ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  7.                 UnityEngine.Vector3 gen_to_be_invoked;translator.Get(L, 1, out gen_to_be_invoked);
  8.                 {
  9.                     float _newX = (float)LuaAPI.lua_tonumber(L, 2);
  10.                     float _newY = (float)LuaAPI.lua_tonumber(L, 3);
  11.                     float _newZ = (float)LuaAPI.lua_tonumber(L, 4);
  12.                     gen_to_be_invoked.Set( _newX, _newY, _newZ );
  13.                     translator.UpdateUnityEngineVector3(L, 1, gen_to_be_invoked);
  14.                     return 0;
  15.                 }
  16.                
  17.             } catch(System.Exception gen_e) {
  18.                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  19.             }
  20.         }
复制代码
前面的部分跟normalized差不多看下UpdateUnityEngineVector3部分
  1. public void UpdateUnityEngineVector3(RealStatePtr L, int index, UnityEngine.Vector3 val)
  2.         {
  3.             if (LuaAPI.lua_type(L, index) == LuaTypes.LUA_TUSERDATA)
  4.             {
  5.                             if (LuaAPI.xlua_gettypeid(L, index) != UnityEngineVector3_TypeID)
  6.                                 {
  7.                                     throw new Exception("invalid userdata for UnityEngine.Vector3");
  8.                                 }
  9.                                
  10.                 IntPtr buff = LuaAPI.lua_touserdata(L, index);
  11.                 if (!CopyByValue.Pack(buff, 0,  val))
  12.                 {
  13.                     throw new Exception("pack fail for UnityEngine.Vector3 ,value="+val);
  14.                 }
  15.             }
  16.             else
  17.             {
  18.                 throw new Exception("try to update a data with lua type:" + LuaAPI.lua_type(L, index));
  19.             }
  20.         }
复制代码
这里看到对应lua来说C#的布局体、类都是UserData。C#想要去改变lua内的内存利用
  1. CopyByValue.Pack函数进行拷贝
复制代码
再拿个GameObject的Component举例,加深下印象:
  1. luaenv.DoString(@"local v1 = CS.UnityEngine.GameObject()
  2.                   local v2 = v1:AddComponent(typeof(CS.UnityEngine.Camera))
  3.                 ");
  4. [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  5.         static int _m_AddComponent(RealStatePtr L)
  6.         {
  7.                     try {
  8.             
  9.                 ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  10.             
  11.             
  12.                 UnityEngine.GameObject gen_to_be_invoked = (UnityEngine.GameObject)translator.FastGetCSObj(L, 1);
  13.             
  14.             
  15.                
  16.                 {
  17.                     System.Type _componentType = (System.Type)translator.GetObject(L, 2, typeof(System.Type));
  18.                     
  19.                         var gen_ret = gen_to_be_invoked.AddComponent( _componentType );
  20.                         translator.Push(L, gen_ret);
  21.                     
  22.                     
  23.                     
  24.                     return 1;
  25.                 }
  26.                
  27.             } catch(System.Exception gen_e) {
  28.                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  29.             }
  30.             
  31.         }
复制代码
这里有个函数getCsObj用于取游戏对象
  1. private object getCsObj(RealStatePtr L, int index, int udata)
  2.         {
  3.             object obj;
  4.             if (udata == -1)
  5.             {
  6.                 if (LuaAPI.lua_type(L, index) != LuaTypes.LUA_TUSERDATA) return null;
  7.                 Type type = GetTypeOf(L, index);
  8.                 if (type == typeof(decimal))
  9.                 {
  10.                     decimal v;
  11.                     Get(L, index, out v);
  12.                     return v;
  13.                 }
  14.                 GetCSObject get;
  15.                 if (type != null && custom_get_funcs.TryGetValue(type, out get))
  16.                 {
  17.                     return get(L, index);
  18.                 }
  19.                 else
  20.                 {
  21.                     return null;
  22.                 }
  23.             }
  24.             else if (objects.TryGetValue(udata, out obj))
  25.             {
  26. #if !UNITY_5 && !XLUA_GENERAL && !UNITY_2017 && !UNITY_2017_1_OR_NEWER && !UNITY_2018
  27.                 if (obj != null && obj is UnityEngine.Object && ((obj as UnityEngine.Object) == null))
  28.                 {
  29.                     //throw new UnityEngine.MissingReferenceException("The object of type '"+ obj.GetType().Name +"' has been destroyed but you are still trying to access it.");
  30.                     return null;
  31.                 }
  32. #endif
  33.                 return obj;
  34.             }
  35.             return null;
  36.         }
复制代码
这里从一个objects字典去查找游戏的对象。跟Vector3有区别。lua创建GameObject的过程会走CS的元表方法(在上篇有介绍),调用c#的Import方法,会把这个GameObject举行注册方法,加入到objects举行维护。

额外测试了删除,发现假如不触发gc,object池不会删除对象,哪怕C#实际上已经删除了


总结:Wrap文件是lua与C#通讯中间代码文件,主要实现方式就是从lua堆栈取出lua数据对象,调用C#代码然后把效果再压栈到堆栈中。
像代码 
local v1 = CS.UnityEngine.Vector3(1,2,3)
v1:Set(4,5,6)
性能显着要优于
v1.x = 4
v2.y = 5
v3.z = 6
压栈少了4次,拷贝次数少了2次
二.Wrap文件生成

•流程:
•1.Generator网络这种范例需要导出的对象
•2.通过LuaTemplate把对应的.tpl.txt文件转成可实验的lua代码
•3.在GenOne方法里给上一步生成的lua代码赋值全局变量
•4.实验lua代码生成wrap文件
映射模板目录:

生成中间代码文件部分

XLua.Utils.GetAllTypes:网络工程全部元数据
ps:这步可以直接举行改造,让其直接对有效元数据举行筛选,稍微节约一点编译时间
GetGenConfig:对元数据举行过滤筛选出需要lua与C#通讯的元数据
以Lua通讯C#代码为例:
老师成一个List,然后去获取全部打上LuaCallCSharp标签的元数据,举行添加,末了在用Linq表达式举行一遍筛选。



实验脚本TemplateCommon,在lua里填充table数据,构造好后去生成Wrap文件
对于每个类都会走到GenOne来生成Wrap文件

以GameObjectWrap文件生成为例:
模板对应文件:
  1. #if USE_UNI_LUA
  2. using LuaAPI = UniLua.Lua;
  3. using RealStatePtr = UniLua.ILuaState;
  4. using LuaCSFunction = UniLua.CSharpFunctionDelegate;
  5. #else
  6. using LuaAPI = XLua.LuaDLL.Lua;
  7. using RealStatePtr = System.IntPtr;
  8. using LuaCSFunction = XLua.LuaDLL.lua_CSFunction;
  9. #endif
  10. using XLua;
  11. using System.Collections.Generic;
  12. <%ForEachCsList(namespaces, function(namespace)%>using <%=namespace%>;<%end)%>
  13. <%
  14. require "TemplateCommon"
  15. local OpNameMap = {
  16.     op_Addition = "__AddMeta",
  17.         op_Subtraction = "__SubMeta",
  18.         op_Multiply = "__MulMeta",
  19.         op_Division = "__DivMeta",
  20.         op_Equality = "__EqMeta",
  21.         op_UnaryNegation = "__UnmMeta",
  22.         op_LessThan = "__LTMeta",
  23.         op_LessThanOrEqual = "__LEMeta",
  24.         op_Modulus = "__ModMeta",
  25.     op_BitwiseAnd = "__BandMeta",
  26.     op_BitwiseOr = "__BorMeta",
  27.     op_ExclusiveOr = "__BxorMeta",
  28.     op_OnesComplement = "__BnotMeta",
  29.     op_LeftShift = "__ShlMeta",
  30.     op_RightShift = "__ShrMeta",
  31. }
  32. local OpCallNameMap = {
  33.     op_Addition = "+",
  34.         op_Subtraction = "-",
  35.         op_Multiply = "*",
  36.         op_Division = "/",
  37.         op_Equality = "==",
  38.         op_UnaryNegation = "-",
  39.         op_LessThan = "<",
  40.         op_LessThanOrEqual = "<=",
  41.         op_Modulus = "%",
  42.         op_BitwiseAnd = "&",
  43.     op_BitwiseOr = "|",
  44.     op_ExclusiveOr = "^",
  45.     op_OnesComplement = "~",
  46.     op_LeftShift = "<<",
  47.     op_RightShift = ">>",
  48. }
  49. local obj_method_count = 0
  50. local obj_getter_count = 0
  51. local obj_setter_count = 0
  52. local meta_func_count = operators.Count
  53. local cls_field_count = 1
  54. local cls_getter_count = 0
  55. local cls_setter_count = 0
  56. ForEachCsList(methods, function(method)
  57.     if method.IsStatic then
  58.             cls_field_count = cls_field_count + 1
  59.         else
  60.             obj_method_count = obj_method_count + 1
  61.     end
  62. end)
  63. ForEachCsList(events, function(event)
  64.     if event.IsStatic then
  65.             cls_field_count = cls_field_count + 1
  66.         else
  67.             obj_method_count = obj_method_count + 1
  68.     end
  69. end)
  70. ForEachCsList(getters, function(getter)
  71.     if getter.IsStatic then
  72.             if getter.ReadOnly then
  73.                 cls_field_count = cls_field_count + 1
  74.             else
  75.                     cls_getter_count = cls_getter_count + 1
  76.                 end
  77.         else
  78.             obj_getter_count = obj_getter_count + 1
  79.     end
  80. end)
  81. ForEachCsList(setters, function(setter)
  82.     if setter.IsStatic then
  83.             cls_setter_count = cls_setter_count + 1
  84.         else
  85.             obj_setter_count = obj_setter_count + 1
  86.     end
  87. end)
  88. ForEachCsList(lazymembers, function(lazymember)
  89.     if lazymember.IsStatic == 'true' then
  90.             if 'CLS_IDX' == lazymember.Index then
  91.                     cls_field_count = cls_field_count + 1
  92.             elseif 'CLS_GETTER_IDX' == lazymember.Index then
  93.                     cls_getter_count = cls_getter_count + 1
  94.                 elseif 'CLS_SETTER_IDX' == lazymember.Index then
  95.                     cls_setter_count = cls_setter_count + 1
  96.                 end
  97.         else
  98.                 if 'METHOD_IDX' == lazymember.Index then
  99.                     obj_method_count = obj_method_count + 1
  100.             elseif 'GETTER_IDX' == lazymember.Index then
  101.                     obj_getter_count = obj_getter_count + 1
  102.                 elseif 'SETTER_IDX' == lazymember.Index then
  103.                     obj_setter_count = obj_setter_count + 1
  104.                 end
  105.         end
  106. end)
  107. local generic_arg_list, type_constraints = GenericArgumentList(type)
  108. %>
  109. namespace XLua.CSObjectWrap
  110. {
  111.     using Utils = XLua.Utils;
  112.     public class <%=CSVariableName(type)%>Wrap<%=generic_arg_list%> <%=type_constraints%>
  113.     {
  114.         public static void __Register(RealStatePtr L)
  115.         {
  116.                         ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  117.                         System.Type type = typeof(<%=CsFullTypeName(type)%>);
  118.                         Utils.BeginObjectRegister(type, L, translator, <%=meta_func_count%>, <%=obj_method_count%>, <%=obj_getter_count%>, <%=obj_setter_count%>);
  119.                         <%ForEachCsList(operators, function(operator)%>Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "<%=(OpNameMap[operator.Name]):gsub('Meta', ''):lower()%>", <%=OpNameMap[operator.Name]%>);
  120.             <%end)%>
  121.                         <%ForEachCsList(methods, function(method) if not method.IsStatic then %>Utils.RegisterFunc(L, Utils.METHOD_IDX, "<%=method.Name%>", _m_<%=method.Name%>);
  122.                         <% end end)%>
  123.                         <%ForEachCsList(events, function(event) if not event.IsStatic then %>Utils.RegisterFunc(L, Utils.METHOD_IDX, "<%=event.Name%>", _e_<%=event.Name%>);
  124.                         <% end end)%>
  125.                         <%ForEachCsList(getters, function(getter) if not getter.IsStatic then %>Utils.RegisterFunc(L, Utils.GETTER_IDX, "<%=getter.Name%>", _g_get_<%=getter.Name%>);
  126.             <%end end)%>
  127.                         <%ForEachCsList(setters, function(setter) if not setter.IsStatic then %>Utils.RegisterFunc(L, Utils.SETTER_IDX, "<%=setter.Name%>", _s_set_<%=setter.Name%>);
  128.             <%end end)%>
  129.                         <%ForEachCsList(lazymembers, function(lazymember) if lazymember.IsStatic == 'false' then %>Utils.RegisterLazyFunc(L, Utils.<%=lazymember.Index%>, "<%=lazymember.Name%>", type, <%=lazymember.MemberType%>, <%=lazymember.IsStatic%>);
  130.             <%end end)%>
  131.                         Utils.EndObjectRegister(type, L, translator, <% if type.IsArray or ((indexers.Count or 0) > 0) then %>__CSIndexer<%else%>null<%end%>, <%if type.IsArray or ((newindexers.Count or 0) > 0) then%>__NewIndexer<%else%>null<%end%>,
  132.                             null, null, null);
  133.                     Utils.BeginClassRegister(type, L, __CreateInstance, <%=cls_field_count%>, <%=cls_getter_count%>, <%=cls_setter_count%>);
  134.                         <%ForEachCsList(methods, function(method) if method.IsStatic then %>Utils.RegisterFunc(L, Utils.CLS_IDX, "<%=method.Overloads[0].Name%>", _m_<%=method.Name%>);
  135.             <% end end)%>
  136.                         <%ForEachCsList(events, function(event) if event.IsStatic then %>Utils.RegisterFunc(L, Utils.CLS_IDX, "<%=event.Name%>", _e_<%=event.Name%>);
  137.                         <% end end)%>
  138.             <%ForEachCsList(getters, function(getter) if getter.IsStatic and getter.ReadOnly then %>Utils.RegisterObject(L, translator, Utils.CLS_IDX, "<%=getter.Name%>", <%=CsFullTypeName(type).."."..getter.Name%>);
  139.             <%end end)%>
  140.                         <%ForEachCsList(getters, function(getter) if getter.IsStatic and (not getter.ReadOnly) then %>Utils.RegisterFunc(L, Utils.CLS_GETTER_IDX, "<%=getter.Name%>", _g_get_<%=getter.Name%>);
  141.             <%end end)%>
  142.                         <%ForEachCsList(setters, function(setter) if setter.IsStatic then %>Utils.RegisterFunc(L, Utils.CLS_SETTER_IDX, "<%=setter.Name%>", _s_set_<%=setter.Name%>);
  143.             <%end end)%>
  144.                         <%ForEachCsList(lazymembers, function(lazymember) if lazymember.IsStatic == 'true' then %>Utils.RegisterLazyFunc(L, Utils.<%=lazymember.Index%>, "<%=lazymember.Name%>", type, <%=lazymember.MemberType%>, <%=lazymember.IsStatic%>);
  145.             <%end end)%>
  146.                         Utils.EndClassRegister(type, L, translator);
  147.         }
  148.         
  149.         [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  150.         static int __CreateInstance(RealStatePtr L)
  151.         {
  152.             <%
  153.             if constructors.Count == 0 and (not type.IsValueType)  then
  154.             %>return LuaAPI.luaL_error(L, "<%=CsFullTypeName(type)%> does not have a constructor!");<%
  155.             else %>
  156.                         try {
  157.                 ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  158.                                 <%
  159.                                 local hasZeroParamsCtor = false
  160.                                 ForEachCsList(constructors, function(constructor, ci)
  161.                                         local parameters = constructor:GetParameters()
  162.                                         if parameters.Length == 0 then
  163.                                             hasZeroParamsCtor = true
  164.                                         end
  165.                                         local def_count = constructor_def_vals[ci]
  166.                                         local param_count = parameters.Length
  167.                                         local in_num = CalcCsList(parameters, function(p) return not (p.IsOut and p.ParameterType.IsByRef) end)
  168.                     local out_num = CalcCsList(parameters, function(p) return p.IsOut or p.ParameterType.IsByRef end)
  169.                                         local real_param_count = param_count - def_count
  170.                     local has_v_params = param_count > 0 and IsParams(parameters[param_count - 1])
  171.                                         local in_pos = 0
  172.                                 %>if(LuaAPI.lua_gettop(L) <%=has_v_params and ">=" or "=="%> <%=in_num + 1 - def_count - (has_v_params and 1 or 0)%><%ForEachCsList(parameters, function(parameter, pi)
  173.                 if pi >= real_param_count then return end
  174.                 local parameterType = parameter.ParameterType
  175.                 if has_v_params and pi == param_count - 1 then  parameterType = parameterType:GetElementType() end
  176.                                 if not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1
  177.                 %> && <%=GetCheckStatement(parameterType, in_pos+1, has_v_params and pi == param_count - 1)%><%
  178.                                 end
  179.                                 end)%>)
  180.                                 {
  181.                                         <%ForEachCsList(parameters, function(parameter, pi)
  182.                     if pi >= real_param_count then return end
  183.                     %><%=GetCasterStatement(parameter.ParameterType, pi+2, LocalName(parameter.Name), true, has_v_params and pi == param_count - 1)%>;
  184.                                         <%end)%>
  185.                                         var gen_ret = new <%=CsFullTypeName(type)%>(<%ForEachCsList(parameters, function(parameter, pi) if pi >= real_param_count then return end; if pi ~=0 then %><%=', '%><% end ;if parameter.IsOut and parameter.ParameterType.IsByRef then %>out <% elseif parameter.ParameterType.IsByRef and not parameter.IsIn then %>ref <% end %><%=LocalName(parameter.Name)%><% end)%>);
  186.                                         <%=GetPushStatement(type, "gen_ret")%>;
  187.                     <%local in_pos = 0
  188.                     ForEachCsList(parameters, function(parameter, pi)
  189.                         if pi >= real_param_count then return end
  190.                         if not (parameter.IsOut and parameter.ParameterType.IsByRef) then
  191.                             in_pos = in_pos + 1
  192.                         end
  193.                         if parameter.ParameterType.IsByRef then
  194.                         %><%=GetPushStatement(parameter.ParameterType:GetElementType(), LocalName(parameter.Name))%>;
  195.                         <%if not parameter.IsOut and parameter.ParameterType.IsByRef and NeedUpdate(parameter.ParameterType) then
  196.                   %><%=GetUpdateStatement(parameter.ParameterType:GetElementType(), in_pos+1, LocalName(parameter.Name))%>;
  197.                         <%end%>
  198.                     <%
  199.                         end
  200.                     end)
  201.                     %>
  202.                                         return <%=out_num + 1%>;
  203.                                 }
  204.                                 <%end)
  205.                                 if (not hasZeroParamsCtor) and type.IsValueType then
  206.                                 %>
  207.                                 if (LuaAPI.lua_gettop(L) == 1)
  208.                                 {
  209.                                     <%=GetPushStatement(type, "default(" .. CsFullTypeName(type).. ")")%>;
  210.                                 return 1;
  211.                                 }
  212.                                 <%end%>
  213.                         }
  214.                         catch(System.Exception gen_e) {
  215.                                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  216.                         }
  217.             return LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%> constructor!");
  218.             <% end %>
  219.         }
  220.         
  221.                 <% if type.IsArray or ((indexers.Count or 0) > 0) then %>
  222.         [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  223.         public static int __CSIndexer(RealStatePtr L)
  224.         {
  225.                         <%if type.IsArray then %>
  226.                         try {
  227.                             ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  228.                        
  229.                                 if (<%=GetCheckStatement(type, 1)%> && LuaAPI.lua_isnumber(L, 2))
  230.                                 {
  231.                                         int index = (int)LuaAPI.lua_tonumber(L, 2);
  232.                                         <%=GetSelfStatement(type)%>;
  233.                                         LuaAPI.lua_pushboolean(L, true);
  234.                                         <%=GetPushStatement(type:GetElementType(), "gen_to_be_invoked[index]")%>;
  235.                                         return 2;
  236.                                 }
  237.                         }
  238.                         catch(System.Exception gen_e) {
  239.                                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  240.                         }
  241.                         <%elseif indexers.Count > 0 then
  242.                         %>try {
  243.                             ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  244.                                 <%
  245.                                         ForEachCsList(indexers, function(indexer)
  246.                                                 local paramter = indexer:GetParameters()[0]
  247.                                 %>
  248.                                 if (<%=GetCheckStatement(type, 1)%> && <%=GetCheckStatement(paramter.ParameterType, 2)%>)
  249.                                 {
  250.                                        
  251.                                         <%=GetSelfStatement(type)%>;
  252.                                         <%=GetCasterStatement(paramter.ParameterType, 2, "index", true)%>;
  253.                                         LuaAPI.lua_pushboolean(L, true);
  254.                                         <%=GetPushStatement(indexer.ReturnType, "gen_to_be_invoked[index]")%>;
  255.                                         return 2;
  256.                                 }
  257.                                 <%end)%>
  258.                         }
  259.                         catch(System.Exception gen_e) {
  260.                                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  261.                         }
  262.                         <%end%>
  263.             LuaAPI.lua_pushboolean(L, false);
  264.                         return 1;
  265.         }
  266.                 <% end %>
  267.         
  268.                 <%if type.IsArray or ((newindexers.Count or 0) > 0) then%>
  269.         [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  270.         public static int __NewIndexer(RealStatePtr L)
  271.         {
  272.                         <%if type.IsArray or newindexers.Count > 0 then %>ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);<%end%>
  273.                         <%if type.IsArray then
  274.                                 local elementType = type:GetElementType()
  275.                         %>
  276.                         try {
  277.                                 if (<%=GetCheckStatement(type, 1)%> && LuaAPI.lua_isnumber(L, 2) && <%=GetCheckStatement(elementType, 3)%>)
  278.                                 {
  279.                                         int index = (int)LuaAPI.lua_tonumber(L, 2);
  280.                                         <%=GetSelfStatement(type)%>;
  281.                                         <%=GetCasterStatement(elementType, 3, "gen_to_be_invoked[index]")%>;
  282.                                         LuaAPI.lua_pushboolean(L, true);
  283.                                         return 1;
  284.                                 }
  285.                         }
  286.                         catch(System.Exception gen_e) {
  287.                                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  288.                         }
  289.                         <%elseif newindexers.Count > 0 then%>
  290.                         try {
  291.                                 <%ForEachCsList(newindexers, function(newindexer)
  292.                                                 local keyType = newindexer:GetParameters()[0].ParameterType
  293.                                                 local valueType = newindexer:GetParameters()[1].ParameterType
  294.                                 %>
  295.                                 if (<%=GetCheckStatement(type, 1)%> && <%=GetCheckStatement(keyType, 2)%> && <%=GetCheckStatement(valueType, 3)%>)
  296.                                 {
  297.                                        
  298.                                         <%=GetSelfStatement(type)%>;
  299.                                         <%=GetCasterStatement(keyType, 2, "key", true)%>;
  300.                                         <%if IsStruct(valueType) then%><%=GetCasterStatement(valueType, 3, "gen_value", true)%>;
  301.                                         gen_to_be_invoked[key] = gen_value;<%else
  302.                   %><%=GetCasterStatement(valueType, 3, "gen_to_be_invoked[key]")%>;<%end%>
  303.                                         LuaAPI.lua_pushboolean(L, true);
  304.                                         return 1;
  305.                                 }
  306.                                 <%end)%>
  307.                         }
  308.                         catch(System.Exception gen_e) {
  309.                                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  310.                         }
  311.                         <%end%>
  312.                         LuaAPI.lua_pushboolean(L, false);
  313.             return 1;
  314.         }
  315.                 <% end %>
  316.         
  317.         <%ForEachCsList(operators, function(operator) %>
  318.         [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  319.         static int <%=OpNameMap[operator.Name]%>(RealStatePtr L)
  320.         {
  321.             <% if operator.Name ~= "op_UnaryNegation" and operator.Name ~= "op_OnesComplement"  then %>
  322.                         try {
  323.                 ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  324.             <%ForEachCsList(operator.Overloads, function(overload)
  325.                 local left_param = overload:GetParameters()[0]
  326.                 local right_param = overload:GetParameters()[1]
  327.             %>
  328.                        
  329.                                 if (<%=GetCheckStatement(left_param.ParameterType, 1)%> && <%=GetCheckStatement(right_param.ParameterType, 2)%>)
  330.                                 {
  331.                                         <%=GetCasterStatement(left_param.ParameterType, 1, "leftside", true)%>;
  332.                                         <%=GetCasterStatement(right_param.ParameterType, 2, "rightside", true)%>;
  333.                                        
  334.                                         <%=GetPushStatement(overload.ReturnType, "leftside " .. OpCallNameMap[operator.Name] .. " rightside")%>;
  335.                                        
  336.                                         return 1;
  337.                                 }
  338.             <%end)%>
  339.                         }
  340.                         catch(System.Exception gen_e) {
  341.                                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  342.                         }
  343.             return LuaAPI.luaL_error(L, "invalid arguments to right hand of <%=OpCallNameMap[operator.Name]%> operator, need <%=CsFullTypeName(type)%>!");
  344.             <%else%>
  345.                         ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  346.             try {
  347.                 <%=GetCasterStatement(type, 1, "rightside", true)%>;
  348.                 <%=GetPushStatement(operator.Overloads[0].ReturnType, OpCallNameMap[operator.Name] .. " rightside")%>;
  349.             } catch(System.Exception gen_e) {
  350.                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  351.             }
  352.             return 1;
  353.             <%end%>
  354.         }
  355.         <%end)%>
  356.         
  357.         <%ForEachCsList(methods, function(method)%>
  358.         [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  359.         static int _m_<%=method.Name%>(RealStatePtr L)
  360.         {
  361.                     try {
  362.             <%
  363.             local need_obj = not method.IsStatic
  364.             if MethodCallNeedTranslator(method) then
  365.             %>
  366.                 ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  367.             <%end%>
  368.             <%if need_obj then%>
  369.                 <%=GetSelfStatement(type)%>;
  370.             <%end%>
  371.             <%if method.Overloads.Count > 1 then%>
  372.                             int gen_param_count = LuaAPI.lua_gettop(L);
  373.             <%end%>
  374.                 <%ForEachCsList(method.Overloads, function(overload, oi)
  375.                 local parameters = MethodParameters(overload)
  376.                 local in_num = CalcCsList(parameters, function(p) return not (p.IsOut and p.ParameterType.IsByRef) end)
  377.                 local param_offset = method.IsStatic and 0 or 1
  378.                 local out_num = CalcCsList(parameters, function(p) return p.IsOut or p.ParameterType.IsByRef end)
  379.                 local in_pos = 0
  380.                 local has_return = (overload.ReturnType.FullName ~= "System.Void")
  381.                 local def_count = method.DefaultValues[oi]
  382.                                 local param_count = parameters.Length
  383.                 local real_param_count = param_count - def_count
  384.                 local has_v_params = param_count > 0 and IsParams(parameters[param_count - 1])
  385.                 if method.Overloads.Count > 1 then
  386.                 %>if(gen_param_count <%=has_v_params and ">=" or "=="%> <%=in_num+param_offset-def_count - (has_v_params and 1 or 0)%><%
  387.                     ForEachCsList(parameters, function(parameter, pi)
  388.                         if pi >= real_param_count then return end
  389.                         local parameterType = parameter.ParameterType
  390.                         if has_v_params and pi == param_count - 1 then  parameterType = parameterType:GetElementType() end
  391.                         if not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1;
  392.                         %>&& <%=GetCheckStatement(parameterType , in_pos+param_offset, has_v_params and pi == param_count - 1)%><%
  393.                         end
  394.                     end)%>) <%end%>
  395.                 {
  396.                     <%if overload.Name == "get_Item" and overload.IsSpecialName then
  397.                                             local keyType = overload:GetParameters()[0].ParameterType%>
  398.                                         <%=GetCasterStatement(keyType, 2, "key", true)%>;
  399.                                         <%=GetPushStatement(overload.ReturnType, "gen_to_be_invoked[key]")%>;
  400.                                         <%elseif overload.Name == "set_Item" and overload.IsSpecialName then
  401.                                             local keyType = overload:GetParameters()[0].ParameterType
  402.                                                 local valueType = overload:GetParameters()[1].ParameterType%>
  403.                                         <%=GetCasterStatement(keyType, 2, "key", true)%>;
  404.                                         <%=GetCasterStatement(valueType, 3, "gen_value", true)%>;
  405.                     gen_to_be_invoked[key] = gen_value;
  406.                     <% else
  407.                     in_pos = 0;
  408.                     ForEachCsList(parameters, function(parameter, pi)
  409.                         if pi >= real_param_count then return end
  410.                         %><%if not (parameter.IsOut and parameter.ParameterType.IsByRef) then
  411.                             in_pos = in_pos + 1
  412.                         %><%=GetCasterStatement(parameter.ParameterType, in_pos+param_offset, LocalName(parameter.Name), true, has_v_params and pi == param_count - 1)%><%
  413.                                             else%><%=CsFullTypeName(parameter.ParameterType)%> <%=LocalName(parameter.Name)%><%end%>;
  414.                     <%end)%>
  415.                     <%
  416.                     if has_return then
  417.                         %>    var gen_ret = <%
  418.                     end
  419.                     %><%if method.IsStatic then
  420.                     %><%=CsFullTypeName(type).."."..UnK(overload.Name)%><%
  421.                     else
  422.                     %>gen_to_be_invoked.<%=UnK(overload.Name)%><%
  423.                     end%>( <%ForEachCsList(parameters, function(parameter, pi)
  424.                         if pi >= real_param_count then return end
  425.                         if pi ~= 0 then %>, <% end; if parameter.IsOut and parameter.ParameterType.IsByRef then %>out <% elseif parameter.ParameterType.IsByRef and not parameter.IsIn then %>ref <% end %><%=LocalName(parameter.Name)%><% end) %> );
  426.                     <%
  427.                     if has_return then
  428.                     %>    <%=GetPushStatement(overload.ReturnType, "gen_ret")%>;
  429.                     <%
  430.                     end
  431.                     local in_pos = 0
  432.                     ForEachCsList(parameters, function(parameter, pi)
  433.                         if pi >= real_param_count then return end
  434.                         if not (parameter.IsOut and parameter.ParameterType.IsByRef) then
  435.                             in_pos = in_pos + 1
  436.                         end
  437.                         if parameter.ParameterType.IsByRef then
  438.                         %><%=GetPushStatement(parameter.ParameterType:GetElementType(), LocalName(parameter.Name))%>;
  439.                         <%if not parameter.IsOut and parameter.ParameterType.IsByRef and NeedUpdate(parameter.ParameterType) then
  440.                   %><%=GetUpdateStatement(parameter.ParameterType:GetElementType(), in_pos+param_offset, LocalName(parameter.Name))%>;
  441.                         <%end%>
  442.                     <%
  443.                         end
  444.                     end)
  445.                                         end
  446.                     %>
  447.                     <%if NeedUpdate(type) and not method.IsStatic then%>
  448.                         <%=GetUpdateStatement(type, 1, "gen_to_be_invoked")%>;
  449.                     <%end%>
  450.                     
  451.                     return <%=out_num+(has_return and 1 or 0)%>;
  452.                 }
  453.                 <% end)%>
  454.             } catch(System.Exception gen_e) {
  455.                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  456.             }
  457.             <%if method.Overloads.Count > 1 then%>
  458.             return LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%>.<%=method.Overloads[0].Name%>!");
  459.             <%end%>
  460.         }
  461.         <% end)%>
  462.         
  463.         
  464.         <%ForEachCsList(getters, function(getter)
  465.         if getter.IsStatic and getter.ReadOnly then return end --readonly static
  466.         %>
  467.         [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  468.         static int _g_get_<%=getter.Name%>(RealStatePtr L)
  469.         {
  470.                     try {
  471.             <%if AccessorNeedTranslator(getter) then %>    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);<%end%>
  472.                         <%if not getter.IsStatic then%>
  473.                 <%=GetSelfStatement(type)%>;
  474.                 <%=GetPushStatement(getter.Type, "gen_to_be_invoked."..UnK(getter.Name))%>;<% else %>    <%=GetPushStatement(getter.Type, CsFullTypeName(type).."."..UnK(getter.Name))%>;<% end%>
  475.             } catch(System.Exception gen_e) {
  476.                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  477.             }
  478.             return 1;
  479.         }
  480.         <%end)%>
  481.         
  482.         <%ForEachCsList(setters, function(setter)
  483.         local is_struct = IsStruct(setter.Type)
  484.         %>
  485.         [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  486.         static int _s_set_<%=setter.Name%>(RealStatePtr L)
  487.         {
  488.                     try {
  489.                 <%if AccessorNeedTranslator(setter) then %>ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);<%end%>
  490.                         <%if not setter.IsStatic then %>
  491.                 <%=GetSelfStatement(type)%>;
  492.                 <%if is_struct then %><%=GetCasterStatement(setter.Type, 2, "gen_value", true)%>;
  493.                                 gen_to_be_invoked.<%=UnK(setter.Name)%> = gen_value;<% else
  494.               %><%=GetCasterStatement(setter.Type, 2, "gen_to_be_invoked." .. UnK(setter.Name))%>;<%end
  495.             else
  496.                                 if is_struct then %><%=GetCasterStatement(setter.Type, 1, "gen_value", true)%>;
  497.                                 <%=CsFullTypeName(type)%>.<%=UnK(setter.Name)%> = gen_value;<%else
  498.           %>    <%=GetCasterStatement(setter.Type, 1, CsFullTypeName(type) .."." .. UnK(setter.Name))%>;<%end
  499.             end%>
  500.             <%if NeedUpdate(type) and not setter.IsStatic then%>
  501.                 <%=GetUpdateStatement(type, 1, "gen_to_be_invoked")%>;
  502.             <%end%>
  503.             } catch(System.Exception gen_e) {
  504.                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  505.             }
  506.             return 0;
  507.         }
  508.         <%end)%>
  509.                
  510.                 <%ForEachCsList(events, function(event) if not event.IsStatic then %>
  511.         [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  512.         static int _e_<%=event.Name%>(RealStatePtr L)
  513.         {
  514.                     try {
  515.                 ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  516.                             int gen_param_count = LuaAPI.lua_gettop(L);
  517.                         <%=GetSelfStatement(type)%>;
  518.                 <%=GetCasterStatement(event.Type, 3, "gen_delegate", true)%>;
  519.                 if (gen_delegate == null) {
  520.                     return LuaAPI.luaL_error(L, "#3 need <%=CsFullTypeName(event.Type)%>!");
  521.                 }
  522.                                
  523.                                 if (gen_param_count == 3)
  524.                                 {
  525.                                         <%if event.CanAdd then%>
  526.                                         if (LuaAPI.xlua_is_eq_str(L, 2, "+")) {
  527.                                                 gen_to_be_invoked.<%=UnK(event.Name)%> += gen_delegate;
  528.                                                 return 0;
  529.                                         }
  530.                                         <%end%>
  531.                                         <%if event.CanRemove then%>
  532.                                         if (LuaAPI.xlua_is_eq_str(L, 2, "-")) {
  533.                                                 gen_to_be_invoked.<%=UnK(event.Name)%> -= gen_delegate;
  534.                                                 return 0;
  535.                                         }
  536.                                         <%end%>
  537.                                 }
  538.                         } catch(System.Exception gen_e) {
  539.                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  540.             }
  541.                         LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%>.<%=event.Name%>!");
  542.             return 0;
  543.         }
  544.         <%end end)%>
  545.                
  546.                 <%ForEachCsList(events, function(event) if event.IsStatic then %>
  547.         [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
  548.         static int _e_<%=event.Name%>(RealStatePtr L)
  549.         {
  550.                     try {
  551.                 ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
  552.                             int gen_param_count = LuaAPI.lua_gettop(L);
  553.                 <%=GetCasterStatement(event.Type, 2, "gen_delegate", true)%>;
  554.                 if (gen_delegate == null) {
  555.                     return LuaAPI.luaL_error(L, "#2 need <%=CsFullTypeName(event.Type)%>!");
  556.                 }
  557.                
  558.                                 <%if event.CanAdd then%>
  559.                                 if (gen_param_count == 2 && LuaAPI.xlua_is_eq_str(L, 1, "+")) {
  560.                                         <%=CsFullTypeName(type)%>.<%=UnK(event.Name)%> += gen_delegate;
  561.                                         return 0;
  562.                                 }
  563.                                 <%end%>
  564.                                 <%if event.CanRemove then%>
  565.                                 if (gen_param_count == 2 && LuaAPI.xlua_is_eq_str(L, 1, "-")) {
  566.                                         <%=CsFullTypeName(type)%>.<%=UnK(event.Name)%> -= gen_delegate;
  567.                                         return 0;
  568.                                 }
  569.                                 <%end%>
  570.                         } catch(System.Exception gen_e) {
  571.                 return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
  572.             }
  573.                         return LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%>.<%=event.Name%>!");
  574.         }
  575.         <%end end)%>
  576.     }
  577. }
复制代码
这里很多多少的 如namespace,ForEachCsList,CSVariableName等运行时会被对应的GameObject替换。
再打一下这个文件被预编译后的文件:
  1. local __text_gen = {}
  2. table.insert(__text_gen, "#if USE_UNI_LUA\r\nusing LuaAPI = UniLua.Lua;\r\nusing RealStatePtr = UniLua.ILuaState;\r\nusing LuaCSFunction = UniLua.CSharpFunctionDelegate;\r\n#else\r\nusing LuaAPI = XLua.LuaDLL.Lua;\r\nusing RealStatePtr = System.IntPtr;\r\nusing LuaCSFunction = XLua.LuaDLL.lua_CSFunction;\r\n#endif\r\n\r\nusing XLua;\r\nusing System.Collections.Generic;\r\n")
  3. ForEachCsList(namespaces, function(namespace)
  4. table.insert(__text_gen, "using ")
  5. table.insert(__text_gen, tostring(namespace))
  6. table.insert(__text_gen, ";")
  7. end)
  8. table.insert(__text_gen, "\r\n")
  9. require "TemplateCommon"
  10. local OpNameMap = {
  11.     op_Addition = "__AddMeta",
  12.         op_Subtraction = "__SubMeta",
  13.         op_Multiply = "__MulMeta",
  14.         op_Division = "__DivMeta",
  15.         op_Equality = "__EqMeta",
  16.         op_UnaryNegation = "__UnmMeta",
  17.         op_LessThan = "__LTMeta",
  18.         op_LessThanOrEqual = "__LEMeta",
  19.         op_Modulus = "__ModMeta",
  20.     op_BitwiseAnd = "__BandMeta",
  21.     op_BitwiseOr = "__BorMeta",
  22.     op_ExclusiveOr = "__BxorMeta",
  23.     op_OnesComplement = "__BnotMeta",
  24.     op_LeftShift = "__ShlMeta",
  25.     op_RightShift = "__ShrMeta",
  26. }
  27. local OpCallNameMap = {
  28.     op_Addition = "+",
  29.         op_Subtraction = "-",
  30.         op_Multiply = "*",
  31.         op_Division = "/",
  32.         op_Equality = "==",
  33.         op_UnaryNegation = "-",
  34.         op_LessThan = "<",
  35.         op_LessThanOrEqual = "<=",
  36.         op_Modulus = "%",
  37.         op_BitwiseAnd = "&",
  38.     op_BitwiseOr = "|",
  39.     op_ExclusiveOr = "^",
  40.     op_OnesComplement = "~",
  41.     op_LeftShift = "<<",
  42.     op_RightShift = ">>",
  43. }
  44. local obj_method_count = 0
  45. local obj_getter_count = 0
  46. local obj_setter_count = 0
  47. local meta_func_count = operators.Count
  48. local cls_field_count = 1
  49. local cls_getter_count = 0
  50. local cls_setter_count = 0
  51. ForEachCsList(methods, function(method)
  52.     if method.IsStatic then
  53.             cls_field_count = cls_field_count + 1
  54.         else
  55.             obj_method_count = obj_method_count + 1
  56.     end
  57. end)
  58. ForEachCsList(events, function(event)
  59.     if event.IsStatic then
  60.             cls_field_count = cls_field_count + 1
  61.         else
  62.             obj_method_count = obj_method_count + 1
  63.     end
  64. end)
  65. ForEachCsList(getters, function(getter)
  66.     if getter.IsStatic then
  67.             if getter.ReadOnly then
  68.                 cls_field_count = cls_field_count + 1
  69.             else
  70.                     cls_getter_count = cls_getter_count + 1
  71.                 end
  72.         else
  73.             obj_getter_count = obj_getter_count + 1
  74.     end
  75. end)
  76. ForEachCsList(setters, function(setter)
  77.     if setter.IsStatic then
  78.             cls_setter_count = cls_setter_count + 1
  79.         else
  80.             obj_setter_count = obj_setter_count + 1
  81.     end
  82. end)
  83. ForEachCsList(lazymembers, function(lazymember)
  84.     if lazymember.IsStatic == 'true' then
  85.             if 'CLS_IDX' == lazymember.Index then
  86.                     cls_field_count = cls_field_count + 1
  87.             elseif 'CLS_GETTER_IDX' == lazymember.Index then
  88.                     cls_getter_count = cls_getter_count + 1
  89.                 elseif 'CLS_SETTER_IDX' == lazymember.Index then
  90.                     cls_setter_count = cls_setter_count + 1
  91.                 end
  92.         else
  93.                 if 'METHOD_IDX' == lazymember.Index then
  94.                     obj_method_count = obj_method_count + 1
  95.             elseif 'GETTER_IDX' == lazymember.Index then
  96.                     obj_getter_count = obj_getter_count + 1
  97.                 elseif 'SETTER_IDX' == lazymember.Index then
  98.                     obj_setter_count = obj_setter_count + 1
  99.                 end
  100.         end
  101. end)
  102. local generic_arg_list, type_constraints = GenericArgumentList(type)
  103. table.insert(__text_gen, "\r\nnamespace XLua.CSObjectWrap\r\n{\r\n    using Utils = XLua.Utils;\r\n    public class ")
  104. table.insert(__text_gen, tostring(CSVariableName(type)))
  105. table.insert(__text_gen, "Wrap")
  106. table.insert(__text_gen, tostring(generic_arg_list))
  107. table.insert(__text_gen, " ")
  108. table.insert(__text_gen, tostring(type_constraints))
  109. table.insert(__text_gen, "\r\n    {\r\n        public static void __Register(RealStatePtr L)\r\n        {\r\n\t\t\tObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n\t\t\tSystem.Type type = typeof(")
  110. table.insert(__text_gen, tostring(CsFullTypeName(type)))
  111. table.insert(__text_gen, ");\r\n\t\t\tUtils.BeginObjectRegister(type, L, translator, ")
  112. table.insert(__text_gen, tostring(meta_func_count))
  113. table.insert(__text_gen, ", ")
  114. table.insert(__text_gen, tostring(obj_method_count))
  115. table.insert(__text_gen, ", ")
  116. table.insert(__text_gen, tostring(obj_getter_count))
  117. table.insert(__text_gen, ", ")
  118. table.insert(__text_gen, tostring(obj_setter_count))
  119. table.insert(__text_gen, ");\r\n\t\t\t")
  120. ForEachCsList(operators, function(operator)
  121. table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "")
  122. table.insert(__text_gen, tostring((OpNameMap[operator.Name]):gsub('Meta', ''):lower()))
  123. table.insert(__text_gen, "", ")
  124. table.insert(__text_gen, tostring(OpNameMap[operator.Name]))
  125. table.insert(__text_gen, ");\r\n            ")
  126. end)
  127. table.insert(__text_gen, "\r\n\t\t\t")
  128. ForEachCsList(methods, function(method) if not method.IsStatic then
  129. table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.METHOD_IDX, "")
  130. table.insert(__text_gen, tostring(method.Name))
  131. table.insert(__text_gen, "", _m_")
  132. table.insert(__text_gen, tostring(method.Name))
  133. table.insert(__text_gen, ");\r\n\t\t\t")
  134. end end)
  135. table.insert(__text_gen, "\r\n\t\t\t")
  136. ForEachCsList(events, function(event) if not event.IsStatic then
  137. table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.METHOD_IDX, "")
  138. table.insert(__text_gen, tostring(event.Name))
  139. table.insert(__text_gen, "", _e_")
  140. table.insert(__text_gen, tostring(event.Name))
  141. table.insert(__text_gen, ");\r\n\t\t\t")
  142. end end)
  143. table.insert(__text_gen, "\r\n\t\t\t")
  144. ForEachCsList(getters, function(getter) if not getter.IsStatic then
  145. table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.GETTER_IDX, "")
  146. table.insert(__text_gen, tostring(getter.Name))
  147. table.insert(__text_gen, "", _g_get_")
  148. table.insert(__text_gen, tostring(getter.Name))
  149. table.insert(__text_gen, ");\r\n            ")
  150. end end)
  151. table.insert(__text_gen, "\r\n\t\t\t")
  152. ForEachCsList(setters, function(setter) if not setter.IsStatic then
  153. table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.SETTER_IDX, "")
  154. table.insert(__text_gen, tostring(setter.Name))
  155. table.insert(__text_gen, "", _s_set_")
  156. table.insert(__text_gen, tostring(setter.Name))
  157. table.insert(__text_gen, ");\r\n            ")
  158. end end)
  159. table.insert(__text_gen, "\r\n\t\t\t")
  160. ForEachCsList(lazymembers, function(lazymember) if lazymember.IsStatic == 'false' then
  161. table.insert(__text_gen, "Utils.RegisterLazyFunc(L, Utils.")
  162. table.insert(__text_gen, tostring(lazymember.Index))
  163. table.insert(__text_gen, ", "")
  164. table.insert(__text_gen, tostring(lazymember.Name))
  165. table.insert(__text_gen, "", type, ")
  166. table.insert(__text_gen, tostring(lazymember.MemberType))
  167. table.insert(__text_gen, ", ")
  168. table.insert(__text_gen, tostring(lazymember.IsStatic))
  169. table.insert(__text_gen, ");\r\n            ")
  170. end end)
  171. table.insert(__text_gen, "\r\n\t\t\tUtils.EndObjectRegister(type, L, translator, ")
  172. if type.IsArray or ((indexers.Count or 0) > 0) then
  173. table.insert(__text_gen, "__CSIndexer")
  174. else
  175. table.insert(__text_gen, "null")
  176. end
  177. table.insert(__text_gen, ", ")
  178. if type.IsArray or ((newindexers.Count or 0) > 0) then
  179. table.insert(__text_gen, "__NewIndexer")
  180. else
  181. table.insert(__text_gen, "null")
  182. end
  183. table.insert(__text_gen, ",\r\n\t\t\t    null, null, null);\r\n\r\n\t\t    Utils.BeginClassRegister(type, L, __CreateInstance, ")
  184. table.insert(__text_gen, tostring(cls_field_count))
  185. table.insert(__text_gen, ", ")
  186. table.insert(__text_gen, tostring(cls_getter_count))
  187. table.insert(__text_gen, ", ")
  188. table.insert(__text_gen, tostring(cls_setter_count))
  189. table.insert(__text_gen, ");\r\n\t\t\t")
  190. ForEachCsList(methods, function(method) if method.IsStatic then
  191. table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.CLS_IDX, "")
  192. table.insert(__text_gen, tostring(method.Overloads[0].Name))
  193. table.insert(__text_gen, "", _m_")
  194. table.insert(__text_gen, tostring(method.Name))
  195. table.insert(__text_gen, ");\r\n            ")
  196. end end)
  197. table.insert(__text_gen, "\r\n\t\t\t")
  198. ForEachCsList(events, function(event) if event.IsStatic then
  199. table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.CLS_IDX, "")
  200. table.insert(__text_gen, tostring(event.Name))
  201. table.insert(__text_gen, "", _e_")
  202. table.insert(__text_gen, tostring(event.Name))
  203. table.insert(__text_gen, ");\r\n\t\t\t")
  204. end end)
  205. table.insert(__text_gen, "\r\n            ")
  206. ForEachCsList(getters, function(getter) if getter.IsStatic and getter.ReadOnly then
  207. table.insert(__text_gen, "Utils.RegisterObject(L, translator, Utils.CLS_IDX, "")
  208. table.insert(__text_gen, tostring(getter.Name))
  209. table.insert(__text_gen, "", ")
  210. table.insert(__text_gen, tostring(CsFullTypeName(type).."."..getter.Name))
  211. table.insert(__text_gen, ");\r\n            ")
  212. end end)
  213. table.insert(__text_gen, "\r\n\t\t\t")
  214. ForEachCsList(getters, function(getter) if getter.IsStatic and (not getter.ReadOnly) then
  215. table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.CLS_GETTER_IDX, "")
  216. table.insert(__text_gen, tostring(getter.Name))
  217. table.insert(__text_gen, "", _g_get_")
  218. table.insert(__text_gen, tostring(getter.Name))
  219. table.insert(__text_gen, ");\r\n            ")
  220. end end)
  221. table.insert(__text_gen, "\r\n\t\t\t")
  222. ForEachCsList(setters, function(setter) if setter.IsStatic then
  223. table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.CLS_SETTER_IDX, "")
  224. table.insert(__text_gen, tostring(setter.Name))
  225. table.insert(__text_gen, "", _s_set_")
  226. table.insert(__text_gen, tostring(setter.Name))
  227. table.insert(__text_gen, ");\r\n            ")
  228. end end)
  229. table.insert(__text_gen, "\r\n\t\t\t")
  230. ForEachCsList(lazymembers, function(lazymember) if lazymember.IsStatic == 'true' then
  231. table.insert(__text_gen, "Utils.RegisterLazyFunc(L, Utils.")
  232. table.insert(__text_gen, tostring(lazymember.Index))
  233. table.insert(__text_gen, ", "")
  234. table.insert(__text_gen, tostring(lazymember.Name))
  235. table.insert(__text_gen, "", type, ")
  236. table.insert(__text_gen, tostring(lazymember.MemberType))
  237. table.insert(__text_gen, ", ")
  238. table.insert(__text_gen, tostring(lazymember.IsStatic))
  239. table.insert(__text_gen, ");\r\n            ")
  240. end end)
  241. table.insert(__text_gen, "\r\n\t\t\tUtils.EndClassRegister(type, L, translator);\r\n        }\r\n        \r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int __CreateInstance(RealStatePtr L)\r\n        {\r\n            ")
  242.             if constructors.Count == 0 and (not type.IsValueType)  then
  243.             
  244. table.insert(__text_gen, "return LuaAPI.luaL_error(L, "")
  245. table.insert(__text_gen, tostring(CsFullTypeName(type)))
  246. table.insert(__text_gen, " does not have a constructor!");")
  247.             else
  248. table.insert(__text_gen, "\r\n\t\t\ttry {\r\n                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n\t\t\t\t")
  249.                                 local hasZeroParamsCtor = false
  250.                                 ForEachCsList(constructors, function(constructor, ci)
  251.                                         local parameters = constructor:GetParameters()
  252.                                         if parameters.Length == 0 then
  253.                                             hasZeroParamsCtor = true
  254.                                         end
  255.                                         local def_count = constructor_def_vals[ci]
  256.                                         local param_count = parameters.Length
  257.                                         local in_num = CalcCsList(parameters, function(p) return not (p.IsOut and p.ParameterType.IsByRef) end)
  258.                     local out_num = CalcCsList(parameters, function(p) return p.IsOut or p.ParameterType.IsByRef end)
  259.                                         local real_param_count = param_count - def_count
  260.                     local has_v_params = param_count > 0 and IsParams(parameters[param_count - 1])
  261.                                         local in_pos = 0
  262.                                
  263. table.insert(__text_gen, "if(LuaAPI.lua_gettop(L) ")
  264. table.insert(__text_gen, tostring(has_v_params and ">=" or "=="))
  265. table.insert(__text_gen, " ")
  266. table.insert(__text_gen, tostring(in_num + 1 - def_count - (has_v_params and 1 or 0)))
  267. ForEachCsList(parameters, function(parameter, pi)
  268.                 if pi >= real_param_count then return end
  269.                 local parameterType = parameter.ParameterType
  270.                 if has_v_params and pi == param_count - 1 then  parameterType = parameterType:GetElementType() end
  271.                                 if not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1
  272.                
  273. table.insert(__text_gen, " && ")
  274. table.insert(__text_gen, tostring(GetCheckStatement(parameterType, in_pos+1, has_v_params and pi == param_count - 1)))
  275.                                 end
  276.                                 end)
  277. table.insert(__text_gen, ")\r\n\t\t\t\t{\r\n\t\t\t\t\t")
  278. ForEachCsList(parameters, function(parameter, pi)
  279.                     if pi >= real_param_count then return end
  280.                     
  281. table.insert(__text_gen, tostring(GetCasterStatement(parameter.ParameterType, pi+2, LocalName(parameter.Name), true, has_v_params and pi == param_count - 1)))
  282. table.insert(__text_gen, ";\r\n\t\t\t\t\t")
  283. end)
  284. table.insert(__text_gen, "\r\n\t\t\t\t\tvar gen_ret = new ")
  285. table.insert(__text_gen, tostring(CsFullTypeName(type)))
  286. table.insert(__text_gen, "(")
  287. ForEachCsList(parameters, function(parameter, pi) if pi >= real_param_count then return end; if pi ~=0 then
  288. table.insert(__text_gen, tostring(', '))
  289. end ;if parameter.IsOut and parameter.ParameterType.IsByRef then
  290. table.insert(__text_gen, "out ")
  291. elseif parameter.ParameterType.IsByRef and not parameter.IsIn then
  292. table.insert(__text_gen, "ref ")
  293. end
  294. table.insert(__text_gen, tostring(LocalName(parameter.Name)))
  295. end)
  296. table.insert(__text_gen, ");\r\n\t\t\t\t\t")
  297. table.insert(__text_gen, tostring(GetPushStatement(type, "gen_ret")))
  298. table.insert(__text_gen, ";\r\n                    ")
  299. local in_pos = 0
  300.                     ForEachCsList(parameters, function(parameter, pi)
  301.                         if pi >= real_param_count then return end
  302.                         if not (parameter.IsOut and parameter.ParameterType.IsByRef) then
  303.                             in_pos = in_pos + 1
  304.                         end
  305.                         if parameter.ParameterType.IsByRef then
  306.                         
  307. table.insert(__text_gen, tostring(GetPushStatement(parameter.ParameterType:GetElementType(), LocalName(parameter.Name))))
  308. table.insert(__text_gen, ";\r\n                        ")
  309. if not parameter.IsOut and parameter.ParameterType.IsByRef and NeedUpdate(parameter.ParameterType) then
  310.                   
  311. table.insert(__text_gen, tostring(GetUpdateStatement(parameter.ParameterType:GetElementType(), in_pos+1, LocalName(parameter.Name))))
  312. table.insert(__text_gen, ";\r\n                        ")
  313. end
  314. table.insert(__text_gen, "\r\n                    ")
  315.                         end
  316.                     end)
  317.                     
  318. table.insert(__text_gen, "\r\n\t\t\t\t\treturn ")
  319. table.insert(__text_gen, tostring(out_num + 1))
  320. table.insert(__text_gen, ";\r\n\t\t\t\t}\r\n\t\t\t\t")
  321. end)
  322.                                 if (not hasZeroParamsCtor) and type.IsValueType then
  323.                                
  324. table.insert(__text_gen, "\r\n\t\t\t\tif (LuaAPI.lua_gettop(L) == 1)\r\n\t\t\t\t{\r\n\t\t\t\t    ")
  325. table.insert(__text_gen, tostring(GetPushStatement(type, "default(" .. CsFullTypeName(type).. ")")))
  326. table.insert(__text_gen, ";\r\n\t\t\t        return 1;\r\n\t\t\t\t}\r\n\t\t\t\t")
  327. end
  328. table.insert(__text_gen, "\r\n\t\t\t}\r\n\t\t\tcatch(System.Exception gen_e) {\r\n\t\t\t\treturn LuaAPI.luaL_error(L, "c# exception:" + gen_e);\r\n\t\t\t}\r\n            return LuaAPI.luaL_error(L, "invalid arguments to ")
  329. table.insert(__text_gen, tostring(CsFullTypeName(type)))
  330. table.insert(__text_gen, " constructor!");\r\n            ")
  331. end
  332. table.insert(__text_gen, "\r\n        }\r\n        \r\n\t\t")
  333. if type.IsArray or ((indexers.Count or 0) > 0) then
  334. table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        public static int __CSIndexer(RealStatePtr L)\r\n        {\r\n\t\t\t")
  335. if type.IsArray then
  336. table.insert(__text_gen, "\r\n\t\t\ttry {\r\n\t\t\t    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n\t\t\t\r\n\t\t\t\tif (")
  337. table.insert(__text_gen, tostring(GetCheckStatement(type, 1)))
  338. table.insert(__text_gen, " && LuaAPI.lua_isnumber(L, 2))\r\n\t\t\t\t{\r\n\t\t\t\t\tint index = (int)LuaAPI.lua_tonumber(L, 2);\r\n\t\t\t\t\t")
  339. table.insert(__text_gen, tostring(GetSelfStatement(type)))
  340. table.insert(__text_gen, ";\r\n\t\t\t\t\tLuaAPI.lua_pushboolean(L, true);\r\n\t\t\t\t\t")
  341. table.insert(__text_gen, tostring(GetPushStatement(type:GetElementType(), "gen_to_be_invoked[index]")))
  342. table.insert(__text_gen, ";\r\n\t\t\t\t\treturn 2;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tcatch(System.Exception gen_e) {\r\n\t\t\t\treturn LuaAPI.luaL_error(L, "c# exception:" + gen_e);\r\n\t\t\t}\r\n\t\t\t")
  343. elseif indexers.Count > 0 then
  344.                        
  345. table.insert(__text_gen, "try {\r\n\t\t\t    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n\t\t\t\t")
  346.                                         ForEachCsList(indexers, function(indexer)
  347.                                                 local paramter = indexer:GetParameters()[0]
  348.                                
  349. table.insert(__text_gen, "\r\n\t\t\t\tif (")
  350. table.insert(__text_gen, tostring(GetCheckStatement(type, 1)))
  351. table.insert(__text_gen, " && ")
  352. table.insert(__text_gen, tostring(GetCheckStatement(paramter.ParameterType, 2)))
  353. table.insert(__text_gen, ")\r\n\t\t\t\t{\r\n\t\t\t\t\t\r\n\t\t\t\t\t")
  354. table.insert(__text_gen, tostring(GetSelfStatement(type)))
  355. table.insert(__text_gen, ";\r\n\t\t\t\t\t")
  356. table.insert(__text_gen, tostring(GetCasterStatement(paramter.ParameterType, 2, "index", true)))
  357. table.insert(__text_gen, ";\r\n\t\t\t\t\tLuaAPI.lua_pushboolean(L, true);\r\n\t\t\t\t\t")
  358. table.insert(__text_gen, tostring(GetPushStatement(indexer.ReturnType, "gen_to_be_invoked[index]")))
  359. table.insert(__text_gen, ";\r\n\t\t\t\t\treturn 2;\r\n\t\t\t\t}\r\n\t\t\t\t")
  360. end)
  361. table.insert(__text_gen, "\r\n\t\t\t}\r\n\t\t\tcatch(System.Exception gen_e) {\r\n\t\t\t\treturn LuaAPI.luaL_error(L, "c# exception:" + gen_e);\r\n\t\t\t}\r\n\t\t\t")
  362. end
  363. table.insert(__text_gen, "\r\n            LuaAPI.lua_pushboolean(L, false);\r\n\t\t\treturn 1;\r\n        }\r\n\t\t")
  364. end
  365. table.insert(__text_gen, "\r\n        \r\n\t\t")
  366. if type.IsArray or ((newindexers.Count or 0) > 0) then
  367. table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        public static int __NewIndexer(RealStatePtr L)\r\n        {\r\n\t\t\t")
  368. if type.IsArray or newindexers.Count > 0 then
  369. table.insert(__text_gen, "ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);")
  370. end
  371. table.insert(__text_gen, "\r\n\t\t\t")
  372. if type.IsArray then
  373.                                 local elementType = type:GetElementType()
  374.                        
  375. table.insert(__text_gen, "\r\n\t\t\ttry {\r\n\t\t\t\tif (")
  376. table.insert(__text_gen, tostring(GetCheckStatement(type, 1)))
  377. table.insert(__text_gen, " && LuaAPI.lua_isnumber(L, 2) && ")
  378. table.insert(__text_gen, tostring(GetCheckStatement(elementType, 3)))
  379. table.insert(__text_gen, ")\r\n\t\t\t\t{\r\n\t\t\t\t\tint index = (int)LuaAPI.lua_tonumber(L, 2);\r\n\t\t\t\t\t")
  380. table.insert(__text_gen, tostring(GetSelfStatement(type)))
  381. table.insert(__text_gen, ";\r\n\t\t\t\t\t")
  382. table.insert(__text_gen, tostring(GetCasterStatement(elementType, 3, "gen_to_be_invoked[index]")))
  383. table.insert(__text_gen, ";\r\n\t\t\t\t\tLuaAPI.lua_pushboolean(L, true);\r\n\t\t\t\t\treturn 1;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tcatch(System.Exception gen_e) {\r\n\t\t\t\treturn LuaAPI.luaL_error(L, "c# exception:" + gen_e);\r\n\t\t\t}\r\n\t\t\t")
  384. elseif newindexers.Count > 0 then
  385. table.insert(__text_gen, "\r\n\t\t\ttry {\r\n\t\t\t\t")
  386. ForEachCsList(newindexers, function(newindexer)
  387.                                                 local keyType = newindexer:GetParameters()[0].ParameterType
  388.                                                 local valueType = newindexer:GetParameters()[1].ParameterType
  389.                                
  390. table.insert(__text_gen, "\r\n\t\t\t\tif (")
  391. table.insert(__text_gen, tostring(GetCheckStatement(type, 1)))
  392. table.insert(__text_gen, " && ")
  393. table.insert(__text_gen, tostring(GetCheckStatement(keyType, 2)))
  394. table.insert(__text_gen, " && ")
  395. table.insert(__text_gen, tostring(GetCheckStatement(valueType, 3)))
  396. table.insert(__text_gen, ")\r\n\t\t\t\t{\r\n\t\t\t\t\t\r\n\t\t\t\t\t")
  397. table.insert(__text_gen, tostring(GetSelfStatement(type)))
  398. table.insert(__text_gen, ";\r\n\t\t\t\t\t")
  399. table.insert(__text_gen, tostring(GetCasterStatement(keyType, 2, "key", true)))
  400. table.insert(__text_gen, ";\r\n\t\t\t\t\t")
  401. if IsStruct(valueType) then
  402. table.insert(__text_gen, tostring(GetCasterStatement(valueType, 3, "gen_value", true)))
  403. table.insert(__text_gen, ";\r\n\t\t\t\t\tgen_to_be_invoked[key] = gen_value;")
  404. else
  405.                   
  406. table.insert(__text_gen, tostring(GetCasterStatement(valueType, 3, "gen_to_be_invoked[key]")))
  407. table.insert(__text_gen, ";")
  408. end
  409. table.insert(__text_gen, "\r\n\t\t\t\t\tLuaAPI.lua_pushboolean(L, true);\r\n\t\t\t\t\treturn 1;\r\n\t\t\t\t}\r\n\t\t\t\t")
  410. end)
  411. table.insert(__text_gen, "\r\n\t\t\t}\r\n\t\t\tcatch(System.Exception gen_e) {\r\n\t\t\t\treturn LuaAPI.luaL_error(L, "c# exception:" + gen_e);\r\n\t\t\t}\r\n\t\t\t")
  412. end
  413. table.insert(__text_gen, "\r\n\t\t\tLuaAPI.lua_pushboolean(L, false);\r\n            return 1;\r\n        }\r\n\t\t")
  414. end
  415. table.insert(__text_gen, "\r\n        \r\n        ")
  416. ForEachCsList(operators, function(operator)
  417. table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int ")
  418. table.insert(__text_gen, tostring(OpNameMap[operator.Name]))
  419. table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n            ")
  420. if operator.Name ~= "op_UnaryNegation" and operator.Name ~= "op_OnesComplement"  then
  421. table.insert(__text_gen, "\r\n\t\t\ttry {\r\n                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n            ")
  422. ForEachCsList(operator.Overloads, function(overload)
  423.                 local left_param = overload:GetParameters()[0]
  424.                 local right_param = overload:GetParameters()[1]
  425.             
  426. table.insert(__text_gen, "\r\n\t\t\t\r\n\t\t\t\tif (")
  427. table.insert(__text_gen, tostring(GetCheckStatement(left_param.ParameterType, 1)))
  428. table.insert(__text_gen, " && ")
  429. table.insert(__text_gen, tostring(GetCheckStatement(right_param.ParameterType, 2)))
  430. table.insert(__text_gen, ")\r\n\t\t\t\t{\r\n\t\t\t\t\t")
  431. table.insert(__text_gen, tostring(GetCasterStatement(left_param.ParameterType, 1, "leftside", true)))
  432. table.insert(__text_gen, ";\r\n\t\t\t\t\t")
  433. table.insert(__text_gen, tostring(GetCasterStatement(right_param.ParameterType, 2, "rightside", true)))
  434. table.insert(__text_gen, ";\r\n\t\t\t\t\t\r\n\t\t\t\t\t")
  435. table.insert(__text_gen, tostring(GetPushStatement(overload.ReturnType, "leftside " .. OpCallNameMap[operator.Name] .. " rightside")))
  436. table.insert(__text_gen, ";\r\n\t\t\t\t\t\r\n\t\t\t\t\treturn 1;\r\n\t\t\t\t}\r\n            ")
  437. end)
  438. table.insert(__text_gen, "\r\n\t\t\t}\r\n\t\t\tcatch(System.Exception gen_e) {\r\n\t\t\t\treturn LuaAPI.luaL_error(L, "c# exception:" + gen_e);\r\n\t\t\t}\r\n            return LuaAPI.luaL_error(L, "invalid arguments to right hand of ")
  439. table.insert(__text_gen, tostring(OpCallNameMap[operator.Name]))
  440. table.insert(__text_gen, " operator, need ")
  441. table.insert(__text_gen, tostring(CsFullTypeName(type)))
  442. table.insert(__text_gen, "!");\r\n            ")
  443. else
  444. table.insert(__text_gen, "\r\n\t\t\tObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n            try {\r\n                ")
  445. table.insert(__text_gen, tostring(GetCasterStatement(type, 1, "rightside", true)))
  446. table.insert(__text_gen, ";\r\n                ")
  447. table.insert(__text_gen, tostring(GetPushStatement(operator.Overloads[0].ReturnType, OpCallNameMap[operator.Name] .. " rightside")))
  448. table.insert(__text_gen, ";\r\n            } catch(System.Exception gen_e) {\r\n                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);\r\n            }\r\n            return 1;\r\n            ")
  449. end
  450. table.insert(__text_gen, "\r\n        }\r\n        ")
  451. end)
  452. table.insert(__text_gen, "\r\n        \r\n        ")
  453. ForEachCsList(methods, function(method)
  454. table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _m_")
  455. table.insert(__text_gen, tostring(method.Name))
  456. table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n\t\t    try {\r\n            ")
  457.             local need_obj = not method.IsStatic
  458.             if MethodCallNeedTranslator(method) then
  459.             
  460. table.insert(__text_gen, "\r\n                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n            ")
  461. end
  462. table.insert(__text_gen, "\r\n            ")
  463. if need_obj then
  464. table.insert(__text_gen, "\r\n                ")
  465. table.insert(__text_gen, tostring(GetSelfStatement(type)))
  466. table.insert(__text_gen, ";\r\n            ")
  467. end
  468. table.insert(__text_gen, "\r\n            ")
  469. if method.Overloads.Count > 1 then
  470. table.insert(__text_gen, "\r\n\t\t\t    int gen_param_count = LuaAPI.lua_gettop(L);\r\n            ")
  471. end
  472. table.insert(__text_gen, "\r\n                ")
  473. ForEachCsList(method.Overloads, function(overload, oi)
  474.                 local parameters = MethodParameters(overload)
  475.                 local in_num = CalcCsList(parameters, function(p) return not (p.IsOut and p.ParameterType.IsByRef) end)
  476.                 local param_offset = method.IsStatic and 0 or 1
  477.                 local out_num = CalcCsList(parameters, function(p) return p.IsOut or p.ParameterType.IsByRef end)
  478.                 local in_pos = 0
  479.                 local has_return = (overload.ReturnType.FullName ~= "System.Void")
  480.                 local def_count = method.DefaultValues[oi]
  481.                                 local param_count = parameters.Length
  482.                 local real_param_count = param_count - def_count
  483.                 local has_v_params = param_count > 0 and IsParams(parameters[param_count - 1])
  484.                 if method.Overloads.Count > 1 then
  485.                
  486. table.insert(__text_gen, "if(gen_param_count ")
  487. table.insert(__text_gen, tostring(has_v_params and ">=" or "=="))
  488. table.insert(__text_gen, " ")
  489. table.insert(__text_gen, tostring(in_num+param_offset-def_count - (has_v_params and 1 or 0)))
  490.                     ForEachCsList(parameters, function(parameter, pi)
  491.                         if pi >= real_param_count then return end
  492.                         local parameterType = parameter.ParameterType
  493.                         if has_v_params and pi == param_count - 1 then  parameterType = parameterType:GetElementType() end
  494.                         if not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1;
  495.                         
  496. table.insert(__text_gen, "&& ")
  497. table.insert(__text_gen, tostring(GetCheckStatement(parameterType , in_pos+param_offset, has_v_params and pi == param_count - 1)))
  498.                         end
  499.                     end)
  500. table.insert(__text_gen, ") ")
  501. end
  502. table.insert(__text_gen, "\r\n                {\r\n                    ")
  503. if overload.Name == "get_Item" and overload.IsSpecialName then
  504.                                             local keyType = overload:GetParameters()[0].ParameterType
  505. table.insert(__text_gen, "\r\n\t\t\t\t\t")
  506. table.insert(__text_gen, tostring(GetCasterStatement(keyType, 2, "key", true)))
  507. table.insert(__text_gen, ";\r\n\t\t\t\t\t")
  508. table.insert(__text_gen, tostring(GetPushStatement(overload.ReturnType, "gen_to_be_invoked[key]")))
  509. table.insert(__text_gen, ";\r\n\t\t\t\t\t")
  510. elseif overload.Name == "set_Item" and overload.IsSpecialName then
  511.                                             local keyType = overload:GetParameters()[0].ParameterType
  512.                                                 local valueType = overload:GetParameters()[1].ParameterType
  513. table.insert(__text_gen, "\r\n\t\t\t\t\t")
  514. table.insert(__text_gen, tostring(GetCasterStatement(keyType, 2, "key", true)))
  515. table.insert(__text_gen, ";\r\n\t\t\t\t\t")
  516. table.insert(__text_gen, tostring(GetCasterStatement(valueType, 3, "gen_value", true)))
  517. table.insert(__text_gen, ";\r\n                    gen_to_be_invoked[key] = gen_value;\r\n                    ")
  518. else
  519.                     in_pos = 0;
  520.                     ForEachCsList(parameters, function(parameter, pi)
  521.                         if pi >= real_param_count then return end
  522.                         
  523. if not (parameter.IsOut and parameter.ParameterType.IsByRef) then
  524.                             in_pos = in_pos + 1
  525.                         
  526. table.insert(__text_gen, tostring(GetCasterStatement(parameter.ParameterType, in_pos+param_offset, LocalName(parameter.Name), true, has_v_params and pi == param_count - 1)))
  527.                                             else
  528. table.insert(__text_gen, tostring(CsFullTypeName(parameter.ParameterType)))
  529. table.insert(__text_gen, " ")
  530. table.insert(__text_gen, tostring(LocalName(parameter.Name)))
  531. end
  532. table.insert(__text_gen, ";\r\n                    ")
  533. end)
  534. table.insert(__text_gen, "\r\n                    ")
  535.                     if has_return then
  536.                         
  537. table.insert(__text_gen, "    var gen_ret = ")
  538.                     end
  539.                     
  540. if method.IsStatic then
  541.                     
  542. table.insert(__text_gen, tostring(CsFullTypeName(type).."."..UnK(overload.Name)))
  543.                     else
  544.                     
  545. table.insert(__text_gen, "gen_to_be_invoked.")
  546. table.insert(__text_gen, tostring(UnK(overload.Name)))
  547.                     end
  548. table.insert(__text_gen, "( ")
  549. ForEachCsList(parameters, function(parameter, pi)
  550.                         if pi >= real_param_count then return end
  551.                         if pi ~= 0 then
  552. table.insert(__text_gen, ", ")
  553. end; if parameter.IsOut and parameter.ParameterType.IsByRef then
  554. table.insert(__text_gen, "out ")
  555. elseif parameter.ParameterType.IsByRef and not parameter.IsIn then
  556. table.insert(__text_gen, "ref ")
  557. end
  558. table.insert(__text_gen, tostring(LocalName(parameter.Name)))
  559. end)
  560. table.insert(__text_gen, " );\r\n                    ")
  561.                     if has_return then
  562.                     
  563. table.insert(__text_gen, "    ")
  564. table.insert(__text_gen, tostring(GetPushStatement(overload.ReturnType, "gen_ret")))
  565. table.insert(__text_gen, ";\r\n                    ")
  566.                     end
  567.                     local in_pos = 0
  568.                     ForEachCsList(parameters, function(parameter, pi)
  569.                         if pi >= real_param_count then return end
  570.                         if not (parameter.IsOut and parameter.ParameterType.IsByRef) then
  571.                             in_pos = in_pos + 1
  572.                         end
  573.                         if parameter.ParameterType.IsByRef then
  574.                         
  575. table.insert(__text_gen, tostring(GetPushStatement(parameter.ParameterType:GetElementType(), LocalName(parameter.Name))))
  576. table.insert(__text_gen, ";\r\n                        ")
  577. if not parameter.IsOut and parameter.ParameterType.IsByRef and NeedUpdate(parameter.ParameterType) then
  578.                   
  579. table.insert(__text_gen, tostring(GetUpdateStatement(parameter.ParameterType:GetElementType(), in_pos+param_offset, LocalName(parameter.Name))))
  580. table.insert(__text_gen, ";\r\n                        ")
  581. end
  582. table.insert(__text_gen, "\r\n                    ")
  583.                         end
  584.                     end)
  585.                                         end
  586.                     
  587. table.insert(__text_gen, "\r\n                    ")
  588. if NeedUpdate(type) and not method.IsStatic then
  589. table.insert(__text_gen, "\r\n                        ")
  590. table.insert(__text_gen, tostring(GetUpdateStatement(type, 1, "gen_to_be_invoked")))
  591. table.insert(__text_gen, ";\r\n                    ")
  592. end
  593. table.insert(__text_gen, "\r\n                    \r\n                    return ")
  594. table.insert(__text_gen, tostring(out_num+(has_return and 1 or 0)))
  595. table.insert(__text_gen, ";\r\n                }\r\n                ")
  596. end)
  597. table.insert(__text_gen, "\r\n            } catch(System.Exception gen_e) {\r\n                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);\r\n            }\r\n            ")
  598. if method.Overloads.Count > 1 then
  599. table.insert(__text_gen, "\r\n            return LuaAPI.luaL_error(L, "invalid arguments to ")
  600. table.insert(__text_gen, tostring(CsFullTypeName(type)))
  601. table.insert(__text_gen, ".")
  602. table.insert(__text_gen, tostring(method.Overloads[0].Name))
  603. table.insert(__text_gen, "!");\r\n            ")
  604. end
  605. table.insert(__text_gen, "\r\n        }\r\n        ")
  606. end)
  607. table.insert(__text_gen, "\r\n        \r\n        \r\n        ")
  608. ForEachCsList(getters, function(getter)
  609.         if getter.IsStatic and getter.ReadOnly then return end --readonly static
  610.         
  611. table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _g_get_")
  612. table.insert(__text_gen, tostring(getter.Name))
  613. table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n\t\t    try {\r\n            ")
  614. if AccessorNeedTranslator(getter) then
  615. table.insert(__text_gen, "    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);")
  616. end
  617. table.insert(__text_gen, "\r\n\t\t\t")
  618. if not getter.IsStatic then
  619. table.insert(__text_gen, "\r\n                ")
  620. table.insert(__text_gen, tostring(GetSelfStatement(type)))
  621. table.insert(__text_gen, ";\r\n                ")
  622. table.insert(__text_gen, tostring(GetPushStatement(getter.Type, "gen_to_be_invoked."..UnK(getter.Name))))
  623. table.insert(__text_gen, ";")
  624. else
  625. table.insert(__text_gen, "    ")
  626. table.insert(__text_gen, tostring(GetPushStatement(getter.Type, CsFullTypeName(type).."."..UnK(getter.Name))))
  627. table.insert(__text_gen, ";")
  628. end
  629. table.insert(__text_gen, "\r\n            } catch(System.Exception gen_e) {\r\n                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);\r\n            }\r\n            return 1;\r\n        }\r\n        ")
  630. end)
  631. table.insert(__text_gen, "\r\n        \r\n        ")
  632. ForEachCsList(setters, function(setter)
  633.         local is_struct = IsStruct(setter.Type)
  634.         
  635. table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _s_set_")
  636. table.insert(__text_gen, tostring(setter.Name))
  637. table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n\t\t    try {\r\n                ")
  638. if AccessorNeedTranslator(setter) then
  639. table.insert(__text_gen, "ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);")
  640. end
  641. table.insert(__text_gen, "\r\n\t\t\t")
  642. if not setter.IsStatic then
  643. table.insert(__text_gen, "\r\n                ")
  644. table.insert(__text_gen, tostring(GetSelfStatement(type)))
  645. table.insert(__text_gen, ";\r\n                ")
  646. if is_struct then
  647. table.insert(__text_gen, tostring(GetCasterStatement(setter.Type, 2, "gen_value", true)))
  648. table.insert(__text_gen, ";\r\n\t\t\t\tgen_to_be_invoked.")
  649. table.insert(__text_gen, tostring(UnK(setter.Name)))
  650. table.insert(__text_gen, " = gen_value;")
  651. else
  652.               
  653. table.insert(__text_gen, tostring(GetCasterStatement(setter.Type, 2, "gen_to_be_invoked." .. UnK(setter.Name))))
  654. table.insert(__text_gen, ";")
  655. end
  656.             else
  657.                                 if is_struct then
  658. table.insert(__text_gen, tostring(GetCasterStatement(setter.Type, 1, "gen_value", true)))
  659. table.insert(__text_gen, ";\r\n\t\t\t\t")
  660. table.insert(__text_gen, tostring(CsFullTypeName(type)))
  661. table.insert(__text_gen, ".")
  662. table.insert(__text_gen, tostring(UnK(setter.Name)))
  663. table.insert(__text_gen, " = gen_value;")
  664. else
  665.          
  666. table.insert(__text_gen, "    ")
  667. table.insert(__text_gen, tostring(GetCasterStatement(setter.Type, 1, CsFullTypeName(type) .."." .. UnK(setter.Name))))
  668. table.insert(__text_gen, ";")
  669. end
  670.             end
  671. table.insert(__text_gen, "\r\n            ")
  672. if NeedUpdate(type) and not setter.IsStatic then
  673. table.insert(__text_gen, "\r\n                ")
  674. table.insert(__text_gen, tostring(GetUpdateStatement(type, 1, "gen_to_be_invoked")))
  675. table.insert(__text_gen, ";\r\n            ")
  676. end
  677. table.insert(__text_gen, "\r\n            } catch(System.Exception gen_e) {\r\n                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);\r\n            }\r\n            return 0;\r\n        }\r\n        ")
  678. end)
  679. table.insert(__text_gen, "\r\n\t\t\r\n\t\t")
  680. ForEachCsList(events, function(event) if not event.IsStatic then
  681. table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _e_")
  682. table.insert(__text_gen, tostring(event.Name))
  683. table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n\t\t    try {\r\n                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n\t\t\t    int gen_param_count = LuaAPI.lua_gettop(L);\r\n\t\t\t")
  684. table.insert(__text_gen, tostring(GetSelfStatement(type)))
  685. table.insert(__text_gen, ";\r\n                ")
  686. table.insert(__text_gen, tostring(GetCasterStatement(event.Type, 3, "gen_delegate", true)))
  687. table.insert(__text_gen, ";\r\n                if (gen_delegate == null) {\r\n                    return LuaAPI.luaL_error(L, "#3 need ")
  688. table.insert(__text_gen, tostring(CsFullTypeName(event.Type)))
  689. table.insert(__text_gen, "!");\r\n                }\r\n\t\t\t\t\r\n\t\t\t\tif (gen_param_count == 3)\r\n\t\t\t\t{\r\n\t\t\t\t\t")
  690. if event.CanAdd then
  691. table.insert(__text_gen, "\r\n\t\t\t\t\tif (LuaAPI.xlua_is_eq_str(L, 2, "+")) {\r\n\t\t\t\t\t\tgen_to_be_invoked.")
  692. table.insert(__text_gen, tostring(UnK(event.Name)))
  693. table.insert(__text_gen, " += gen_delegate;\r\n\t\t\t\t\t\treturn 0;\r\n\t\t\t\t\t} \r\n\t\t\t\t\t")
  694. end
  695. table.insert(__text_gen, "\r\n\t\t\t\t\t")
  696. if event.CanRemove then
  697. table.insert(__text_gen, "\r\n\t\t\t\t\tif (LuaAPI.xlua_is_eq_str(L, 2, "-")) {\r\n\t\t\t\t\t\tgen_to_be_invoked.")
  698. table.insert(__text_gen, tostring(UnK(event.Name)))
  699. table.insert(__text_gen, " -= gen_delegate;\r\n\t\t\t\t\t\treturn 0;\r\n\t\t\t\t\t} \r\n\t\t\t\t\t")
  700. end
  701. table.insert(__text_gen, "\r\n\t\t\t\t}\r\n\t\t\t} catch(System.Exception gen_e) {\r\n                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);\r\n            }\r\n\t\t\tLuaAPI.luaL_error(L, "invalid arguments to ")
  702. table.insert(__text_gen, tostring(CsFullTypeName(type)))
  703. table.insert(__text_gen, ".")
  704. table.insert(__text_gen, tostring(event.Name))
  705. table.insert(__text_gen, "!");\r\n            return 0;\r\n        }\r\n        ")
  706. end end)
  707. table.insert(__text_gen, "\r\n\t\t\r\n\t\t")
  708. ForEachCsList(events, function(event) if event.IsStatic then
  709. table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _e_")
  710. table.insert(__text_gen, tostring(event.Name))
  711. table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n\t\t    try {\r\n                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n\t\t\t    int gen_param_count = LuaAPI.lua_gettop(L);\r\n                ")
  712. table.insert(__text_gen, tostring(GetCasterStatement(event.Type, 2, "gen_delegate", true)))
  713. table.insert(__text_gen, ";\r\n                if (gen_delegate == null) {\r\n                    return LuaAPI.luaL_error(L, "#2 need ")
  714. table.insert(__text_gen, tostring(CsFullTypeName(event.Type)))
  715. table.insert(__text_gen, "!");\r\n                }\r\n                \r\n\t\t\t\t")
  716. if event.CanAdd then
  717. table.insert(__text_gen, "\r\n\t\t\t\tif (gen_param_count == 2 && LuaAPI.xlua_is_eq_str(L, 1, "+")) {\r\n\t\t\t\t\t")
  718. table.insert(__text_gen, tostring(CsFullTypeName(type)))
  719. table.insert(__text_gen, ".")
  720. table.insert(__text_gen, tostring(UnK(event.Name)))
  721. table.insert(__text_gen, " += gen_delegate;\r\n\t\t\t\t\treturn 0;\r\n\t\t\t\t} \r\n\t\t\t\t")
  722. end
  723. table.insert(__text_gen, "\r\n\t\t\t\t")
  724. if event.CanRemove then
  725. table.insert(__text_gen, "\r\n\t\t\t\tif (gen_param_count == 2 && LuaAPI.xlua_is_eq_str(L, 1, "-")) {\r\n\t\t\t\t\t")
  726. table.insert(__text_gen, tostring(CsFullTypeName(type)))
  727. table.insert(__text_gen, ".")
  728. table.insert(__text_gen, tostring(UnK(event.Name)))
  729. table.insert(__text_gen, " -= gen_delegate;\r\n\t\t\t\t\treturn 0;\r\n\t\t\t\t} \r\n\t\t\t\t")
  730. end
  731. table.insert(__text_gen, "\r\n\t\t\t} catch(System.Exception gen_e) {\r\n                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);\r\n            }\r\n\t\t\treturn LuaAPI.luaL_error(L, "invalid arguments to ")
  732. table.insert(__text_gen, tostring(CsFullTypeName(type)))
  733. table.insert(__text_gen, ".")
  734. table.insert(__text_gen, tostring(event.Name))
  735. table.insert(__text_gen, "!");\r\n        }\r\n        ")
  736. end end)
  737. table.insert(__text_gen, "\r\n    }\r\n}\r\n")
  738. return table.concat(__text_gen)
复制代码
  1. 到这里看到模板在内存中对应变成了一个生成的方法,对应传进C#的替换字符。
复制代码
替换比力复杂不一一分析了。大概就是C#对应类的成员变量,静态方法等全部元数据替换成table的表里,一个循环遍历举行插入字符比如下面的GameObject的构造函数




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

花瓣小跑

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表