#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 v_type_name = CSVariableName(type) local generic_arg_list, type_constraints = GenericArgumentList(type) %> namespace XLua { public static partial class ObjectTranslator_Gen { public static void __Register<%=v_type_name%><%=generic_arg_list%>(this ObjectTranslator thiz, RealStatePtr L) <%=type_constraints%> { System.Type type = typeof(<%=CsFullTypeName(type)%>); Utils.BeginObjectRegister(type, L, thiz, <%=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()%>", thiz.<%=v_type_name%><%=OpNameMap[operator.Name]%><%=generic_arg_list%>); <%end)%> <%ForEachCsList(methods, function(method) if not method.IsStatic then %>Utils.RegisterFunc(L, Utils.METHOD_IDX, "<%=method.Name%>", thiz.<%=v_type_name%>_m_<%=method.Name%><%=generic_arg_list%>); <% end end)%> <%ForEachCsList(events, function(event) if not event.IsStatic then %>Utils.RegisterFunc(L, Utils.METHOD_IDX, "<%=event.Name%>", thiz.<%=v_type_name%>_e_<%=event.Name%><%=generic_arg_list%>); <% end end)%> <%ForEachCsList(getters, function(getter) if not getter.IsStatic then %>Utils.RegisterFunc(L, Utils.GETTER_IDX, "<%=getter.Name%>", thiz.<%=v_type_name%>_g_get_<%=getter.Name%><%=generic_arg_list%>); <%end end)%> <%ForEachCsList(setters, function(setter) if not setter.IsStatic then %>Utils.RegisterFunc(L, Utils.SETTER_IDX, "<%=setter.Name%>", thiz.<%=v_type_name%>_s_set_<%=setter.Name%><%=generic_arg_list%>); <%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, thiz, <% if type.IsArray or ((indexers.Count or 0) > 0) then %>thiz.__CSIndexer<%=v_type_name%><%=generic_arg_list%><%else%>null<%end%>, <%if type.IsArray or ((newindexers.Count or 0) > 0) then%>thiz.__NewIndexer<%=v_type_name%><%=generic_arg_list%><%else%>null<%end%>, null, null, null); Utils.BeginClassRegister(type, L, thiz.__CreateInstance<%=v_type_name%><%=generic_arg_list%>, <%=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%>", thiz.<%=v_type_name%>_m_<%=method.Name%><%=generic_arg_list%>); <% end end)%> <%ForEachCsList(events, function(event) if event.IsStatic then %>Utils.RegisterFunc(L, Utils.CLS_IDX, "<%=event.Name%>", thiz.<%=v_type_name%>_e_<%=event.Name%><%=generic_arg_list%>); <% end end)%> <%ForEachCsList(getters, function(getter) if getter.IsStatic and getter.ReadOnly then %>Utils.RegisterObject(L, thiz, 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%>", thiz.<%=v_type_name%>_g_get_<%=getter.Name%><%=generic_arg_list%>); <%end end)%> <%ForEachCsList(setters, function(setter) if setter.IsStatic then %>Utils.RegisterFunc(L, Utils.CLS_SETTER_IDX, "<%=setter.Name%>", thiz.<%=v_type_name%>_s_set_<%=setter.Name%><%=generic_arg_list%>); <%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, thiz); } static int __CreateInstance<%=v_type_name%><%=generic_arg_list%>(this ObjectTranslator thiz, RealStatePtr L, int gen_param_count) <%=type_constraints%> { <% if constructors.Count == 0 and (not type.IsValueType) then %>return LuaAPI.luaL_error(L, "<%=CsFullTypeName(type)%> does not have a constructor!");<% else %> ObjectTranslator translator = thiz; <% 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(gen_param_count <%=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)%> <%=CsFullTypeName(type)%> 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 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 (gen_param_count == 1) { <%=GetPushStatement(type, "default(" .. CsFullTypeName(type).. ")")%>; return 1; } <%end%> return LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%> constructor!"); <% end %> } <% if type.IsArray or ((indexers.Count or 0) > 0) then %> static int __CSIndexer<%=v_type_name%><%=generic_arg_list%>(this ObjectTranslator thiz, RealStatePtr L, int gen_param_count) <%=type_constraints%> { <%if type.IsArray then %> ObjectTranslator translator = thiz; 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; } <%elseif indexers.Count > 0 then %>ObjectTranslator translator = thiz; <% 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) end%> LuaAPI.lua_pushboolean(L, false); return 1; } <% end %> <%if type.IsArray or ((newindexers.Count or 0) > 0) then%> static int __NewIndexer<%=v_type_name%><%=generic_arg_list%>(this ObjectTranslator thiz, RealStatePtr L, int gen_param_count) <%=type_constraints%> { <%if type.IsArray or newindexers.Count > 0 then %>ObjectTranslator translator = thiz;<%end%> <%if type.IsArray then local elementType = type:GetElementType() %> 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; } <%elseif newindexers.Count > 0 then%> <%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) end%> LuaAPI.lua_pushboolean(L, false); return 1; } <% end %> <%ForEachCsList(operators, function(operator) %> static int <%=v_type_name%><%=OpNameMap[operator.Name]%><%=generic_arg_list%>(this ObjectTranslator thiz, RealStatePtr L, int gen_param_count) <%=type_constraints%> { ObjectTranslator translator = thiz; <% if operator.Name ~= "op_UnaryNegation" and operator.Name ~= "op_OnesComplement" then 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)%> return LuaAPI.luaL_error(L, "invalid arguments to right hand of <%=OpCallNameMap[operator.Name]%> operator, need <%=CsFullTypeName(type)%>!"); <%else%> <%=GetCasterStatement(type, 1, "rightside", true)%>; <%=GetPushStatement(operator.Overloads[0].ReturnType, OpCallNameMap[operator.Name] .. " rightside")%>; return 1; <%end%> } <%end)%> <%ForEachCsList(methods, function(method)%> static int <%=v_type_name%>_m_<%=method.Name%><%=generic_arg_list%>(this ObjectTranslator thiz, RealStatePtr L, int gen_param_count) <%=type_constraints%> { <% local need_obj = not method.IsStatic if MethodCallNeedTranslator(method) then %> ObjectTranslator translator = thiz; <%end%> <%if need_obj then%> <%=GetSelfStatement(type)%>; <%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_to_be_invoked[key]")%>; <% 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 %><%=CsFullTypeName(overload.ReturnType)%> 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)%> <%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 %> static int <%=v_type_name%>_g_get_<%=getter.Name%><%=generic_arg_list%>(this ObjectTranslator thiz, RealStatePtr L, int gen_param_count) <%=type_constraints%> { <%if AccessorNeedTranslator(getter) then %>ObjectTranslator translator = thiz;<%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%> return 1; } <%end)%> <%ForEachCsList(setters, function(setter) local is_struct = IsStruct(setter.Type) %> static int <%=v_type_name%>_s_set_<%=setter.Name%><%=generic_arg_list%>(this ObjectTranslator thiz, RealStatePtr L, int gen_param_count) <%=type_constraints%> { <%if AccessorNeedTranslator(setter) then %>ObjectTranslator translator = thiz;<%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%> return 0; } <%end)%> <%ForEachCsList(events, function(event) if not event.IsStatic then %> static int <%=v_type_name%>_e_<%=event.Name%><%=generic_arg_list%>(this ObjectTranslator thiz, RealStatePtr L, int gen_param_count) <%=type_constraints%> { ObjectTranslator translator = thiz; <%=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%> } LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%>.<%=event.Name%>!"); return 0; } <%end end)%> <%ForEachCsList(events, function(event) if event.IsStatic then %> static int <%=v_type_name%>_e_<%=event.Name%><%=generic_arg_list%>(this ObjectTranslator thiz, RealStatePtr L, int gen_param_count) <%=type_constraints%> { ObjectTranslator translator = thiz; <%=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%> return LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%>.<%=event.Name%>!"); } <%end end)%> } }