private void GenRegMemberFunction(CodeGener gener, Type type, MethodInfo[] methodGroup) { var temp = new List <CodeStatement>(); int count = 0; foreach (var methodInfo in methodGroup) { var args = methodInfo.GetParameters(); StringBuilder checkStringBuilder = new StringBuilder(); checkStringBuilder.Append($"L.CheckNum({args.Length + 1})"); if (args.Length > 0) { checkStringBuilder.Append($" && L.CheckType<"); StringBuilder typeArgs = new StringBuilder(); typeArgs.Append(type.FullName); for (int i = 0; i < args.Length; i++) { typeArgs.Append(", "); typeArgs.Append(args[i].ParameterType.FullName); } checkStringBuilder.Append(typeArgs); checkStringBuilder.Append($">(1)"); } if (count == 0) { temp.Add(new CodeSnippetStatement($"\t\t\tif({checkStringBuilder})\n\t\t\t{{")); } else { temp.Add(new CodeSnippetStatement($"\t\t\telse if({checkStringBuilder})\n\t\t\t{{")); } temp.Add(new CodeSnippetStatement($"\t\t\t\tvar obj = ({type.FullName}) L.ToObject(1);")); for (int i = 1; i <= args.Length; i++) { var paramInfo = args[i - 1]; temp.Add(new CodeSnippetStatement( $"\t\t\t\tvar arg{i} = L.{GetCheckString(paramInfo.ParameterType)}({i + 1});")); } var paramBuilder = new StringBuilder(); for (int i = 1; i <= args.Length; i++) { var paramInfo = args[i - 1]; if (i != 1) { paramBuilder.Append(", "); } paramBuilder.Append($"arg{i}"); } if (methodInfo.ReturnType == typeof(void)) { temp.Add(new CodeSnippetStatement($"\t\t\t\tobj.{methodInfo.Name}({paramBuilder});")); temp.Add(new CodeSnippetStatement("\t\t\t\treturn 0;")); } else { temp.Add(new CodeSnippetStatement($"\t\t\t\tvar result = obj.{methodInfo.Name}({paramBuilder});")); temp.Add(new CodeSnippetStatement($"\t\t\t\tL.{GetPushString(methodInfo.ReturnType)}(result);")); temp.Add(new CodeSnippetStatement("\t\t\t\treturn 1;")); } temp.Add(new CodeSnippetStatement($"\t\t\t}}")); count++; } temp.Add(new CodeSnippetStatement("\t\t\tL.L_Error(\"call function args is error\");")); temp.Add(new CodeSnippetStatement("\t\t\treturn 1;")); gener.AddMemberMethod(typeof(int), methodGroup[0].Name, new Dictionary <string, Type>() { { "L", typeof(ILuaState) } }, MemberAttributes.Private | MemberAttributes.Static, temp.ToArray()); }
private void GenConstructor(CodeGener gener, Type type) { //TODO var constructorInfos = type.GetConstructors(); var temp = new List <CodeStatement>(); int count = 0; foreach (var constructorInfo in constructorInfos) { var args = constructorInfo.GetParameters(); //检查类型的方法 StringBuilder checkStringBuilder = new StringBuilder(); checkStringBuilder.Append($"L.CheckNum({args.Length})"); if (args.Length > 0) { checkStringBuilder.Append($"&& L.CheckType<"); StringBuilder typeArgs = new StringBuilder(); for (int i = 0; i < args.Length; i++) { if (i != 0) { typeArgs.Append(", "); } typeArgs.Append(args[i].ParameterType.FullName); } checkStringBuilder.Append(typeArgs); checkStringBuilder.Append($">(0)"); } if (count == 0) { temp.Add(new CodeSnippetStatement($"\t\t\tif({checkStringBuilder})\n\t\t\t{{")); } else { temp.Add(new CodeSnippetStatement($"\t\t\telse if({checkStringBuilder})\n\t\t\t{{")); } for (int i = 1; i <= args.Length; i++) { var paramInfo = args[i - 1]; temp.Add(new CodeSnippetStatement($"\t\t\t\tvar arg{i} = L.{GetCheckString(paramInfo.ParameterType)}({i});")); } var paramBuilder = new StringBuilder(); for (int i = 1; i <= args.Length; i++) { if (i != 1) { paramBuilder.Append(", "); } paramBuilder.Append($"arg{i}"); } temp.Add(new CodeSnippetStatement($"\t\t\t\tL.{GetPushString(type)}(new {type.FullName}({paramBuilder}));")); temp.Add(new CodeSnippetStatement("\t\t\t\treturn 1;")); temp.Add(new CodeSnippetStatement($"\t\t\t}}")); count++; } temp.Add(new CodeSnippetStatement("\t\t\tL.L_Error(\"call function args is error\");")); temp.Add(new CodeSnippetStatement("\t\t\treturn 1;")); gener.AddMemberMethod(typeof(int), $"_Create{type.Name}", new Dictionary <string, Type>() { { "L", typeof(ILuaState) } }, MemberAttributes.Private | MemberAttributes.Static, temp.ToArray()); }
private void GenClass(Type classType) { if (classType == null) { return; } var className = GetClassFileName(classType); CodeGener gener = new CodeGener("UniToLua", className); var baseClassName = classType.BaseType == typeof(System.Object) || classType.BaseType == null ? "null" : classType.BaseType.FullName; var fields = classType.GetFields(); var propertys = classType.GetProperties(); var methodGroups = classType.GetMethods().Where((method) => { if (propertys.Count(prop => prop.GetMethod == method || prop.SetMethod == method) != 0) { return(false); } if (IsObsolete(method)) { return(false); } return(true); }).GroupBy(mi => mi.Name).ToArray(); List <CodeStatement> registerMethodStatement = new List <CodeStatement>(); registerMethodStatement.Add(new CodeSnippetStatement($"\t\t\tL.BeginClass(typeof({classType.FullName}), {baseClassName});")); registerMethodStatement.Add(new CodeSnippetStatement($"\t\t\tL.RegFunction(\"New\", _Create{classType.Name});")); foreach (var fieldInfo in fields) { registerMethodStatement.Add(new CodeSnippetStatement($"\t\t\tL.RegVar(\"{fieldInfo.Name}\", get_{fieldInfo.Name}, set_{fieldInfo.Name});")); } foreach (var propertyInfo in propertys) { StringBuilder builder = new StringBuilder($"\t\t\tL.RegVar(\"{propertyInfo.Name}\", "); if (propertyInfo.GetMethod != null && propertyInfo.GetMethod.IsPublic) { builder.Append($"get_{propertyInfo.Name}, "); } else { builder.Append("null, "); } if (propertyInfo.SetMethod != null && propertyInfo.SetMethod.IsPublic) { builder.Append($"set_{propertyInfo.Name}"); } else { builder.Append("null"); } builder.Append(");"); registerMethodStatement.Add(new CodeSnippetStatement(builder.ToString())); } foreach (var methodGroup in methodGroups) { registerMethodStatement.Add(new CodeSnippetStatement($"\t\t\tL.RegFunction(\"{methodGroup.Key}\", {methodGroup.Key});")); } registerMethodStatement.Add(new CodeSnippetStatement("\t\t\tL.EndClass();")); gener.AddMemberMethod(typeof(void), "Register", new Dictionary <string, Type>() { { "L", typeof(ILuaState) } }, MemberAttributes.Public | MemberAttributes.Static, registerMethodStatement.ToArray()); GenConstructor(gener, classType); foreach (var fieldInfo in fields) { if (fieldInfo.IsStatic) { GenRegStaticField(gener, classType, fieldInfo); } else { GenRegMemberField(gener, classType, fieldInfo); } } foreach (var propertyInfo in propertys) { if ((propertyInfo.GetMethod != null && propertyInfo.GetMethod.IsStatic) || (propertyInfo.SetMethod != null && propertyInfo.SetMethod.IsStatic)) { GenRegStaticProperty(gener, classType, propertyInfo); } else { GenRegMemberProperty(gener, classType, propertyInfo); } } foreach (var methodGroup in methodGroups) { if (!methodGroup.Any()) { continue; } if (methodGroup.First().IsStatic) { GenRegStaticFunction(gener, classType, methodGroup.ToArray()); } else { GenRegMemberFunction(gener, classType, methodGroup.ToArray()); } } gener.GenCSharp(outputPath); }
private void GenStaticLib(Type libType) { if (libType == null) { return; } var className = GetClassFileName(libType); CodeGener gener = new CodeGener("UniToLua", className); var fields = libType.GetFields(BindingFlags.Public | BindingFlags.Static); var propertys = libType.GetProperties(BindingFlags.Public | BindingFlags.Static); var methodGroups = libType.GetMethods(BindingFlags.Public | BindingFlags.Static).Where((method) => { if (propertys.Count(prop => prop.GetMethod == method || prop.SetMethod == method) != 0) { return(false); } if (IsObsolete(method)) { return(false); } return(true); }).GroupBy(mi => mi.Name).ToArray(); List <CodeStatement> registerMethodStatement = new List <CodeStatement>(); registerMethodStatement.Add(new CodeSnippetStatement($"\t\t\tL.BeginStaticLib(\"{libType.Name}\");")); foreach (var fieldInfo in fields) { registerMethodStatement.Add(new CodeSnippetStatement($"\t\t\tL.RegVar(\"{fieldInfo.Name}\", get_{fieldInfo.Name}, set_{fieldInfo.Name});")); } foreach (var propertyInfo in propertys) { StringBuilder builder = new StringBuilder($"\t\t\tL.RegVar(\"{propertyInfo.Name}\", "); if (propertyInfo.GetMethod != null && propertyInfo.GetMethod.IsPublic) { builder.Append($"get_{propertyInfo.Name}, "); } else { builder.Append("null, "); } if (propertyInfo.SetMethod != null && propertyInfo.SetMethod.IsPublic) { builder.Append($"set_{propertyInfo.Name}"); } else { builder.Append("null"); } builder.Append(");"); registerMethodStatement.Add(new CodeSnippetStatement(builder.ToString())); } foreach (var methodGroup in methodGroups) { registerMethodStatement.Add(new CodeSnippetStatement($"\t\t\tL.RegFunction(\"{methodGroup.Key}\", {methodGroup.Key});")); } registerMethodStatement.Add(new CodeSnippetStatement($"\t\t\tL.EndStaticLib();")); gener.AddMemberMethod(typeof(void), "Register", new Dictionary <string, Type>() { { "L", typeof(ILuaState) } }, MemberAttributes.Public | MemberAttributes.Static, registerMethodStatement.ToArray()); foreach (var fieldInfo in fields) { GenRegStaticField(gener, libType, fieldInfo); } foreach (var propertyInfo in propertys) { GenRegStaticProperty(gener, libType, propertyInfo); } foreach (var methodGroup in methodGroups) { GenRegStaticFunction(gener, libType, methodGroup.ToArray()); } gener.GenCSharp(outputPath); }
//生成数据代码 public void GenModelScript(BaseUI ui) { rootGo = ui.gameObject; uiType = ui.GetType(); string modelClassName = uiType.Name + "Model"; if (File.Exists(PathEx.Combine(Application.dataPath, UIModel.uiModelScriptPath, modelClassName + ".cs"))) { if (!EditorUtility.DisplayDialog("提示", "已存在" + modelClassName + ",是否要覆盖?", "继续", "取消")) { return; } } CodeGener gener = new CodeGener(UIModel.uiModelNameSpace, modelClassName); gener.AddBaseType(typeof(UIModel).Name) .AddImport("ResetCore.UGUI") .AddImport("ResetCore.Event"); List <string> hasAddedProperty = new List <string>(); CodeConstructor constructor = new CodeConstructor(); constructor.Attributes = MemberAttributes.Public; rootGo.transform.DoToSelfAndAllChildren((tran) => { GameObject go = tran.gameObject; if (!go.name.StartsWith(UIModel.genableSign)) { return; } string goName = go.name.Replace(UIModel.genableSign, string.Empty); string propertyName; string typeName; if (!goName.Contains(splitGoNameAndProperty[0])) { return; } string[] tempstrs = goName.Split(splitGoNameAndProperty, StringSplitOptions.RemoveEmptyEntries); goName = tempstrs[0]; if (!tempstrs[1].Contains(splitComponentAndProperty[0])) { EditorUtility.WarnPrefab(go, "命名错误", go.name + "的格式不正确,标准格式为“g-View变量名@组件名->Model属性名:变量类型”", "好的"); return; } propertyName = tempstrs[1].Split(splitComponentAndProperty, StringSplitOptions.RemoveEmptyEntries)[1]; if (!propertyName.Contains(splitPropertyAndType.ToString())) { typeName = "EventProperty<string>"; } tempstrs = propertyName.Split(splitPropertyAndType, StringSplitOptions.RemoveEmptyEntries); propertyName = tempstrs[0]; typeName = "EventProperty<" + tempstrs[1] + ">"; if (!hasAddedProperty.Contains(propertyName)) { gener.AddMemberProperty(typeName, propertyName); hasAddedProperty.Add(propertyName); constructor.Statements.AddRange(new CodeStatement[] { new CodeCommentStatement("From " + go.name), new CodeSnippetStatement(propertyName + " = new " + typeName + "();") }); } }); gener.newClass.Members.Add(constructor); gener.GenCSharp(PathEx.Combine(Application.dataPath, UIModel.uiModelScriptPath)); }
//生成自动绑定代码 public void GenBindScript(BaseUI ui) { rootGo = ui.gameObject; uiType = ui.GetType(); string binderClassName = uiType.Name + "Binder"; if (File.Exists(PathEx.Combine(Application.dataPath, UIBinder.uiBinderScriptPath, binderClassName + ".cs"))) { if (!EditorUtility.DisplayDialog("提示", "已存在" + binderClassName + ",是否要覆盖?", "继续", "取消")) { return; } } CodeGener gener = new CodeGener(UIBinder.uiBinderNameSpace, binderClassName); gener.AddBaseType(typeof(UIBinder).Name) .AddImport("ResetCore.UGUI") .AddImport("ResetCore.Event") .AddImport(UIView.uiViewNameSpace) .AddImport(UIModel.uiModelNameSpace); CodeMemberMethod initMethod = new CodeMemberMethod(); initMethod.AddComment("Used to bind view and model", true); initMethod.Name = "Bind"; string viewClassName = uiType.Name + "View"; string modelClassName = uiType.Name + "Model"; initMethod.Parameters.AddRange(new CodeParameterDeclarationExpression[] { new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(UIView).Name), "view"), new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(UIModel).Name), "model"), }); initMethod.Attributes = MemberAttributes.Public | MemberAttributes.Override; List <string> hasAddedProperty = new List <string>(); rootGo.transform.DoToSelfAndAllChildren((tran) => { GameObject go = tran.gameObject; if (!go.name.StartsWith(UIBinder.genableSign)) { return; } string goName = go.name.Replace(UIBinder.genableSign, string.Empty); string comName; string propertyName; string typeName; if (!goName.Contains(splitGoNameAndProperty[0])) { return; } string[] tempstrs = goName.Split(splitGoNameAndProperty, StringSplitOptions.RemoveEmptyEntries); goName = tempstrs[0]; if (!tempstrs[1].Contains(splitComponentAndProperty[0])) { EditorUtility.WarnPrefab(go, "命名错误", go.name + "的格式不正确,标准格式为“g-View变量名@组件名->Model属性名:变量类型”", "好的"); return; } tempstrs = tempstrs[1].Split(splitComponentAndProperty, StringSplitOptions.RemoveEmptyEntries); comName = tempstrs[0]; propertyName = tempstrs[1]; if (!propertyName.Contains(splitPropertyAndType.ToString())) { typeName = "EventProperty<string>"; } tempstrs = propertyName.Split(splitPropertyAndType, StringSplitOptions.RemoveEmptyEntries); propertyName = tempstrs[0]; typeName = "EventProperty<" + tempstrs[1] + ">"; initMethod.Statements.AddRange(new CodeStatement[] { new CodeCommentStatement("From " + go.name), new CodeSnippetStatement("((" + viewClassName + ")view)." + comName + goName + ".Bind(((" + modelClassName + ")model)." + propertyName + ");"), }); }); gener.newClass.Members.Add(initMethod); gener.GenCSharp(PathEx.Combine(Application.dataPath, UIBinder.uiBinderScriptPath)); }