Xlua原理 二

news2024/12/28 19:49:57

一已经介绍了初步的lua与C#通信的原理,和xlua的LuaEnv的初始化内容。

这边介绍下Wrap文件。

一.Wrap介绍

导入xlua后可以看到会多出上图菜单。

点击后生成一堆wrap文件,这些文件是lua调用C#时进行映射查找用的中间代码。这样就不需要去反射调用节约性能。

这里以Vector3Wrap文件为例:

先看一眼Wrap文件结构

   public class UnityEngineVector3Wrap 
    {
        public static void __Register(RealStatePtr L)
        {
			ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
			System.Type type = typeof(UnityEngine.Vector3);
			Utils.BeginObjectRegister(type, L, translator, 6, 6, 6, 3);
			Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__add", __AddMeta);
            Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__sub", __SubMeta);
            Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__unm", __UnmMeta);
            Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__mul", __MulMeta);
            Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__div", __DivMeta);
            Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__eq", __EqMeta);
            
			Utils.RegisterFunc(L, Utils.METHOD_IDX, "Set", _m_Set);
			Utils.RegisterFunc(L, Utils.METHOD_IDX, "Scale", _m_Scale);
			Utils.RegisterFunc(L, Utils.METHOD_IDX, "GetHashCode", _m_GetHashCode);
			Utils.RegisterFunc(L, Utils.METHOD_IDX, "Equals", _m_Equals);
			Utils.RegisterFunc(L, Utils.METHOD_IDX, "Normalize", _m_Normalize);
			Utils.RegisterFunc(L, Utils.METHOD_IDX, "ToString", _m_ToString);
           ...
        }
        ...
    }    
 private void Demo4()
        {
            LuaEnv luaenv = new LuaEnv();
            luaenv.DoString(@"local v1 = CS.UnityEngine.Vector3(10,10,10)
                            local v2 = v1.normalized
                            CS.UnityEngine.Debug.Log(v2.x)
                            local v3 = v1 + v2
                            local v4 = CS.UnityEngine.Vector3.Distance(v1,v2)
                            v1:Set(5,6,7)
                            CS.UnityEngine.Debug.Log(v1.x)
                            ");
            luaenv.Dispose();
        }

以调用到normalized为例

Utils.RegisterFunc(L, Utils.GETTER_IDX, "normalized", _g_get_normalized);

....

 [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int _g_get_normalized(RealStatePtr L)
        {
		    try {
                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
			
                UnityEngine.Vector3 gen_to_be_invoked;
                translator.Get(L, 1, out gen_to_be_invoked);
                translator.PushUnityEngineVector3(L, gen_to_be_invoked.normalized);
            } catch(System.Exception gen_e) {
                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
            }
            return 1;
        }

上面那步在lua虚拟机注册normalized,对应是C#里的函数。

函数中先获得Vector3变量然后调用C#中的normalized,最后再进行压栈操作供lua使用。

这块看出来,实际上lua还是去调用C#的代码,并且伴随压栈出栈操作。这就是为什么我们的lua的代码减少 . 这样的调用能节约一些性能的原因。

再换个函数Set

       [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int _m_Set(RealStatePtr L)
        {
		    try {
            
                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
                UnityEngine.Vector3 gen_to_be_invoked;translator.Get(L, 1, out gen_to_be_invoked);
                {
                    float _newX = (float)LuaAPI.lua_tonumber(L, 2);
                    float _newY = (float)LuaAPI.lua_tonumber(L, 3);
                    float _newZ = (float)LuaAPI.lua_tonumber(L, 4);
                    gen_to_be_invoked.Set( _newX, _newY, _newZ );
                    translator.UpdateUnityEngineVector3(L, 1, gen_to_be_invoked);
                    return 0;
                }
                
            } catch(System.Exception gen_e) {
                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
            }
        }

前面的部分跟normalized差不多看下UpdateUnityEngineVector3部分

public void UpdateUnityEngineVector3(RealStatePtr L, int index, UnityEngine.Vector3 val)
        {
            if (LuaAPI.lua_type(L, index) == LuaTypes.LUA_TUSERDATA)
            {
			    if (LuaAPI.xlua_gettypeid(L, index) != UnityEngineVector3_TypeID)
				{
				    throw new Exception("invalid userdata for UnityEngine.Vector3");
				}
				
                IntPtr buff = LuaAPI.lua_touserdata(L, index);
                if (!CopyByValue.Pack(buff, 0,  val))
                {
                    throw new Exception("pack fail for UnityEngine.Vector3 ,value="+val);
                }
            }
            else
            {
                throw new Exception("try to update a data with lua type:" + LuaAPI.lua_type(L, index));
            }
        }

这里看到对应lua来说C#的结构体、类都是UserData。C#想要去改变lua内的内存使用

CopyByValue.Pack函数进行拷贝

再拿个GameObject的Component举例,加深下印象:

luaenv.DoString(@"local v1 = CS.UnityEngine.GameObject()
                  local v2 = v1:AddComponent(typeof(CS.UnityEngine.Camera))
                ");

[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int _m_AddComponent(RealStatePtr L)
        {
		    try {
            
                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            
            
                UnityEngine.GameObject gen_to_be_invoked = (UnityEngine.GameObject)translator.FastGetCSObj(L, 1);
            
            
                
                {
                    System.Type _componentType = (System.Type)translator.GetObject(L, 2, typeof(System.Type));
                    
                        var gen_ret = gen_to_be_invoked.AddComponent( _componentType );
                        translator.Push(L, gen_ret);
                    
                    
                    
                    return 1;
                }
                
            } catch(System.Exception gen_e) {
                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
            }
            
        }

这里有个函数getCsObj用于取游戏对象

private object getCsObj(RealStatePtr L, int index, int udata)
        {
            object obj;
            if (udata == -1)
            {
                if (LuaAPI.lua_type(L, index) != LuaTypes.LUA_TUSERDATA) return null;

                Type type = GetTypeOf(L, index);
                if (type == typeof(decimal))
                {
                    decimal v;
                    Get(L, index, out v);
                    return v;
                }
                GetCSObject get;
                if (type != null && custom_get_funcs.TryGetValue(type, out get))
                {
                    return get(L, index);
                }
                else
                {
                    return null;
                }
            }
            else if (objects.TryGetValue(udata, out obj))
            {
#if !UNITY_5 && !XLUA_GENERAL && !UNITY_2017 && !UNITY_2017_1_OR_NEWER && !UNITY_2018
                if (obj != null && obj is UnityEngine.Object && ((obj as UnityEngine.Object) == null))
                {
                    //throw new UnityEngine.MissingReferenceException("The object of type '"+ obj.GetType().Name +"' has been destroyed but you are still trying to access it.");
                    return null;
                }
#endif
                return obj;
            }
            return null;
        }

这里从一个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文件生成为例:

模板对应文件:

#if USE_UNI_LUA
using LuaAPI = UniLua.Lua;
using RealStatePtr = UniLua.ILuaState;
using LuaCSFunction = UniLua.CSharpFunctionDelegate;
#else
using LuaAPI = XLua.LuaDLL.Lua;
using RealStatePtr = System.IntPtr;
using LuaCSFunction = XLua.LuaDLL.lua_CSFunction;
#endif

using XLua;
using System.Collections.Generic;
<%ForEachCsList(namespaces, function(namespace)%>using <%=namespace%>;<%end)%>
<%
require "TemplateCommon"

local OpNameMap = {
    op_Addition = "__AddMeta",
	op_Subtraction = "__SubMeta",
	op_Multiply = "__MulMeta",
	op_Division = "__DivMeta",
	op_Equality = "__EqMeta",
	op_UnaryNegation = "__UnmMeta",
	op_LessThan = "__LTMeta",
	op_LessThanOrEqual = "__LEMeta",
	op_Modulus = "__ModMeta",
    op_BitwiseAnd = "__BandMeta",
    op_BitwiseOr = "__BorMeta",
    op_ExclusiveOr = "__BxorMeta",
    op_OnesComplement = "__BnotMeta",
    op_LeftShift = "__ShlMeta",
    op_RightShift = "__ShrMeta",
}

local OpCallNameMap = {
    op_Addition = "+",
	op_Subtraction = "-",
	op_Multiply = "*",
	op_Division = "/",
	op_Equality = "==",
	op_UnaryNegation = "-",
	op_LessThan = "<",
	op_LessThanOrEqual = "<=",
	op_Modulus = "%",
	op_BitwiseAnd = "&",
    op_BitwiseOr = "|",
    op_ExclusiveOr = "^",
    op_OnesComplement = "~",
    op_LeftShift = "<<",
    op_RightShift = ">>",
}

local obj_method_count = 0
local obj_getter_count = 0
local obj_setter_count = 0
local meta_func_count = operators.Count
local cls_field_count = 1
local cls_getter_count = 0
local cls_setter_count = 0

ForEachCsList(methods, function(method)
    if method.IsStatic then
	    cls_field_count = cls_field_count + 1
	else
	    obj_method_count = obj_method_count + 1
    end 
end)

ForEachCsList(events, function(event)
    if event.IsStatic then
	    cls_field_count = cls_field_count + 1
	else
	    obj_method_count = obj_method_count + 1
    end 
end)

ForEachCsList(getters, function(getter)
    if getter.IsStatic then
	    if getter.ReadOnly then
	        cls_field_count = cls_field_count + 1
	    else
		    cls_getter_count = cls_getter_count + 1
		end
	else
	    obj_getter_count = obj_getter_count + 1
    end 
end)

ForEachCsList(setters, function(setter)
    if setter.IsStatic then
	    cls_setter_count = cls_setter_count + 1
	else
	    obj_setter_count = obj_setter_count + 1
    end 
end)

ForEachCsList(lazymembers, function(lazymember)
    if lazymember.IsStatic == 'true' then
	    if 'CLS_IDX' == lazymember.Index then
		    cls_field_count = cls_field_count + 1
	    elseif 'CLS_GETTER_IDX' == lazymember.Index then
		    cls_getter_count = cls_getter_count + 1
		elseif 'CLS_SETTER_IDX' == lazymember.Index then
		    cls_setter_count = cls_setter_count + 1
		end
	else
		if 'METHOD_IDX' == lazymember.Index then
		    obj_method_count = obj_method_count + 1
	    elseif 'GETTER_IDX' == lazymember.Index then
		    obj_getter_count = obj_getter_count + 1
		elseif 'SETTER_IDX' == lazymember.Index then
		    obj_setter_count = obj_setter_count + 1
		end
	end
end)

local generic_arg_list, type_constraints = GenericArgumentList(type)

%>
namespace XLua.CSObjectWrap
{
    using Utils = XLua.Utils;
    public class <%=CSVariableName(type)%>Wrap<%=generic_arg_list%> <%=type_constraints%>
    {
        public static void __Register(RealStatePtr L)
        {
			ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
			System.Type type = typeof(<%=CsFullTypeName(type)%>);
			Utils.BeginObjectRegister(type, L, translator, <%=meta_func_count%>, <%=obj_method_count%>, <%=obj_getter_count%>, <%=obj_setter_count%>);
			<%ForEachCsList(operators, function(operator)%>Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "<%=(OpNameMap[operator.Name]):gsub('Meta', ''):lower()%>", <%=OpNameMap[operator.Name]%>);
            <%end)%>
			<%ForEachCsList(methods, function(method) if not method.IsStatic then %>Utils.RegisterFunc(L, Utils.METHOD_IDX, "<%=method.Name%>", _m_<%=method.Name%>);
			<% end end)%>
			<%ForEachCsList(events, function(event) if not event.IsStatic then %>Utils.RegisterFunc(L, Utils.METHOD_IDX, "<%=event.Name%>", _e_<%=event.Name%>);
			<% end end)%>
			<%ForEachCsList(getters, function(getter) if not getter.IsStatic then %>Utils.RegisterFunc(L, Utils.GETTER_IDX, "<%=getter.Name%>", _g_get_<%=getter.Name%>);
            <%end end)%>
			<%ForEachCsList(setters, function(setter) if not setter.IsStatic then %>Utils.RegisterFunc(L, Utils.SETTER_IDX, "<%=setter.Name%>", _s_set_<%=setter.Name%>);
            <%end end)%>
			<%ForEachCsList(lazymembers, function(lazymember) if lazymember.IsStatic == 'false' then %>Utils.RegisterLazyFunc(L, Utils.<%=lazymember.Index%>, "<%=lazymember.Name%>", type, <%=lazymember.MemberType%>, <%=lazymember.IsStatic%>);
            <%end end)%>
			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%>,
			    null, null, null);

		    Utils.BeginClassRegister(type, L, __CreateInstance, <%=cls_field_count%>, <%=cls_getter_count%>, <%=cls_setter_count%>);
			<%ForEachCsList(methods, function(method) if method.IsStatic then %>Utils.RegisterFunc(L, Utils.CLS_IDX, "<%=method.Overloads[0].Name%>", _m_<%=method.Name%>);
            <% end end)%>
			<%ForEachCsList(events, function(event) if event.IsStatic then %>Utils.RegisterFunc(L, Utils.CLS_IDX, "<%=event.Name%>", _e_<%=event.Name%>);
			<% end end)%>
            <%ForEachCsList(getters, function(getter) if getter.IsStatic and getter.ReadOnly then %>Utils.RegisterObject(L, translator, Utils.CLS_IDX, "<%=getter.Name%>", <%=CsFullTypeName(type).."."..getter.Name%>);
            <%end end)%>
			<%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%>);
            <%end end)%>
			<%ForEachCsList(setters, function(setter) if setter.IsStatic then %>Utils.RegisterFunc(L, Utils.CLS_SETTER_IDX, "<%=setter.Name%>", _s_set_<%=setter.Name%>);
            <%end end)%>
			<%ForEachCsList(lazymembers, function(lazymember) if lazymember.IsStatic == 'true' then %>Utils.RegisterLazyFunc(L, Utils.<%=lazymember.Index%>, "<%=lazymember.Name%>", type, <%=lazymember.MemberType%>, <%=lazymember.IsStatic%>);
            <%end end)%>
			Utils.EndClassRegister(type, L, translator);
        }
        
        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int __CreateInstance(RealStatePtr L)
        {
            <% 
            if constructors.Count == 0 and (not type.IsValueType)  then 
            %>return LuaAPI.luaL_error(L, "<%=CsFullTypeName(type)%> does not have a constructor!");<% 
            else %>
			try {
                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
				<% 
				local hasZeroParamsCtor = false
				ForEachCsList(constructors, function(constructor, ci)
					local parameters = constructor:GetParameters()
					if parameters.Length == 0 then
					    hasZeroParamsCtor = true
					end
					local def_count = constructor_def_vals[ci]
					local param_count = parameters.Length
					local in_num = CalcCsList(parameters, function(p) return not (p.IsOut and p.ParameterType.IsByRef) end)
                    local out_num = CalcCsList(parameters, function(p) return p.IsOut or p.ParameterType.IsByRef end)
					local real_param_count = param_count - def_count
                    local has_v_params = param_count > 0 and IsParams(parameters[param_count - 1])
					local in_pos = 0
				%>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) 
                if pi >= real_param_count then return end 
                local parameterType = parameter.ParameterType
                if has_v_params and pi == param_count - 1 then  parameterType = parameterType:GetElementType() end
				if not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1
                %> && <%=GetCheckStatement(parameterType, in_pos+1, has_v_params and pi == param_count - 1)%><% 
				end
				end)%>)
				{
					<%ForEachCsList(parameters, function(parameter, pi) 
                    if pi >= real_param_count then return end 
                    %><%=GetCasterStatement(parameter.ParameterType, pi+2, LocalName(parameter.Name), true, has_v_params and pi == param_count - 1)%>;
					<%end)%>
					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)%>);
					<%=GetPushStatement(type, "gen_ret")%>;
                    <%local in_pos = 0
                    ForEachCsList(parameters, function(parameter, pi)
                        if pi >= real_param_count then return end
                        if not (parameter.IsOut and parameter.ParameterType.IsByRef) then 
                            in_pos = in_pos + 1
                        end
                        if parameter.ParameterType.IsByRef then
                        %><%=GetPushStatement(parameter.ParameterType:GetElementType(), LocalName(parameter.Name))%>;
                        <%if not parameter.IsOut and parameter.ParameterType.IsByRef and NeedUpdate(parameter.ParameterType) then 
                  %><%=GetUpdateStatement(parameter.ParameterType:GetElementType(), in_pos+1, LocalName(parameter.Name))%>;
                        <%end%>
                    <%
                        end
                    end)
                    %>
					return <%=out_num + 1%>;
				}
				<%end)
				if (not hasZeroParamsCtor) and type.IsValueType then
				%>
				if (LuaAPI.lua_gettop(L) == 1)
				{
				    <%=GetPushStatement(type, "default(" .. CsFullTypeName(type).. ")")%>;
			        return 1;
				}
				<%end%>
			}
			catch(System.Exception gen_e) {
				return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
			}
            return LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%> constructor!");
            <% end %>
        }
        
		<% if type.IsArray or ((indexers.Count or 0) > 0) then %>
        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        public static int __CSIndexer(RealStatePtr L)
        {
			<%if type.IsArray then %>
			try {
			    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
			
				if (<%=GetCheckStatement(type, 1)%> && LuaAPI.lua_isnumber(L, 2))
				{
					int index = (int)LuaAPI.lua_tonumber(L, 2);
					<%=GetSelfStatement(type)%>;
					LuaAPI.lua_pushboolean(L, true);
					<%=GetPushStatement(type:GetElementType(), "gen_to_be_invoked[index]")%>;
					return 2;
				}
			}
			catch(System.Exception gen_e) {
				return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
			}
			<%elseif indexers.Count > 0 then
			%>try {
			    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
				<%
					ForEachCsList(indexers, function(indexer)
						local paramter = indexer:GetParameters()[0]
				%>
				if (<%=GetCheckStatement(type, 1)%> && <%=GetCheckStatement(paramter.ParameterType, 2)%>)
				{
					
					<%=GetSelfStatement(type)%>;
					<%=GetCasterStatement(paramter.ParameterType, 2, "index", true)%>;
					LuaAPI.lua_pushboolean(L, true);
					<%=GetPushStatement(indexer.ReturnType, "gen_to_be_invoked[index]")%>;
					return 2;
				}
				<%end)%>
			}
			catch(System.Exception gen_e) {
				return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
			}
			<%end%>
            LuaAPI.lua_pushboolean(L, false);
			return 1;
        }
		<% end %>
        
		<%if type.IsArray or ((newindexers.Count or 0) > 0) then%>
        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        public static int __NewIndexer(RealStatePtr L)
        {
			<%if type.IsArray or newindexers.Count > 0 then %>ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);<%end%>
			<%if type.IsArray then 
				local elementType = type:GetElementType()
			%>
			try {
				if (<%=GetCheckStatement(type, 1)%> && LuaAPI.lua_isnumber(L, 2) && <%=GetCheckStatement(elementType, 3)%>)
				{
					int index = (int)LuaAPI.lua_tonumber(L, 2);
					<%=GetSelfStatement(type)%>;
					<%=GetCasterStatement(elementType, 3, "gen_to_be_invoked[index]")%>;
					LuaAPI.lua_pushboolean(L, true);
					return 1;
				}
			}
			catch(System.Exception gen_e) {
				return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
			}
			<%elseif newindexers.Count > 0 then%>
			try {
				<%ForEachCsList(newindexers, function(newindexer)
						local keyType = newindexer:GetParameters()[0].ParameterType
						local valueType = newindexer:GetParameters()[1].ParameterType
				%>
				if (<%=GetCheckStatement(type, 1)%> && <%=GetCheckStatement(keyType, 2)%> && <%=GetCheckStatement(valueType, 3)%>)
				{
					
					<%=GetSelfStatement(type)%>;
					<%=GetCasterStatement(keyType, 2, "key", true)%>;
					<%if IsStruct(valueType) then%><%=GetCasterStatement(valueType, 3, "gen_value", true)%>;
					gen_to_be_invoked[key] = gen_value;<%else
                  %><%=GetCasterStatement(valueType, 3, "gen_to_be_invoked[key]")%>;<%end%>
					LuaAPI.lua_pushboolean(L, true);
					return 1;
				}
				<%end)%>
			}
			catch(System.Exception gen_e) {
				return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
			}
			<%end%>
			LuaAPI.lua_pushboolean(L, false);
            return 1;
        }
		<% end %>
        
        <%ForEachCsList(operators, function(operator) %>
        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int <%=OpNameMap[operator.Name]%>(RealStatePtr L)
        {
            <% if operator.Name ~= "op_UnaryNegation" and operator.Name ~= "op_OnesComplement"  then %>
			try {
                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            <%ForEachCsList(operator.Overloads, function(overload)
                local left_param = overload:GetParameters()[0]
                local right_param = overload:GetParameters()[1]
            %>
			
				if (<%=GetCheckStatement(left_param.ParameterType, 1)%> && <%=GetCheckStatement(right_param.ParameterType, 2)%>)
				{
					<%=GetCasterStatement(left_param.ParameterType, 1, "leftside", true)%>;
					<%=GetCasterStatement(right_param.ParameterType, 2, "rightside", true)%>;
					
					<%=GetPushStatement(overload.ReturnType, "leftside " .. OpCallNameMap[operator.Name] .. " rightside")%>;
					
					return 1;
				}
            <%end)%>
			}
			catch(System.Exception gen_e) {
				return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
			}
            return LuaAPI.luaL_error(L, "invalid arguments to right hand of <%=OpCallNameMap[operator.Name]%> operator, need <%=CsFullTypeName(type)%>!");
            <%else%>
			ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            try {
                <%=GetCasterStatement(type, 1, "rightside", true)%>;
                <%=GetPushStatement(operator.Overloads[0].ReturnType, OpCallNameMap[operator.Name] .. " rightside")%>;
            } catch(System.Exception gen_e) {
                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
            }
            return 1;
            <%end%>
        }
        <%end)%>
        
        <%ForEachCsList(methods, function(method)%>
        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int _m_<%=method.Name%>(RealStatePtr L)
        {
		    try {
            <%
            local need_obj = not method.IsStatic
            if MethodCallNeedTranslator(method) then
            %>
                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
            <%end%>
            <%if need_obj then%>
                <%=GetSelfStatement(type)%>;
            <%end%>
            <%if method.Overloads.Count > 1 then%>
			    int gen_param_count = LuaAPI.lua_gettop(L);
            <%end%>
                <%ForEachCsList(method.Overloads, function(overload, oi)
                local parameters = MethodParameters(overload)
                local in_num = CalcCsList(parameters, function(p) return not (p.IsOut and p.ParameterType.IsByRef) end)
                local param_offset = method.IsStatic and 0 or 1
                local out_num = CalcCsList(parameters, function(p) return p.IsOut or p.ParameterType.IsByRef end)
                local in_pos = 0
                local has_return = (overload.ReturnType.FullName ~= "System.Void")
                local def_count = method.DefaultValues[oi]
				local param_count = parameters.Length
                local real_param_count = param_count - def_count
                local has_v_params = param_count > 0 and IsParams(parameters[param_count - 1])
                if method.Overloads.Count > 1 then
                %>if(gen_param_count <%=has_v_params and ">=" or "=="%> <%=in_num+param_offset-def_count - (has_v_params and 1 or 0)%><%
                    ForEachCsList(parameters, function(parameter, pi)
                        if pi >= real_param_count then return end
                        local parameterType = parameter.ParameterType
                        if has_v_params and pi == param_count - 1 then  parameterType = parameterType:GetElementType() end
                        if not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1; 
                        %>&& <%=GetCheckStatement(parameterType , in_pos+param_offset, has_v_params and pi == param_count - 1)%><% 
                        end 
                    end)%>) <%end%>
                {
                    <%if overload.Name == "get_Item" and overload.IsSpecialName then
					    local keyType = overload:GetParameters()[0].ParameterType%>
					<%=GetCasterStatement(keyType, 2, "key", true)%>;
					<%=GetPushStatement(overload.ReturnType, "gen_to_be_invoked[key]")%>;
					<%elseif overload.Name == "set_Item" and overload.IsSpecialName then
					    local keyType = overload:GetParameters()[0].ParameterType
						local valueType = overload:GetParameters()[1].ParameterType%>
					<%=GetCasterStatement(keyType, 2, "key", true)%>;
					<%=GetCasterStatement(valueType, 3, "gen_value", true)%>;
                    gen_to_be_invoked[key] = gen_value;
                    <% else
                    in_pos = 0;
                    ForEachCsList(parameters, function(parameter, pi) 
                        if pi >= real_param_count then return end
                        %><%if not (parameter.IsOut and parameter.ParameterType.IsByRef) then 
                            in_pos = in_pos + 1
                        %><%=GetCasterStatement(parameter.ParameterType, in_pos+param_offset, LocalName(parameter.Name), true, has_v_params and pi == param_count - 1)%><%
					    else%><%=CsFullTypeName(parameter.ParameterType)%> <%=LocalName(parameter.Name)%><%end%>;
                    <%end)%>
                    <%
                    if has_return then
                        %>    var gen_ret = <%
                    end
                    %><%if method.IsStatic then
                    %><%=CsFullTypeName(type).."."..UnK(overload.Name)%><%
                    else
                    %>gen_to_be_invoked.<%=UnK(overload.Name)%><%
                    end%>( <%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) %> );
                    <%
                    if has_return then
                    %>    <%=GetPushStatement(overload.ReturnType, "gen_ret")%>;
                    <%
                    end
                    local in_pos = 0
                    ForEachCsList(parameters, function(parameter, pi)
                        if pi >= real_param_count then return end
                        if not (parameter.IsOut and parameter.ParameterType.IsByRef) then 
                            in_pos = in_pos + 1
                        end
                        if parameter.ParameterType.IsByRef then
                        %><%=GetPushStatement(parameter.ParameterType:GetElementType(), LocalName(parameter.Name))%>;
                        <%if not parameter.IsOut and parameter.ParameterType.IsByRef and NeedUpdate(parameter.ParameterType) then 
                  %><%=GetUpdateStatement(parameter.ParameterType:GetElementType(), in_pos+param_offset, LocalName(parameter.Name))%>;
                        <%end%>
                    <%
                        end
                    end)
					end
                    %>
                    <%if NeedUpdate(type) and not method.IsStatic then%>
                        <%=GetUpdateStatement(type, 1, "gen_to_be_invoked")%>;
                    <%end%>
                    
                    return <%=out_num+(has_return and 1 or 0)%>;
                }
                <% end)%>
            } catch(System.Exception gen_e) {
                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
            }
            <%if method.Overloads.Count > 1 then%>
            return LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%>.<%=method.Overloads[0].Name%>!");
            <%end%>
        }
        <% end)%>
        
        
        <%ForEachCsList(getters, function(getter) 
        if getter.IsStatic and getter.ReadOnly then return end --readonly static
        %>
        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int _g_get_<%=getter.Name%>(RealStatePtr L)
        {
		    try {
            <%if AccessorNeedTranslator(getter) then %>    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);<%end%>
			<%if not getter.IsStatic then%>
                <%=GetSelfStatement(type)%>;
                <%=GetPushStatement(getter.Type, "gen_to_be_invoked."..UnK(getter.Name))%>;<% else %>    <%=GetPushStatement(getter.Type, CsFullTypeName(type).."."..UnK(getter.Name))%>;<% end%>
            } catch(System.Exception gen_e) {
                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
            }
            return 1;
        }
        <%end)%>
        
        <%ForEachCsList(setters, function(setter)
        local is_struct = IsStruct(setter.Type)
        %>
        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int _s_set_<%=setter.Name%>(RealStatePtr L)
        {
		    try {
                <%if AccessorNeedTranslator(setter) then %>ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);<%end%>
			<%if not setter.IsStatic then %>
                <%=GetSelfStatement(type)%>;
                <%if is_struct then %><%=GetCasterStatement(setter.Type, 2, "gen_value", true)%>;
				gen_to_be_invoked.<%=UnK(setter.Name)%> = gen_value;<% else 
              %><%=GetCasterStatement(setter.Type, 2, "gen_to_be_invoked." .. UnK(setter.Name))%>;<%end
            else 
				if is_struct then %><%=GetCasterStatement(setter.Type, 1, "gen_value", true)%>;
				<%=CsFullTypeName(type)%>.<%=UnK(setter.Name)%> = gen_value;<%else
          %>    <%=GetCasterStatement(setter.Type, 1, CsFullTypeName(type) .."." .. UnK(setter.Name))%>;<%end
            end%>
            <%if NeedUpdate(type) and not setter.IsStatic then%>
                <%=GetUpdateStatement(type, 1, "gen_to_be_invoked")%>;
            <%end%>
            } catch(System.Exception gen_e) {
                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
            }
            return 0;
        }
        <%end)%>
		
		<%ForEachCsList(events, function(event) if not event.IsStatic then %>
        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int _e_<%=event.Name%>(RealStatePtr L)
        {
		    try {
                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
			    int gen_param_count = LuaAPI.lua_gettop(L);
			<%=GetSelfStatement(type)%>;
                <%=GetCasterStatement(event.Type, 3, "gen_delegate", true)%>;
                if (gen_delegate == null) {
                    return LuaAPI.luaL_error(L, "#3 need <%=CsFullTypeName(event.Type)%>!");
                }
				
				if (gen_param_count == 3)
				{
					<%if event.CanAdd then%>
					if (LuaAPI.xlua_is_eq_str(L, 2, "+")) {
						gen_to_be_invoked.<%=UnK(event.Name)%> += gen_delegate;
						return 0;
					} 
					<%end%>
					<%if event.CanRemove then%>
					if (LuaAPI.xlua_is_eq_str(L, 2, "-")) {
						gen_to_be_invoked.<%=UnK(event.Name)%> -= gen_delegate;
						return 0;
					} 
					<%end%>
				}
			} catch(System.Exception gen_e) {
                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
            }
			LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%>.<%=event.Name%>!");
            return 0;
        }
        <%end end)%>
		
		<%ForEachCsList(events, function(event) if event.IsStatic then %>
        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]
        static int _e_<%=event.Name%>(RealStatePtr L)
        {
		    try {
                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);
			    int gen_param_count = LuaAPI.lua_gettop(L);
                <%=GetCasterStatement(event.Type, 2, "gen_delegate", true)%>;
                if (gen_delegate == null) {
                    return LuaAPI.luaL_error(L, "#2 need <%=CsFullTypeName(event.Type)%>!");
                }
                
				<%if event.CanAdd then%>
				if (gen_param_count == 2 && LuaAPI.xlua_is_eq_str(L, 1, "+")) {
					<%=CsFullTypeName(type)%>.<%=UnK(event.Name)%> += gen_delegate;
					return 0;
				} 
				<%end%>
				<%if event.CanRemove then%>
				if (gen_param_count == 2 && LuaAPI.xlua_is_eq_str(L, 1, "-")) {
					<%=CsFullTypeName(type)%>.<%=UnK(event.Name)%> -= gen_delegate;
					return 0;
				} 
				<%end%>
			} catch(System.Exception gen_e) {
                return LuaAPI.luaL_error(L, "c# exception:" + gen_e);
            }
			return LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%>.<%=event.Name%>!");
        }
        <%end end)%>
    }
}

这里好多的 如namespace,ForEachCsList,CSVariableName等运行时会被对应的GameObject替换。

再打一下这个文件被预编译后的文件:

local __text_gen = {}
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")
ForEachCsList(namespaces, function(namespace)
table.insert(__text_gen, "using ")
table.insert(__text_gen, tostring(namespace))
table.insert(__text_gen, ";")
end)
table.insert(__text_gen, "\r\n")

require "TemplateCommon"

local OpNameMap = {
    op_Addition = "__AddMeta",
	op_Subtraction = "__SubMeta",
	op_Multiply = "__MulMeta",
	op_Division = "__DivMeta",
	op_Equality = "__EqMeta",
	op_UnaryNegation = "__UnmMeta",
	op_LessThan = "__LTMeta",
	op_LessThanOrEqual = "__LEMeta",
	op_Modulus = "__ModMeta",
    op_BitwiseAnd = "__BandMeta",
    op_BitwiseOr = "__BorMeta",
    op_ExclusiveOr = "__BxorMeta",
    op_OnesComplement = "__BnotMeta",
    op_LeftShift = "__ShlMeta",
    op_RightShift = "__ShrMeta",
}

local OpCallNameMap = {
    op_Addition = "+",
	op_Subtraction = "-",
	op_Multiply = "*",
	op_Division = "/",
	op_Equality = "==",
	op_UnaryNegation = "-",
	op_LessThan = "<",
	op_LessThanOrEqual = "<=",
	op_Modulus = "%",
	op_BitwiseAnd = "&",
    op_BitwiseOr = "|",
    op_ExclusiveOr = "^",
    op_OnesComplement = "~",
    op_LeftShift = "<<",
    op_RightShift = ">>",
}

local obj_method_count = 0
local obj_getter_count = 0
local obj_setter_count = 0
local meta_func_count = operators.Count
local cls_field_count = 1
local cls_getter_count = 0
local cls_setter_count = 0

ForEachCsList(methods, function(method)
    if method.IsStatic then
	    cls_field_count = cls_field_count + 1
	else
	    obj_method_count = obj_method_count + 1
    end 
end)

ForEachCsList(events, function(event)
    if event.IsStatic then
	    cls_field_count = cls_field_count + 1
	else
	    obj_method_count = obj_method_count + 1
    end 
end)

ForEachCsList(getters, function(getter)
    if getter.IsStatic then
	    if getter.ReadOnly then
	        cls_field_count = cls_field_count + 1
	    else
		    cls_getter_count = cls_getter_count + 1
		end
	else
	    obj_getter_count = obj_getter_count + 1
    end 
end)

ForEachCsList(setters, function(setter)
    if setter.IsStatic then
	    cls_setter_count = cls_setter_count + 1
	else
	    obj_setter_count = obj_setter_count + 1
    end 
end)

ForEachCsList(lazymembers, function(lazymember)
    if lazymember.IsStatic == 'true' then
	    if 'CLS_IDX' == lazymember.Index then
		    cls_field_count = cls_field_count + 1
	    elseif 'CLS_GETTER_IDX' == lazymember.Index then
		    cls_getter_count = cls_getter_count + 1
		elseif 'CLS_SETTER_IDX' == lazymember.Index then
		    cls_setter_count = cls_setter_count + 1
		end
	else
		if 'METHOD_IDX' == lazymember.Index then
		    obj_method_count = obj_method_count + 1
	    elseif 'GETTER_IDX' == lazymember.Index then
		    obj_getter_count = obj_getter_count + 1
		elseif 'SETTER_IDX' == lazymember.Index then
		    obj_setter_count = obj_setter_count + 1
		end
	end
end)

local generic_arg_list, type_constraints = GenericArgumentList(type)


table.insert(__text_gen, "\r\nnamespace XLua.CSObjectWrap\r\n{\r\n    using Utils = XLua.Utils;\r\n    public class ")
table.insert(__text_gen, tostring(CSVariableName(type)))
table.insert(__text_gen, "Wrap")
table.insert(__text_gen, tostring(generic_arg_list))
table.insert(__text_gen, " ")
table.insert(__text_gen, tostring(type_constraints))
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(")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, ");\r\n\t\t\tUtils.BeginObjectRegister(type, L, translator, ")
table.insert(__text_gen, tostring(meta_func_count))
table.insert(__text_gen, ", ")
table.insert(__text_gen, tostring(obj_method_count))
table.insert(__text_gen, ", ")
table.insert(__text_gen, tostring(obj_getter_count))
table.insert(__text_gen, ", ")
table.insert(__text_gen, tostring(obj_setter_count))
table.insert(__text_gen, ");\r\n\t\t\t")
ForEachCsList(operators, function(operator)
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.OBJ_META_IDX, \"")
table.insert(__text_gen, tostring((OpNameMap[operator.Name]):gsub('Meta', ''):lower()))
table.insert(__text_gen, "\", ")
table.insert(__text_gen, tostring(OpNameMap[operator.Name]))
table.insert(__text_gen, ");\r\n            ")
end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(methods, function(method) if not method.IsStatic then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.METHOD_IDX, \"")
table.insert(__text_gen, tostring(method.Name))
table.insert(__text_gen, "\", _m_")
table.insert(__text_gen, tostring(method.Name))
table.insert(__text_gen, ");\r\n\t\t\t")
 end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(events, function(event) if not event.IsStatic then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.METHOD_IDX, \"")
table.insert(__text_gen, tostring(event.Name))
table.insert(__text_gen, "\", _e_")
table.insert(__text_gen, tostring(event.Name))
table.insert(__text_gen, ");\r\n\t\t\t")
 end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(getters, function(getter) if not getter.IsStatic then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.GETTER_IDX, \"")
table.insert(__text_gen, tostring(getter.Name))
table.insert(__text_gen, "\", _g_get_")
table.insert(__text_gen, tostring(getter.Name))
table.insert(__text_gen, ");\r\n            ")
end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(setters, function(setter) if not setter.IsStatic then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.SETTER_IDX, \"")
table.insert(__text_gen, tostring(setter.Name))
table.insert(__text_gen, "\", _s_set_")
table.insert(__text_gen, tostring(setter.Name))
table.insert(__text_gen, ");\r\n            ")
end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(lazymembers, function(lazymember) if lazymember.IsStatic == 'false' then 
table.insert(__text_gen, "Utils.RegisterLazyFunc(L, Utils.")
table.insert(__text_gen, tostring(lazymember.Index))
table.insert(__text_gen, ", \"")
table.insert(__text_gen, tostring(lazymember.Name))
table.insert(__text_gen, "\", type, ")
table.insert(__text_gen, tostring(lazymember.MemberType))
table.insert(__text_gen, ", ")
table.insert(__text_gen, tostring(lazymember.IsStatic))
table.insert(__text_gen, ");\r\n            ")
end end)
table.insert(__text_gen, "\r\n\t\t\tUtils.EndObjectRegister(type, L, translator, ")
 if type.IsArray or ((indexers.Count or 0) > 0) then 
table.insert(__text_gen, "__CSIndexer")
else
table.insert(__text_gen, "null")
end
table.insert(__text_gen, ", ")
if type.IsArray or ((newindexers.Count or 0) > 0) then
table.insert(__text_gen, "__NewIndexer")
else
table.insert(__text_gen, "null")
end
table.insert(__text_gen, ",\r\n\t\t\t    null, null, null);\r\n\r\n\t\t    Utils.BeginClassRegister(type, L, __CreateInstance, ")
table.insert(__text_gen, tostring(cls_field_count))
table.insert(__text_gen, ", ")
table.insert(__text_gen, tostring(cls_getter_count))
table.insert(__text_gen, ", ")
table.insert(__text_gen, tostring(cls_setter_count))
table.insert(__text_gen, ");\r\n\t\t\t")
ForEachCsList(methods, function(method) if method.IsStatic then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.CLS_IDX, \"")
table.insert(__text_gen, tostring(method.Overloads[0].Name))
table.insert(__text_gen, "\", _m_")
table.insert(__text_gen, tostring(method.Name))
table.insert(__text_gen, ");\r\n            ")
 end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(events, function(event) if event.IsStatic then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.CLS_IDX, \"")
table.insert(__text_gen, tostring(event.Name))
table.insert(__text_gen, "\", _e_")
table.insert(__text_gen, tostring(event.Name))
table.insert(__text_gen, ");\r\n\t\t\t")
 end end)
table.insert(__text_gen, "\r\n            ")
ForEachCsList(getters, function(getter) if getter.IsStatic and getter.ReadOnly then 
table.insert(__text_gen, "Utils.RegisterObject(L, translator, Utils.CLS_IDX, \"")
table.insert(__text_gen, tostring(getter.Name))
table.insert(__text_gen, "\", ")
table.insert(__text_gen, tostring(CsFullTypeName(type).."."..getter.Name))
table.insert(__text_gen, ");\r\n            ")
end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(getters, function(getter) if getter.IsStatic and (not getter.ReadOnly) then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.CLS_GETTER_IDX, \"")
table.insert(__text_gen, tostring(getter.Name))
table.insert(__text_gen, "\", _g_get_")
table.insert(__text_gen, tostring(getter.Name))
table.insert(__text_gen, ");\r\n            ")
end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(setters, function(setter) if setter.IsStatic then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.CLS_SETTER_IDX, \"")
table.insert(__text_gen, tostring(setter.Name))
table.insert(__text_gen, "\", _s_set_")
table.insert(__text_gen, tostring(setter.Name))
table.insert(__text_gen, ");\r\n            ")
end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(lazymembers, function(lazymember) if lazymember.IsStatic == 'true' then 
table.insert(__text_gen, "Utils.RegisterLazyFunc(L, Utils.")
table.insert(__text_gen, tostring(lazymember.Index))
table.insert(__text_gen, ", \"")
table.insert(__text_gen, tostring(lazymember.Name))
table.insert(__text_gen, "\", type, ")
table.insert(__text_gen, tostring(lazymember.MemberType))
table.insert(__text_gen, ", ")
table.insert(__text_gen, tostring(lazymember.IsStatic))
table.insert(__text_gen, ");\r\n            ")
end end)
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            ")
 
            if constructors.Count == 0 and (not type.IsValueType)  then 
            
table.insert(__text_gen, "return LuaAPI.luaL_error(L, \"")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, " does not have a constructor!\");")
 
            else 
table.insert(__text_gen, "\r\n\t\t\ttry {\r\n                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n\t\t\t\t")
 
				local hasZeroParamsCtor = false
				ForEachCsList(constructors, function(constructor, ci)
					local parameters = constructor:GetParameters()
					if parameters.Length == 0 then
					    hasZeroParamsCtor = true
					end
					local def_count = constructor_def_vals[ci]
					local param_count = parameters.Length
					local in_num = CalcCsList(parameters, function(p) return not (p.IsOut and p.ParameterType.IsByRef) end)
                    local out_num = CalcCsList(parameters, function(p) return p.IsOut or p.ParameterType.IsByRef end)
					local real_param_count = param_count - def_count
                    local has_v_params = param_count > 0 and IsParams(parameters[param_count - 1])
					local in_pos = 0
				
table.insert(__text_gen, "if(LuaAPI.lua_gettop(L) ")
table.insert(__text_gen, tostring(has_v_params and ">=" or "=="))
table.insert(__text_gen, " ")
table.insert(__text_gen, tostring(in_num + 1 - def_count - (has_v_params and 1 or 0)))
ForEachCsList(parameters, function(parameter, pi) 
                if pi >= real_param_count then return end 
                local parameterType = parameter.ParameterType
                if has_v_params and pi == param_count - 1 then  parameterType = parameterType:GetElementType() end
				if not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1
                
table.insert(__text_gen, " && ")
table.insert(__text_gen, tostring(GetCheckStatement(parameterType, in_pos+1, has_v_params and pi == param_count - 1)))
 
				end
				end)
table.insert(__text_gen, ")\r\n\t\t\t\t{\r\n\t\t\t\t\t")
ForEachCsList(parameters, function(parameter, pi) 
                    if pi >= real_param_count then return end 
                    
table.insert(__text_gen, tostring(GetCasterStatement(parameter.ParameterType, pi+2, LocalName(parameter.Name), true, has_v_params and pi == param_count - 1)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
end)
table.insert(__text_gen, "\r\n\t\t\t\t\tvar gen_ret = new ")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, "(")
ForEachCsList(parameters, function(parameter, pi) if pi >= real_param_count then return end; if pi ~=0 then 
table.insert(__text_gen, tostring(', '))
 end ;if parameter.IsOut and parameter.ParameterType.IsByRef then 
table.insert(__text_gen, "out ")
 elseif parameter.ParameterType.IsByRef and not parameter.IsIn then 
table.insert(__text_gen, "ref ")
 end 
table.insert(__text_gen, tostring(LocalName(parameter.Name)))
 end)
table.insert(__text_gen, ");\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetPushStatement(type, "gen_ret")))
table.insert(__text_gen, ";\r\n                    ")
local in_pos = 0
                    ForEachCsList(parameters, function(parameter, pi)
                        if pi >= real_param_count then return end
                        if not (parameter.IsOut and parameter.ParameterType.IsByRef) then 
                            in_pos = in_pos + 1
                        end
                        if parameter.ParameterType.IsByRef then
                        
table.insert(__text_gen, tostring(GetPushStatement(parameter.ParameterType:GetElementType(), LocalName(parameter.Name))))
table.insert(__text_gen, ";\r\n                        ")
if not parameter.IsOut and parameter.ParameterType.IsByRef and NeedUpdate(parameter.ParameterType) then 
                  
table.insert(__text_gen, tostring(GetUpdateStatement(parameter.ParameterType:GetElementType(), in_pos+1, LocalName(parameter.Name))))
table.insert(__text_gen, ";\r\n                        ")
end
table.insert(__text_gen, "\r\n                    ")

                        end
                    end)
                    
table.insert(__text_gen, "\r\n\t\t\t\t\treturn ")
table.insert(__text_gen, tostring(out_num + 1))
table.insert(__text_gen, ";\r\n\t\t\t\t}\r\n\t\t\t\t")
end)
				if (not hasZeroParamsCtor) and type.IsValueType then
				
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    ")
table.insert(__text_gen, tostring(GetPushStatement(type, "default(" .. CsFullTypeName(type).. ")")))
table.insert(__text_gen, ";\r\n\t\t\t        return 1;\r\n\t\t\t\t}\r\n\t\t\t\t")
end
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 ")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, " constructor!\");\r\n            ")
 end 
table.insert(__text_gen, "\r\n        }\r\n        \r\n\t\t")
 if type.IsArray or ((indexers.Count or 0) > 0) then 
table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        public static int __CSIndexer(RealStatePtr L)\r\n        {\r\n\t\t\t")
if type.IsArray then 
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 (")
table.insert(__text_gen, tostring(GetCheckStatement(type, 1)))
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")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n\t\t\t\t\tLuaAPI.lua_pushboolean(L, true);\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetPushStatement(type:GetElementType(), "gen_to_be_invoked[index]")))
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")
elseif indexers.Count > 0 then
			
table.insert(__text_gen, "try {\r\n\t\t\t    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n\t\t\t\t")

					ForEachCsList(indexers, function(indexer)
						local paramter = indexer:GetParameters()[0]
				
table.insert(__text_gen, "\r\n\t\t\t\tif (")
table.insert(__text_gen, tostring(GetCheckStatement(type, 1)))
table.insert(__text_gen, " && ")
table.insert(__text_gen, tostring(GetCheckStatement(paramter.ParameterType, 2)))
table.insert(__text_gen, ")\r\n\t\t\t\t{\r\n\t\t\t\t\t\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(paramter.ParameterType, 2, "index", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t\tLuaAPI.lua_pushboolean(L, true);\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetPushStatement(indexer.ReturnType, "gen_to_be_invoked[index]")))
table.insert(__text_gen, ";\r\n\t\t\t\t\treturn 2;\r\n\t\t\t\t}\r\n\t\t\t\t")
end)
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")
end
table.insert(__text_gen, "\r\n            LuaAPI.lua_pushboolean(L, false);\r\n\t\t\treturn 1;\r\n        }\r\n\t\t")
 end 
table.insert(__text_gen, "\r\n        \r\n\t\t")
if type.IsArray or ((newindexers.Count or 0) > 0) then
table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        public static int __NewIndexer(RealStatePtr L)\r\n        {\r\n\t\t\t")
if type.IsArray or newindexers.Count > 0 then 
table.insert(__text_gen, "ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);")
end
table.insert(__text_gen, "\r\n\t\t\t")
if type.IsArray then 
				local elementType = type:GetElementType()
			
table.insert(__text_gen, "\r\n\t\t\ttry {\r\n\t\t\t\tif (")
table.insert(__text_gen, tostring(GetCheckStatement(type, 1)))
table.insert(__text_gen, " && LuaAPI.lua_isnumber(L, 2) && ")
table.insert(__text_gen, tostring(GetCheckStatement(elementType, 3)))
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")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(elementType, 3, "gen_to_be_invoked[index]")))
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")
elseif newindexers.Count > 0 then
table.insert(__text_gen, "\r\n\t\t\ttry {\r\n\t\t\t\t")
ForEachCsList(newindexers, function(newindexer)
						local keyType = newindexer:GetParameters()[0].ParameterType
						local valueType = newindexer:GetParameters()[1].ParameterType
				
table.insert(__text_gen, "\r\n\t\t\t\tif (")
table.insert(__text_gen, tostring(GetCheckStatement(type, 1)))
table.insert(__text_gen, " && ")
table.insert(__text_gen, tostring(GetCheckStatement(keyType, 2)))
table.insert(__text_gen, " && ")
table.insert(__text_gen, tostring(GetCheckStatement(valueType, 3)))
table.insert(__text_gen, ")\r\n\t\t\t\t{\r\n\t\t\t\t\t\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(keyType, 2, "key", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
if IsStruct(valueType) then
table.insert(__text_gen, tostring(GetCasterStatement(valueType, 3, "gen_value", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t\tgen_to_be_invoked[key] = gen_value;")
else
                  
table.insert(__text_gen, tostring(GetCasterStatement(valueType, 3, "gen_to_be_invoked[key]")))
table.insert(__text_gen, ";")
end
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")
end)
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")
end
table.insert(__text_gen, "\r\n\t\t\tLuaAPI.lua_pushboolean(L, false);\r\n            return 1;\r\n        }\r\n\t\t")
 end 
table.insert(__text_gen, "\r\n        \r\n        ")
ForEachCsList(operators, function(operator) 
table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int ")
table.insert(__text_gen, tostring(OpNameMap[operator.Name]))
table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n            ")
 if operator.Name ~= "op_UnaryNegation" and operator.Name ~= "op_OnesComplement"  then 
table.insert(__text_gen, "\r\n\t\t\ttry {\r\n                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n            ")
ForEachCsList(operator.Overloads, function(overload)
                local left_param = overload:GetParameters()[0]
                local right_param = overload:GetParameters()[1]
            
table.insert(__text_gen, "\r\n\t\t\t\r\n\t\t\t\tif (")
table.insert(__text_gen, tostring(GetCheckStatement(left_param.ParameterType, 1)))
table.insert(__text_gen, " && ")
table.insert(__text_gen, tostring(GetCheckStatement(right_param.ParameterType, 2)))
table.insert(__text_gen, ")\r\n\t\t\t\t{\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(left_param.ParameterType, 1, "leftside", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(right_param.ParameterType, 2, "rightside", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetPushStatement(overload.ReturnType, "leftside " .. OpCallNameMap[operator.Name] .. " rightside")))
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            ")
end)
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 ")
table.insert(__text_gen, tostring(OpCallNameMap[operator.Name]))
table.insert(__text_gen, " operator, need ")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, "!\");\r\n            ")
else
table.insert(__text_gen, "\r\n\t\t\tObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n            try {\r\n                ")
table.insert(__text_gen, tostring(GetCasterStatement(type, 1, "rightside", true)))
table.insert(__text_gen, ";\r\n                ")
table.insert(__text_gen, tostring(GetPushStatement(operator.Overloads[0].ReturnType, OpCallNameMap[operator.Name] .. " rightside")))
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            ")
end
table.insert(__text_gen, "\r\n        }\r\n        ")
end)
table.insert(__text_gen, "\r\n        \r\n        ")
ForEachCsList(methods, function(method)
table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _m_")
table.insert(__text_gen, tostring(method.Name))
table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n\t\t    try {\r\n            ")

            local need_obj = not method.IsStatic
            if MethodCallNeedTranslator(method) then
            
table.insert(__text_gen, "\r\n                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n            ")
end
table.insert(__text_gen, "\r\n            ")
if need_obj then
table.insert(__text_gen, "\r\n                ")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n            ")
end
table.insert(__text_gen, "\r\n            ")
if method.Overloads.Count > 1 then
table.insert(__text_gen, "\r\n\t\t\t    int gen_param_count = LuaAPI.lua_gettop(L);\r\n            ")
end
table.insert(__text_gen, "\r\n                ")
ForEachCsList(method.Overloads, function(overload, oi)
                local parameters = MethodParameters(overload)
                local in_num = CalcCsList(parameters, function(p) return not (p.IsOut and p.ParameterType.IsByRef) end)
                local param_offset = method.IsStatic and 0 or 1
                local out_num = CalcCsList(parameters, function(p) return p.IsOut or p.ParameterType.IsByRef end)
                local in_pos = 0
                local has_return = (overload.ReturnType.FullName ~= "System.Void")
                local def_count = method.DefaultValues[oi]
				local param_count = parameters.Length
                local real_param_count = param_count - def_count
                local has_v_params = param_count > 0 and IsParams(parameters[param_count - 1])
                if method.Overloads.Count > 1 then
                
table.insert(__text_gen, "if(gen_param_count ")
table.insert(__text_gen, tostring(has_v_params and ">=" or "=="))
table.insert(__text_gen, " ")
table.insert(__text_gen, tostring(in_num+param_offset-def_count - (has_v_params and 1 or 0)))

                    ForEachCsList(parameters, function(parameter, pi)
                        if pi >= real_param_count then return end
                        local parameterType = parameter.ParameterType
                        if has_v_params and pi == param_count - 1 then  parameterType = parameterType:GetElementType() end
                        if not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1; 
                        
table.insert(__text_gen, "&& ")
table.insert(__text_gen, tostring(GetCheckStatement(parameterType , in_pos+param_offset, has_v_params and pi == param_count - 1)))
 
                        end 
                    end)
table.insert(__text_gen, ") ")
end
table.insert(__text_gen, "\r\n                {\r\n                    ")
if overload.Name == "get_Item" and overload.IsSpecialName then
					    local keyType = overload:GetParameters()[0].ParameterType
table.insert(__text_gen, "\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(keyType, 2, "key", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetPushStatement(overload.ReturnType, "gen_to_be_invoked[key]")))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
elseif overload.Name == "set_Item" and overload.IsSpecialName then
					    local keyType = overload:GetParameters()[0].ParameterType
						local valueType = overload:GetParameters()[1].ParameterType
table.insert(__text_gen, "\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(keyType, 2, "key", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(valueType, 3, "gen_value", true)))
table.insert(__text_gen, ";\r\n                    gen_to_be_invoked[key] = gen_value;\r\n                    ")
 else
                    in_pos = 0;
                    ForEachCsList(parameters, function(parameter, pi) 
                        if pi >= real_param_count then return end
                        
if not (parameter.IsOut and parameter.ParameterType.IsByRef) then 
                            in_pos = in_pos + 1
                        
table.insert(__text_gen, tostring(GetCasterStatement(parameter.ParameterType, in_pos+param_offset, LocalName(parameter.Name), true, has_v_params and pi == param_count - 1)))

					    else
table.insert(__text_gen, tostring(CsFullTypeName(parameter.ParameterType)))
table.insert(__text_gen, " ")
table.insert(__text_gen, tostring(LocalName(parameter.Name)))
end
table.insert(__text_gen, ";\r\n                    ")
end)
table.insert(__text_gen, "\r\n                    ")

                    if has_return then
                        
table.insert(__text_gen, "    var gen_ret = ")

                    end
                    
if method.IsStatic then
                    
table.insert(__text_gen, tostring(CsFullTypeName(type).."."..UnK(overload.Name)))

                    else
                    
table.insert(__text_gen, "gen_to_be_invoked.")
table.insert(__text_gen, tostring(UnK(overload.Name)))

                    end
table.insert(__text_gen, "( ")
ForEachCsList(parameters, function(parameter, pi) 
                        if pi >= real_param_count then return end
                        if pi ~= 0 then 
table.insert(__text_gen, ", ")
 end; if parameter.IsOut and parameter.ParameterType.IsByRef then 
table.insert(__text_gen, "out ")
 elseif parameter.ParameterType.IsByRef and not parameter.IsIn then 
table.insert(__text_gen, "ref ")
 end 
table.insert(__text_gen, tostring(LocalName(parameter.Name)))
 end) 
table.insert(__text_gen, " );\r\n                    ")

                    if has_return then
                    
table.insert(__text_gen, "    ")
table.insert(__text_gen, tostring(GetPushStatement(overload.ReturnType, "gen_ret")))
table.insert(__text_gen, ";\r\n                    ")

                    end
                    local in_pos = 0
                    ForEachCsList(parameters, function(parameter, pi)
                        if pi >= real_param_count then return end
                        if not (parameter.IsOut and parameter.ParameterType.IsByRef) then 
                            in_pos = in_pos + 1
                        end
                        if parameter.ParameterType.IsByRef then
                        
table.insert(__text_gen, tostring(GetPushStatement(parameter.ParameterType:GetElementType(), LocalName(parameter.Name))))
table.insert(__text_gen, ";\r\n                        ")
if not parameter.IsOut and parameter.ParameterType.IsByRef and NeedUpdate(parameter.ParameterType) then 
                  
table.insert(__text_gen, tostring(GetUpdateStatement(parameter.ParameterType:GetElementType(), in_pos+param_offset, LocalName(parameter.Name))))
table.insert(__text_gen, ";\r\n                        ")
end
table.insert(__text_gen, "\r\n                    ")

                        end
                    end)
					end
                    
table.insert(__text_gen, "\r\n                    ")
if NeedUpdate(type) and not method.IsStatic then
table.insert(__text_gen, "\r\n                        ")
table.insert(__text_gen, tostring(GetUpdateStatement(type, 1, "gen_to_be_invoked")))
table.insert(__text_gen, ";\r\n                    ")
end
table.insert(__text_gen, "\r\n                    \r\n                    return ")
table.insert(__text_gen, tostring(out_num+(has_return and 1 or 0)))
table.insert(__text_gen, ";\r\n                }\r\n                ")
 end)
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            ")
if method.Overloads.Count > 1 then
table.insert(__text_gen, "\r\n            return LuaAPI.luaL_error(L, \"invalid arguments to ")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, ".")
table.insert(__text_gen, tostring(method.Overloads[0].Name))
table.insert(__text_gen, "!\");\r\n            ")
end
table.insert(__text_gen, "\r\n        }\r\n        ")
 end)
table.insert(__text_gen, "\r\n        \r\n        \r\n        ")
ForEachCsList(getters, function(getter) 
        if getter.IsStatic and getter.ReadOnly then return end --readonly static
        
table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _g_get_")
table.insert(__text_gen, tostring(getter.Name))
table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n\t\t    try {\r\n            ")
if AccessorNeedTranslator(getter) then 
table.insert(__text_gen, "    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);")
end
table.insert(__text_gen, "\r\n\t\t\t")
if not getter.IsStatic then
table.insert(__text_gen, "\r\n                ")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n                ")
table.insert(__text_gen, tostring(GetPushStatement(getter.Type, "gen_to_be_invoked."..UnK(getter.Name))))
table.insert(__text_gen, ";")
 else 
table.insert(__text_gen, "    ")
table.insert(__text_gen, tostring(GetPushStatement(getter.Type, CsFullTypeName(type).."."..UnK(getter.Name))))
table.insert(__text_gen, ";")
 end
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        ")
end)
table.insert(__text_gen, "\r\n        \r\n        ")
ForEachCsList(setters, function(setter)
        local is_struct = IsStruct(setter.Type)
        
table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _s_set_")
table.insert(__text_gen, tostring(setter.Name))
table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n\t\t    try {\r\n                ")
if AccessorNeedTranslator(setter) then 
table.insert(__text_gen, "ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);")
end
table.insert(__text_gen, "\r\n\t\t\t")
if not setter.IsStatic then 
table.insert(__text_gen, "\r\n                ")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n                ")
if is_struct then 
table.insert(__text_gen, tostring(GetCasterStatement(setter.Type, 2, "gen_value", true)))
table.insert(__text_gen, ";\r\n\t\t\t\tgen_to_be_invoked.")
table.insert(__text_gen, tostring(UnK(setter.Name)))
table.insert(__text_gen, " = gen_value;")
 else 
              
table.insert(__text_gen, tostring(GetCasterStatement(setter.Type, 2, "gen_to_be_invoked." .. UnK(setter.Name))))
table.insert(__text_gen, ";")
end
            else 
				if is_struct then 
table.insert(__text_gen, tostring(GetCasterStatement(setter.Type, 1, "gen_value", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, ".")
table.insert(__text_gen, tostring(UnK(setter.Name)))
table.insert(__text_gen, " = gen_value;")
else
          
table.insert(__text_gen, "    ")
table.insert(__text_gen, tostring(GetCasterStatement(setter.Type, 1, CsFullTypeName(type) .."." .. UnK(setter.Name))))
table.insert(__text_gen, ";")
end
            end
table.insert(__text_gen, "\r\n            ")
if NeedUpdate(type) and not setter.IsStatic then
table.insert(__text_gen, "\r\n                ")
table.insert(__text_gen, tostring(GetUpdateStatement(type, 1, "gen_to_be_invoked")))
table.insert(__text_gen, ";\r\n            ")
end
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        ")
end)
table.insert(__text_gen, "\r\n\t\t\r\n\t\t")
ForEachCsList(events, function(event) if not event.IsStatic then 
table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _e_")
table.insert(__text_gen, tostring(event.Name))
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")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n                ")
table.insert(__text_gen, tostring(GetCasterStatement(event.Type, 3, "gen_delegate", true)))
table.insert(__text_gen, ";\r\n                if (gen_delegate == null) {\r\n                    return LuaAPI.luaL_error(L, \"#3 need ")
table.insert(__text_gen, tostring(CsFullTypeName(event.Type)))
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")
if event.CanAdd then
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.")
table.insert(__text_gen, tostring(UnK(event.Name)))
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")
end
table.insert(__text_gen, "\r\n\t\t\t\t\t")
if event.CanRemove then
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.")
table.insert(__text_gen, tostring(UnK(event.Name)))
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")
end
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 ")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, ".")
table.insert(__text_gen, tostring(event.Name))
table.insert(__text_gen, "!\");\r\n            return 0;\r\n        }\r\n        ")
end end)
table.insert(__text_gen, "\r\n\t\t\r\n\t\t")
ForEachCsList(events, function(event) if event.IsStatic then 
table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _e_")
table.insert(__text_gen, tostring(event.Name))
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                ")
table.insert(__text_gen, tostring(GetCasterStatement(event.Type, 2, "gen_delegate", true)))
table.insert(__text_gen, ";\r\n                if (gen_delegate == null) {\r\n                    return LuaAPI.luaL_error(L, \"#2 need ")
table.insert(__text_gen, tostring(CsFullTypeName(event.Type)))
table.insert(__text_gen, "!\");\r\n                }\r\n                \r\n\t\t\t\t")
if event.CanAdd then
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")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, ".")
table.insert(__text_gen, tostring(UnK(event.Name)))
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")
end
table.insert(__text_gen, "\r\n\t\t\t\t")
if event.CanRemove then
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")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, ".")
table.insert(__text_gen, tostring(UnK(event.Name)))
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")
end
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 ")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, ".")
table.insert(__text_gen, tostring(event.Name))
table.insert(__text_gen, "!\");\r\n        }\r\n        ")
end end)
table.insert(__text_gen, "\r\n    }\r\n}\r\n")
return table.concat(__text_gen)
到这里看到模板在内存中对应变成了一个生成的方法,对应传进C#的替换字符。

替换比较复杂不一一分析了。大概就是C#对应类的成员变量,静态方法等所有元数据替换成table的表里,一个循环遍历进行插入字符比如下面的GameObject的构造函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1942146.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt实现简易CAD软件的开发:技术解析与实现

文章目录 简易CAD软件的开发&#xff1a;技术解析与实现引言项目概述程序入口主窗口的实现主窗口类定义&#xff08;mainwindow.h&#xff09;主窗口类实现&#xff08;mainwindow.cpp&#xff09; 自定义绘图视图自定义绘图视图类定义&#xff08;myqgraphicsview.h&#xff0…

ISP代理和双ISP代理:区别和优势

随着互联网技术的不断发展和普及&#xff0c;网络代理服务成为众多用户保护隐私、提高网络性能、增强安全性的重要工具。其中&#xff0c;ISP代理和双ISP代理是两种常见的网络代理服务形式。本文将详细探讨ISP代理和双ISP代理的区别和优势&#xff0c;以便用户更好地了解并选择…

【数据脱敏】⭐️SpringBoot 整合 Jackson 实现隐私数据加密

目录 &#x1f378;前言 &#x1f37b;一、Jackson 序列化库 &#x1f37a;二、方案实践 2.1 环境准备 2.2 依赖引入 2.3 代码编写 &#x1f49e;️三、接口测试 &#x1f379;四、章末 &#x1f378;前言 小伙伴们大家好&#xff0c;最近也是很忙啊&#xff0c;上次的文章…

【人工智能】使用Python的dlib库实现人脸识别技术

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、引言二、传统人脸识别技术1. 基于几何特征的方法2. 基于模板匹配的方法3. 基于统计学习的方法 三、深度学习在脸识别中的应用1. 卷积神经网络&#xff08;CNN&#xff09;2. FaceNet和ArcFace 四、使用Python和dlib库实…

SpringBoot:SpringBoot通过注解监测Controller接口

一、前言 在Spring Boot中&#xff0c;度量指标&#xff08;Metrics&#xff09;是监控和诊断应用性能与行为的重要工具。Spring Boot通过集成Micrometer和Spring Boot Actuator&#xff0c;提供了强大的度量指标收集与暴露功能。 二、度量指标 1. Micrometer Micrometer是一…

C#基于SkiaSharp实现印章管理(4)

前几篇文章实现了绘制不同外形印章的功能&#xff0c;印章内部一般包含圆形、线条等形状&#xff0c;有些印章内部还有五角星&#xff0c;然后就是各种样式的文字。本文实现在印章内部绘制圆形、线条、矩形、椭圆等四种形状。   定义FigureType枚举记录印章内部形状&#xff…

Lua 语法学习笔记

Lua 语法学习笔记 安装(windows) 官网&#xff1a;https://www.lua.org/ 下载SDK 解压&修改名称&#xff08;去除版本号&#xff09; 将lua后面的版本号去掉&#xff0c;如lua54.exe->lua.ext 配置环境变量 数据类型 数据类型描述nil这个最简单&#xff0c;只有值n…

HTML 相册2.0 通过css 获取图片资源 2024/7/22 日志

简单方法通过css 绕过同源策略 以获取资源 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>水面倒影…

软件更新的双刃剑:从”微软蓝屏”事件看网络安全的挑战与对策

引言 原文链接 近日&#xff0c;一场由微软视窗系统软件更新引发的全球性"微软蓝屏"事件震惊了整个科技界。这次事件源于美国电脑安全技术公司"众击"提供的一个带有"缺陷"的软件更新&#xff0c;如同一颗隐形炸弹在全球范围内引爆&#xff0c;…

《数据结构:顺序实现二叉树》

文章目录 一、树1、树的结构与概念2、树相关术语 二、二叉树1、概念与结构2、满二叉树3、完全二叉树 三、顺序二叉树存储结构四、实现顺序结构二叉树1、堆的概念与结构2、堆的实现3、堆的排序 一、树 1、树的结构与概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff…

选购指南:如何挑选最适合的快手矩阵系统

在短视频风潮席卷的今天&#xff0c;快手作为其中的佼佼者&#xff0c;吸引了无数创作者和商家的目光。然而&#xff0c;想要在快手上脱颖而出&#xff0c;仅凭内容和创意是远远不够的。一个强大且适合的快手矩阵系统&#xff0c;将是你通往成功的重要钥匙。那么&#xff0c;如…

『 Linux 』信号概念与信号的产生

文章目录 信号概念前台进程与后台进程信号的本质硬件理解信号的产生 信号概念 "信号"一词指用来传达信息或只是的各种形式的提示或标志; 在生活中常见的信号例如红绿灯,交通标志,短信通知等 在操作系统中,"信号"是一种用于异步通知进程发生特定事件的机制;…

【iOS】——SideTable

SideTable Side Table主要用于存储和管理对象的额外信息&#xff0c;特别是与弱引用相关的数据。Side Table的设计和使用是Objective-C运行时实现弱引用的基础&#xff0c;使得ARC&#xff08;Automatic Reference Counting&#xff09;能够正确地处理弱引用的生命周期。 新版…

【深度学习】大模型GLM-4-9B Chat ,微调与部署

下载好东西&#xff1a; 启动容器环境: docker run -it --gpus all --net host --shm-size8g -v /ssd/xiedong/glm-4-9b-xd:/ssd/xiedong/glm-4-9b-xd kevinchina/deeplearning:pytorch2.3.0-cuda12.1-cudnn8-devel-yolov8train bashpip install typer tiktoken numpy1.2…

2024最新版虚拟便携空调小程序源码 支持流量主切换空调型号

产品截图 部分源代码展示 urls.js Object.defineProperty(exports, "__esModule", {value: !0 }), exports.default ["9c5f1fa582bee88300ffb7e28dce8b68_3188_128_128.png", "E-116154b04e91de689fb1c4ae99266dff_960.svg", "573eee719…

web每日一练

每日一题 每天一题罢了。。 ctfshow内部赛签到 扫到备份文件 login.php <?php function check($arr){ if(preg_match("/load|and|or|\||\&|select|union|\|| |\\\|,|sleep|ascii/i",$arr)){echo "<script>alert(bad hacker!)</script>&q…

windows网页视频下载器+Video DownloadHelper+IDM+唧唧down

1:Video DownloadHelper 第一步:下载 链接&#xff1a;https://pan.baidu.com/s/1tWlXcJsq0kY_qrn9pzfCXw?pwdcsy2 提取码&#xff1a;csy2 --来自百度网盘超级会员V4的分享 第二步:浏览器扩展 以edge为例:点击管理扩展: 点击"加载解压缩的扩展": 选中我们的文…

中科亿海微信号采集核心板在振动采集场景中的应用

在工业现场控制领域&#xff0c;对于旋转物体的速度我们通用的做法是测量旋转所产生的振动量来倒推设备的转速值。振动采集系统是一种广泛用于检测和记录系统振动的设备&#xff0c;整体包括传感器和数据采集两部分。传感器类型包括加速度传感器、速度传感器和位移传感器&#…

微信小程序:多图片显示及图片点击放大,多视频显示

微信小程序&#xff1a;多图片显示及图片点击放大&#xff0c;多视频显示 01 多图片显示及图片点击放大02 多视频03 全部代码 01 多图片显示及图片点击放大 <view><view class"title">图片&#xff1a;</view><block wx:if"{{photoUrlList…

什么是离线语音识别芯片?与在线语音识别的区别

离线语音识别芯片是一种不需要联网和其他外部设备支持&#xff0c;‌上电即可使用的语音识别系统。‌它的应用场合相对单一&#xff0c;‌主要适用于智能家电、‌语音遥控器、‌智能玩具等&#xff0c;‌以及车载声控和一部分智能家居。‌离线语音识别芯片的特点包括小词汇量、…