static ToLuaTree <string> InitTree() { ToLuaTree <string> tree = new ToLuaTree <string>(); ToLuaNode <string> root = tree.GetRoot(); BindType[] list = GenBindTypes(CustomSettings.customTypeList); for (int i = 0; i < list.Length; i++) { string space = list[i].nameSpace; AddSpaceNameToTree(tree, root, space); } DelegateType[] dts = CustomSettings.customDelegateList; string str = null; for (int i = 0; i < dts.Length; i++) { string space = ToLuaExport.GetNameSpace(dts[i].type, out str); AddSpaceNameToTree(tree, root, space); } return(tree); }
static void GenLuaDelegates() { // 如果 beAutoGen 为假且脚本正在编译中就弹窗警告 if (!beAutoGen && EditorApplication.isCompiling) { EditorUtility.DisplayDialog("警告", "请等待编辑器完成编译再执行此功能", "确定"); return; } // 重置 ToLuaExport ToLuaExport.Clear(); // 新建一个委托类型信息类 list,并将 CustomSettings.customDelegateList 中所有元素添加进来 List <DelegateType> list = new List <DelegateType>(); list.AddRange(CustomSettings.customDelegateList); // 以 HashSet<Type> 形式获取 CustomSettings.customTypeList 中所有委托类型元素(字段、属性、方法参数)的类型 HashSet <Type> set = GetCustomTypeDelegates(); // 如果委托 list 中找不到当前类型的委托类型信息类,就新建一个并添加到 HashSet 中 foreach (Type t in set) { if (null == list.Find((p) => { return(p.type == t); })) { list.Add(new DelegateType(t)); } } // 生成 "DelegateFactory.cs" 脚本 ToLuaExport.GenDelegates(list.ToArray()); // 释放资源 set.Clear(); ToLuaExport.Clear(); // 刷新 AssetDatabase、打印消息 AssetDatabase.Refresh(); Debug.Log("Create lua delegate over"); }
public BindType(Type t) { type = t; nameSpace = ToLuaExport.GetNameSpace(t, out libName); name = ToLuaExport.CombineTypeStr(nameSpace, libName); libName = ToLuaExport.ConvertToLibSign(libName); if (name == "object") { wrapName = "System_Object"; name = "System.Object"; } else if (name == "string") { wrapName = "System_String"; name = "System.String"; } else { wrapName = name.Replace('.', '_'); wrapName = ToLuaExport.ConvertToLibSign(wrapName); } if (type.BaseType != null && type.BaseType != typeof(ValueType)) { baseType = type.BaseType; } int index = CustomSettings.staticClassTypes.IndexOf(type); if (index >= 0 || (type.GetConstructor(Type.EmptyTypes) == null && type.IsAbstract && type.IsSealed)) { IsStatic = true; baseType = baseType == typeof(object) ? null : baseType; } }
private void ExportType(BindType bindType) { var type = bindType.type; if (!NeedExportType(type)) { return; } ToLuaExport.Clear(); ToLuaExport.className = bindType.name; ToLuaExport.type = bindType.type; ToLuaExport.isStaticClass = bindType.IsStatic; ToLuaExport.baseType = bindType.baseType; ToLuaExport.wrapClassName = bindType.wrapName; ToLuaExport.libClassName = bindType.libName; ToLuaExport.extendList = bindType.extendList; ExportType(type); ToLuaExport.Clear(); AddType(type.BaseType); }
public BindType(Type t) { type = t; nameSpace = ToLuaExport.GetNameSpace(t, out libName); className = ToLuaExport.CombineTypeStr(nameSpace, libName); libName = ToLuaExport.ConvertToLibSign(libName); if (typeof(System.Delegate).IsAssignableFrom(t) || typeof(System.MulticastDelegate).IsAssignableFrom(t)) { isDelegate = true; typeClassify = "delegate"; } else { if (className == "object") { wrapName = "System_Object"; className = "System.Object"; } else if (className == "string") { wrapName = "System_String"; className = "System.String"; } else { wrapName = className.Replace('.', '_'); wrapName = ToLuaExport.ConvertToLibSign(wrapName); } wrapName += "Wrap"; if (t.BaseType != null && t.BaseType != typeof(ValueType)) { baseClass = t.BaseType.AssemblyQualifiedName; } if ((t.GetConstructor(Type.EmptyTypes) == null && t.IsAbstract && t.IsSealed)) { isStatic = true; baseClass = baseClass == typeof(object).AssemblyQualifiedName ? null : baseClass; } if (t.IsAbstract) { typeClassify = "abstract"; } else if (t.IsInterface) { typeClassify = "interface"; } else if (t.IsEnum) { typeClassify = "enum"; } else if (t.IsClass && isStatic) { typeClassify = "static class"; } else { typeClassify = "class"; } } }
public void GenLuaBinder() { StringBuilder sb = new StringBuilder(); List <DelegateType> dtList = new List <DelegateType>(); List <BindType> allTypes = GetAllWrappedCustomType(); List <DelegateType> delegateList = GetAllBuildedDelegate(); ToLuaTree <string> tree = InitTree(allTypes, delegateList); List <BindType> preloadList = GetAllPreloadType(); List <BindType> backupList = new List <BindType>(); backupList.AddRange(allTypes); sb.AppendLine("//this source code was auto-generated by tolua#, do not modify it"); sb.AppendLine("using System;"); sb.AppendLine("using UnityEngine;"); sb.AppendLine("using LaoHan.Infrastruture.ulua;"); sb.AppendLine(); sb.AppendLine("public static class LuaBinder"); sb.AppendLine("{"); sb.AppendLine("\tpublic static void Bind(LuaState L)"); sb.AppendLine("\t{"); sb.AppendLine("\t\tfloat t = Time.realtimeSinceStartup;"); sb.AppendLine("\t\tL.BeginModule(null);"); for (int i = 0; i < allTypes.Count; i++) { BindType dt = preloadList.Find((p) => { return(allTypes[i].type == p.type); }); if (dt == null && allTypes[i].nameSpace == null) { string str = "\t\t" + allTypes[i].wrapName + ".Register(L);\r\n"; sb.Append(str); allTypes.RemoveAt(i--); } } Action <ToLuaNode <string> > begin = (node) => { if (node.value == null) { return; } sb.AppendFormat("\t\tL.BeginModule(\"{0}\");\r\n", node.value); string space = GetSpaceNameFromTree(node); for (int i = 0; i < allTypes.Count; i++) { BindType dt = preloadList.Find((p) => { return(allTypes[i].type == p.type); }); if (dt == null && allTypes[i].nameSpace == space) { string str = "\t\t" + allTypes[i].wrapName + ".Register(L);\r\n"; sb.Append(str); allTypes.RemoveAt(i--); } } string funcName = null; for (int i = 0; i < delegateList.Count; i++) { DelegateType dt = delegateList[i]; Type type = dt.type; string typeSpace = ToLuaExport.GetNameSpace(type, out funcName); if (typeSpace == space) { funcName = ToLuaExport.ConvertToLibSign(funcName); string abr = dt.abr; abr = abr == null ? funcName : abr; sb.AppendFormat("\t\tL.RegFunction(\"{0}\", {1});\r\n", abr, dt.name); dtList.Add(dt); } } }; Action <ToLuaNode <string> > end = (node) => { if (node.value != null) { sb.AppendLine("\t\tL.EndModule();"); } }; tree.DepthFirstTraversal(begin, end, tree.GetRoot()); sb.AppendLine("\t\tL.EndModule();"); if (preloadList.Count > 0) { sb.AppendLine("\t\tL.BeginPreLoad();"); for (int i = 0; i < preloadList.Count; i++) { BindType t1 = preloadList[i]; BindType bt = backupList.Find((p) => { return(p.type == t1.type); }); sb.AppendFormat("\t\tL.AddPreLoad(\"{0}\", LuaOpen_{1}, typeof({0}));\r\n", bt.className, bt.wrapName); } sb.AppendLine("\t\tL.EndPreLoad();"); } //sb.AppendLine("\t\tDebugger.Log(\"Register lua type cost time: {0}\", Time.realtimeSinceStartup - t);"); sb.AppendLine("\t}"); for (int i = 0; i < dtList.Count; i++) { ToLuaExport.GenEventFunction(dtList[i].type, sb); } if (preloadList.Count > 0) { for (int i = 0; i < preloadList.Count; i++) { BindType t = preloadList[i]; BindType bt = backupList.Find((p) => { return(p.type == t.type); }); GenPreLoadFunction(bt, sb); } } sb.AppendLine("}\r\n"); allTypes.Clear(); using (StreamWriter textWriter = new StreamWriter(luaBinderFilePath, false, Encoding.UTF8)) { textWriter.Write(sb.ToString()); textWriter.Flush(); textWriter.Close(); } lhDebug.Log("Generate LuaBinder over !"); }
public void GenDelegate() { ToLuaExport.Clear(); ToLuaExport.GenDelegates(GetAllBuildedDelegate().ToArray(), delegateFactoryFilePath); ToLuaExport.Clear(); }
private static void WriteDelegateTypeDefine() { List <Type> exportDelegateTypeList = new List <Type>(); for (int i = 0; i < CustomSettings.customDelegateList.Length; i++) { exportDelegateTypeList.Add(CustomSettings.customDelegateList[i].type); } //查找所有导出类型中,是否有用到了委托的 Action <Type> recordDelegateTypeToList = type => { if (typeof(Delegate).IsAssignableFrom(type)) { if (ToLuaExport.IsMemberFilter(type)) { return; } if (!exportDelegateTypeList.Contains(type)) { exportDelegateTypeList.Add(type); } } }; for (int i = 0; i < exportTypeList.Count; i++) { Type exportType = exportTypeList[i]; #if ToLuaVersion //tolua基础类型的委托事件好像都没有被导出来 if (ToLuaFacility.toluaBaseTypes.Contains(exportType)) { continue; } #endif MethodInfo[] methodInfos = exportType.GetMethods(BindingFlags.Public | BindingFlags.Static); FieldInfo[] fieldInfos = exportType.GetFields(BindingFlags.Public | BindingFlags.Static); PropertyInfo[] propertyInfos = exportType.GetProperties(BindingFlags.Public | BindingFlags.Static); for (int j = 0; j < methodInfos.Length; j++) { MethodInfo methodInfo = methodInfos[j]; ParameterInfo[] parameterInfos = methodInfo.GetParameters(); for (int k = 0; k < parameterInfos.Length; k++) { ParameterInfo parameterInfo = parameterInfos[k]; if (parameterInfo.IsOut || parameterInfo.ParameterType.IsByRef) { recordDelegateTypeToList(parameterInfo.ParameterType.GetElementType()); } else { recordDelegateTypeToList(parameterInfo.ParameterType); } } ParameterInfo returnInfo = methodInfo.ReturnParameter; recordDelegateTypeToList(returnInfo.ParameterType); } for (int j = 0; j < fieldInfos.Length; j++) { FieldInfo fieldInfo = fieldInfos[j]; recordDelegateTypeToList(fieldInfo.FieldType); } for (int j = 0; j < propertyInfos.Length; j++) { PropertyInfo propertyInfo = propertyInfos[j]; recordDelegateTypeToList(propertyInfo.PropertyType); } } // Debug.Log("以下Delegate类型需要导出:"); // for (int i = 0; i < exportDelegateTypeList.Count; i++) // { // Debug.Log(exportDelegateTypeList[i].FullName); // } for (int i = 0; i < exportDelegateTypeList.Count; i++) { Type delegateType = exportDelegateTypeList[i]; WriteDelegateTypeComment(delegateType); if (delegateType.IsGenericType) { // Debug.Log("泛型委托: " + delegateType.FullName); if (string.IsNullOrEmpty(delegateType.FullName)) { continue; } tempSb.Clear(); tempSb.Append(delegateType.GetGenericTypeFullName().ReplaceDotOrPlusWithUnderscore()); Type[] genericTypes = delegateType.GetGenericArguments(); for (int j = 0; j < genericTypes.Length; j++) { // Debug.Log("包含泛型参数类型: " + genericTypes[j].FullName); tempSb.AppendFormat("_{0}", genericTypes[j].ToCSharpTypeFullName().ReplaceDotOrPlusWithUnderscore()); } tempSb.AppendFormat(" = {0}", delegateType.GetGenericTypeFullName()); for (int j = 0; j < genericTypes.Length; j++) { tempSb.AppendFormat("_{0}", genericTypes[j].ToCSharpTypeFullName().ReplaceDotOrPlusWithUnderscore()); } sb.AppendLine(tempSb.ToString()); } else { sb.AppendLine(string.Format("{0} = {1}", delegateType.FullName.ReplaceDotOrPlusWithUnderscore(), delegateType.FullName.ReplacePlusWithDot())); } } }
public static void GenerateSublimeCompletion() { if (!beAutoGen && EditorApplication.isCompiling) { EditorUtility.DisplayDialog("警告", "请等待编辑器完成编译再执行此功能", "确定"); return; } if (!File.Exists(CustomSettings.saveDir)) { Directory.CreateDirectory(CustomSettings.saveDir); } ToLuaExport.autocomp.Clear(); allTypes.Clear(); BindType[] typeList = CustomSettings.customTypeList; BindType[] list = GenBindTypes(typeList); ToLuaExport.allTypes.AddRange(baseType); for (int i = 0; i < list.Length; i++) { ToLuaExport.allTypes.Add(list[i].type); } for (int i = 0; i < list.Length; i++) { ToLuaExport.Clear(); ToLuaExport.className = list[i].name; ToLuaExport.type = list[i].type; ToLuaExport.isStaticClass = list[i].IsStatic; ToLuaExport.baseType = list[i].baseType; ToLuaExport.wrapClassName = list[i].wrapName; ToLuaExport.libClassName = list[i].libName; ToLuaExport.extendList = list[i].extendList; ToLuaExport.GenerateComp(CustomSettings.saveDir); } string file = "./../../SublimeTolua/quickxlib/tolua.sublime-completions"; using (StreamWriter textWriter = new StreamWriter(file, false, Encoding.UTF8)) { textWriter.Write("{\n\"scope\": \"source.lua\",\n\"completions\":\n["); textWriter.Write(ToLuaExport.autocomp.ToString()); textWriter.Write("]\n}\n"); textWriter.Flush(); textWriter.Close(); } Debug.Log("Generate sublime completion files over"); ToLuaExport.allTypes.Clear(); allTypes.Clear(); AssetDatabase.Refresh(); }
private bool IsObsolete(MemberInfo memberInfo) { return(ToLuaExport.IsObsolete(memberInfo)); }
static HashSet <Type> GetCustomTypeDelegates() { BindType[] list = CustomSettings.customTypeList; HashSet <Type> set = new HashSet <Type>(); BindingFlags binding = BindingFlags.Public | BindingFlags.Static | BindingFlags.IgnoreCase | BindingFlags.Instance; for (int i = 0; i < list.Length; i++) { Type type = list[i].type; FieldInfo[] fields = type.GetFields(BindingFlags.GetField | BindingFlags.SetField | binding); PropertyInfo[] props = type.GetProperties(BindingFlags.GetProperty | BindingFlags.SetProperty | binding); MethodInfo[] methods = null; if (type.IsInterface) { methods = type.GetMethods(); } else { methods = type.GetMethods(BindingFlags.Instance | binding); } for (int j = 0; j < fields.Length; j++) { Type t = fields[j].FieldType; if (ToLuaExport.IsDelegateType(t)) { set.Add(t); } } for (int j = 0; j < props.Length; j++) { Type t = props[j].PropertyType; if (ToLuaExport.IsDelegateType(t)) { set.Add(t); } } for (int j = 0; j < methods.Length; j++) { MethodInfo m = methods[j]; if (m.IsGenericMethod) { continue; } ParameterInfo[] pifs = m.GetParameters(); for (int k = 0; k < pifs.Length; k++) { Type t = pifs[k].ParameterType; if (t.IsByRef) { t = t.GetElementType(); } if (ToLuaExport.IsDelegateType(t)) { set.Add(t); } } } } return(set); }
void GenerateClassSkip(Assembly assembly) { // 所有public的类 var types = assembly.GetExportedTypes().ToList(); types.RemoveAll(v => _skipClass.Contains(v)); // 所有需要生成的类 var gens = _methods.Values.GroupBy(v => v.method.ReflectedType.IsGenericType && !v.method.ReflectedType.IsGenericTypeDefinition ? v.method.ReflectedType.GetGenericTypeDefinition() : v.method.ReflectedType).Select(v => v.Key).Concat(_includeClass).GroupBy(v => v).ToDictionary(v => v.Key); var impls = CustomSettings.luaImplementList.ToDictionary(v => v); // 找到不需要生成的类 types.RemoveAll(v => impls.ContainsKey(v) || gens.ContainsKey(v) || !(v.IsClass || IsStruct(v)) || ToLuaExport.IsDelegateType(v)); foreach (var namespacePair in types.GroupBy(t => t.Namespace)) { var ns = namespacePair.Key; sb.AppendFormat("\t\t<namespace name=\"{0}\">\n", ns); foreach (var classTypePair in namespacePair) { var classType = classTypePair; GenerateBanedClass(classType); } sb.AppendFormat("\t\t</namespace>\n"); } }
static void GenLuaBinder() { if (!beAutoGen && EditorApplication.isCompiling) { EditorUtility.DisplayDialog("警告", "请等待编辑器完成编译再执行此功能", "确定"); return; } allTypes.Clear(); ToLuaTree <string> tree = InitTree(); StringBuilder sb = new StringBuilder(); List <DelegateType> dtList = new List <DelegateType>(); List <DelegateType> list = new List <DelegateType>(); list.AddRange(CustomSettings.customDelegateList); // 以 HashSet<Type> 形式获取 CustomSettings.customTypeList 中所有委托类型元素(字段、属性、方法参数)的类型 HashSet <Type> set = GetCustomTypeDelegates(); // 以 List<BindType> 形式获取自身 allTypes 所有元素 List <BindType> backupList = new List <BindType>(); backupList.AddRange(allTypes); ToLuaNode <string> root = tree.GetRoot(); string libname = null; // 补充 List<DelegateType> list 中没有的 DelegateType foreach (Type t in set) { if (null == list.Find((p) => { return(p.type == t); })) { DelegateType dt = new DelegateType(t); AddSpaceNameToTree(tree, root, ToLuaExport.GetNameSpace(t, out libname)); list.Add(dt); } } // 拼接文本 sb.AppendLineEx("//this source code was auto-generated by tolua#, do not modify it"); sb.AppendLineEx("using System;"); sb.AppendLineEx("using UnityEngine;"); sb.AppendLineEx("using LuaInterface;"); sb.AppendLineEx(); sb.AppendLineEx("public static class LuaBinder"); sb.AppendLineEx("{"); sb.AppendLineEx("\tpublic static void Bind(LuaState L)"); sb.AppendLineEx("\t{"); sb.AppendLineEx("\t\tfloat t = Time.realtimeSinceStartup;"); sb.AppendLineEx("\t\tL.BeginModule(null);"); // 生成注册信息字符串并对 list、dtList 两个 list 做相应更新 GenRegisterInfo(null, sb, list, dtList); // 为 DepthFirstTraversal 方法新建一个将 value 不为空的 ToLuaNode<string> 的 value 组织字符串,并添加到参数 sb 中(于开头处添加字符);再获取参数 node 的完全限定名、根据 t 的 Namespace 更新参数 tree 和 root 的父或子节点信息 Action <ToLuaNode <string> > begin = (node) => { if (node.value == null) { return; } sb.AppendFormat("\t\tL.BeginModule(\"{0}\");\r\n", node.value); string space = GetSpaceNameFromTree(node); GenRegisterInfo(space, sb, list, dtList); }; // 为 DepthFirstTraversal 方法新建一个将 value 不为空的 ToLuaNode<string> 的 value 组织字符串并添加到参数 sb 中(于结尾处添加字符) Action <ToLuaNode <string> > end = (node) => { if (node.value != null) { sb.AppendLineEx("\t\tL.EndModule();"); } }; // 从最底层的子节点开始对参数 node 及其子节点进行遍历,同时使用 begin 和 end 委托对字符串进行修改 tree.DepthFirstTraversal(begin, end, tree.GetRoot()); // 在结尾处添加字符串 sb.AppendLineEx("\t\tL.EndModule();"); // 处理动态类型 list 字符串 if (CustomSettings.dynamicList.Count > 0) { sb.AppendLineEx("\t\tL.BeginPreLoad();"); for (int i = 0; i < CustomSettings.dynamicList.Count; i++) { Type t1 = CustomSettings.dynamicList[i]; BindType bt = backupList.Find((p) => { return(p.type == t1); }); sb.AppendFormat("\t\tL.AddPreLoad(\"{0}\", LuaOpen_{1}, typeof({0}));\r\n", bt.name, bt.wrapName); } sb.AppendLineEx("\t\tL.EndPreLoad();"); } sb.AppendLineEx("\t\tDebugger.Log(\"Register lua type cost time: {0}\", Time.realtimeSinceStartup - t);"); sb.AppendLineEx("\t}"); // 遍历 dtList,为每一个元素生成指定类型的 EventFunction 字符串并添加到参数 StringBuilder sb 中 for (int i = 0; i < dtList.Count; i++) { ToLuaExport.GenEventFunction(dtList[i].type, sb); } // 遍历动态类型 list 并为每一个 backupList 中类型与当前元素相等的 BindType 生成 PreLoadFunction 字符串并添加到参数 StringBuilder sb if (CustomSettings.dynamicList.Count > 0) { for (int i = 0; i < CustomSettings.dynamicList.Count; i++) { Type t = CustomSettings.dynamicList[i]; BindType bt = backupList.Find((p) => { return(p.type == t); }); GenPreLoadFunction(bt, sb); } } // 添加结尾字符串,并清空 allTypes,合成文件储存路径 sb.AppendLineEx("}\r\n"); allTypes.Clear(); string file = CustomSettings.saveDir + "LuaBinder.cs"; // 生成文件、刷新 AssetDatabase 并打印提示 using (StreamWriter textWriter = new StreamWriter(file, false, Encoding.UTF8)) { textWriter.Write(sb.ToString()); textWriter.Flush(); textWriter.Close(); } AssetDatabase.Refresh(); Debugger.Log("Generate LuaBinder over !"); }
/// <summary> /// 以 HashSet<Type> 形式获取 CustomSettings.customTypeList 中所有委托类型元素(字段、属性、方法参数)的类型 /// </summary> static HashSet <Type> GetCustomTypeDelegates() { // 以数组形式获取 CustomSettings.customTypeList 的所有元素 BindType[] list = CustomSettings.customTypeList; HashSet <Type> set = new HashSet <Type>(); // 指定 BindingFlags 为公共、静态、忽略大小写、包括实例 BindingFlags binding = BindingFlags.Public | BindingFlags.Static | BindingFlags.IgnoreCase | BindingFlags.Instance; for (int i = 0; i < list.Length; i++) { Type type = list[i].type; // 根据 BindingFlags 指定规则获取字段 FieldInfo[] fields = type.GetFields(BindingFlags.GetField | BindingFlags.SetField | binding); // 根据 BindingFlags 指定规则获取属性信息 PropertyInfo[] props = type.GetProperties(BindingFlags.GetProperty | BindingFlags.SetProperty | binding); MethodInfo[] methods = null; // 为 MethodInfo[] methods 获取 MethodInfo if (type.IsInterface) { methods = type.GetMethods(); } else { methods = type.GetMethods(BindingFlags.Instance | binding); } // 为 HashSet<Type> set 添加委托类型字段的类型 for (int j = 0; j < fields.Length; j++) { Type t = fields[j].FieldType; if (ToLuaExport.IsDelegateType(t)) { set.Add(t); } } // 为 HashSet<Type> set 添加委托类型属性的类型 for (int j = 0; j < props.Length; j++) { Type t = props[j].PropertyType; if (ToLuaExport.IsDelegateType(t)) { set.Add(t); } } for (int j = 0; j < methods.Length; j++) { MethodInfo m = methods[j]; // 如果是泛型方法直接跳过 if (m.IsGenericMethod) { continue; } // 获取当前元素的参数信息 ParameterInfo[] pifs = m.GetParameters(); // 为 HashSet<Type> set 添加委托类型参数的类型 for (int k = 0; k < pifs.Length; k++) { Type t = pifs[k].ParameterType; if (t.IsByRef) { t = t.GetElementType(); } if (ToLuaExport.IsDelegateType(t)) { set.Add(t); } } } } return(set); }
public DelegateType(Type t) { type = t; strType = ToLuaExport.GetTypeStr(t); name = ToLuaExport.ConvertToLibSign(strType); }
static void GenLuaBinder() { if (!beAutoGen && EditorApplication.isCompiling) { EditorUtility.DisplayDialog("警告", "请等待编辑器完成编译在执行此功能", "确定"); return; } allTypes.Clear(); ToLuaTree <string> tree = InitTree(); StringBuilder sb = new StringBuilder(); List <DelegateType> dtList = new List <DelegateType>(); sb.AppendLineEx("using System;"); sb.AppendLineEx("using UnityEngine;"); sb.AppendLineEx("using LuaInterface;"); sb.AppendLineEx(); sb.AppendLineEx("public static class LuaBinder"); sb.AppendLineEx("{"); sb.AppendLineEx("\tpublic static void Bind(LuaState L)"); sb.AppendLineEx("\t{"); sb.AppendLineEx("\t\tfloat t = Time.realtimeSinceStartup;"); sb.AppendLineEx("\t\tL.BeginModule(null);"); //if (File.Exists(CustomSettings.saveDir + "DelegateFactoryWrap.cs")) //{ // sb.AppendLineEx("\t\tDelegateFactoryWrap.Register(L);"); //} for (int i = 0; i < allTypes.Count; i++) { if (allTypes[i].nameSpace == null) { string str = "\t\t" + allTypes[i].wrapName + "Wrap.Register(L);\r\n"; sb.Append(str); allTypes.RemoveAt(i--); } } Action <ToLuaNode <string> > begin = (node) => { if (node.value == null) { return; } sb.AppendFormat("\t\tL.BeginModule(\"{0}\");\r\n", node.value); string space = GetSpaceNameFromTree(node); for (int i = 0; i < allTypes.Count; i++) { if (allTypes[i].nameSpace == space) { string str = "\t\t" + allTypes[i].wrapName + "Wrap.Register(L);\r\n"; sb.Append(str); allTypes.RemoveAt(i--); } } string funcName = null; for (int i = 0; i < CustomSettings.customDelegateList.Length; i++) { DelegateType dt = CustomSettings.customDelegateList[i]; Type type = CustomSettings.customDelegateList[i].type; if (type.Namespace == space) { ToLuaExport.GetNameSpace(type, out funcName); funcName = ToLuaExport.ConvertToLibSign(funcName); string abr = dt.abr; abr = abr == null ? funcName : abr; sb.AppendFormat("\t\tL.RegFunction(\"{0}\", {1});\r\n", abr, dt.name); dtList.Add(dt); } } }; Action <ToLuaNode <string> > end = (node) => { if (node.value != null) { sb.AppendLineEx("\t\tL.EndModule();"); } }; tree.DepthFirstTraversal(begin, end, tree.GetRoot()); sb.AppendLineEx("\t\tL.EndModule();"); sb.AppendLineEx("\t\tDebugger.Log(\"Register lua type cost time: {0}\", Time.realtimeSinceStartup - t);"); sb.AppendLineEx("\t}"); for (int i = 0; i < dtList.Count; i++) { ToLuaExport.GenEventFunction(dtList[i].type, sb); } sb.AppendLineEx("}\r\n"); allTypes.Clear(); string file = CustomSettings.saveDir + "LuaBinder.cs"; using (StreamWriter textWriter = new StreamWriter(file, false, Encoding.UTF8)) { textWriter.Write(sb.ToString()); textWriter.Flush(); textWriter.Close(); } AssetDatabase.Refresh(); }
public static void U3dBinding() { List <string> dropList = new List <string> { //特殊修改 "UnityEngine.Object", //一般情况不需要的类, 编辑器相关的 "HideInInspector", "ExecuteInEditMode", "AddComponentMenu", "ContextMenu", "RequireComponent", "DisallowMultipleComponent", "SerializeField", "AssemblyIsEditorAssembly", "Attribute", //一些列文件,都是编辑器相关的 "FFTWindow", "Types", "UnitySurrogateSelector", "TypeInferenceRules", "ThreadPriority", "Debug", //自定义debugger取代 "GenericStack", //异常,lua无法catch "PlayerPrefsException", "UnassignedReferenceException", "UnityException", "MissingComponentException", "MissingReferenceException", //RPC网络 "RPC", "Network", "MasterServer", "BitStream", "HostData", "ConnectionTesterStatus", //unity 自带编辑器GUI "GUI", "EventType", "EventModifiers", //"Event", "FontStyle", "TextAlignment", "TextEditor", "TextEditorDblClickSnapping", "TextGenerator", "TextClipping", "TextGenerationSettings", "TextAnchor", "TextAsset", "TextWrapMode", "Gizmos", "ImagePosition", "FocusType", //地形相关 "Terrain", "Tree", "SplatPrototype", "DetailPrototype", "DetailRenderMode", //其他 "MeshSubsetCombineUtility", "AOT", "Random", "Mathf", "Social", "Enumerator", "SendMouseEvents", "Cursor", "Flash", "ActionScript", //非通用的类 "ADBannerView", "ADInterstitialAd", "Android", "jvalue", "iPhone", "iOS", "CalendarIdentifier", "CalendarUnit", "CalendarUnit", "FullScreenMovieControlMode", "FullScreenMovieScalingMode", "Handheld", "LocalNotification", "Motion", //空类 "NotificationServices", "RemoteNotificationType", "RemoteNotification", "SamsungTV", "TextureCompressionQuality", "TouchScreenKeyboardType", "TouchScreenKeyboard", "MovieTexture", //我不需要的 //2d 类 "AccelerationEventWrap", //加速 "AnimatorUtility", "AudioChorusFilter", "AudioDistortionFilter", "AudioEchoFilter", "AudioHighPassFilter", "AudioLowPassFilter", "AudioReverbFilter", "AudioReverbPreset", "AudioReverbZone", "AudioRolloffMode", "AudioSettings", "AudioSpeakerMode", "AudioType", "AudioVelocityUpdateMode", "Ping", "Profiler", "StaticBatchingUtility", "Font", "Gyroscope", //不需要重力感应 "ISerializationCallbackReceiver", //u3d 继承的序列化接口,lua不需要 "ImageEffectOpaque", //后处理 "ImageEffectTransformsToLDR", "PrimitiveType", // 暂时不需要 GameObject.CreatePrimitive "Skybox", //不会u3d自带的Skybox "SparseTexture", // mega texture 不需要 "Plane", "PlayerPrefs", //不用ugui "SpriteAlignment", "SpriteMeshType", "SpritePackingMode", "SpritePackingRotation", "SpriteRenderer", "Sprite", "UIVertex", "CanvasGroup", "CanvasRenderer", "ICanvasRaycastFilter", "Canvas", "RectTransform", "DrivenRectTransformTracker", "DrivenTransformProperties", "RectTransformAxis", "RectTransformEdge", "RectTransformUtility", "RectTransform", "UICharInfo", "UILineInfo", //不需要轮子碰撞体 "WheelCollider", "WheelFrictionCurve", "WheelHit", //手机不适用雾 "FogMode", "UnityEventBase", "UnityEventCallState", "UnityEvent", "LightProbeGroup", "LightProbes", "NPOTSupport", //只是SystemInfo 的一个枚举值 //没用到substance纹理 "ProceduralCacheSize", "ProceduralLoadingBehavior", "ProceduralMaterial", "ProceduralOutputType", "ProceduralProcessorUsage", "ProceduralPropertyDescription", "ProceduralPropertyType", "ProceduralTexture", //物理关节系统 "JointDriveMode", "JointDrive", "JointLimits", "JointMotor", "JointProjectionMode", "JointSpring", "SoftJointLimit", "SpringJoint", "HingeJoint", "FixedJoint", "ConfigurableJoint", "CharacterJoint", "Joint", "LODGroup", "LOD", "DataUtility", //给sprite使用的 "CrashReport", "CombineInstance", }; List <BindType> list = new List <BindType>(); Assembly assembly = Assembly.Load("UnityEngine"); Type[] types = assembly.GetExportedTypes(); for (int i = 0; i < types.Length; i++) { //不导出: 模版类,event委托, c#协同相关, obsolete 类 if (!types[i].IsGenericType && types[i].BaseType != typeof(System.MulticastDelegate) && !typeof(YieldInstruction).IsAssignableFrom(types[i]) && !ToLuaExport.IsObsolete(types[i])) { list.Add(_GT(types[i])); } else { Debug.Log("drop generic type " + types[i].ToString()); } } for (int i = 0; i < dropList.Count; i++) { list.RemoveAll((p) => { return(p.type.ToString().Contains(dropList[i])); }); } //for (int i = 0; i < list.Count; i++) //{ // if (!typeof(UnityEngine.Object).IsAssignableFrom(list[i].type) && !list[i].type.IsEnum && !typeof(UnityEngine.TrackedReference).IsAssignableFrom(list[i].type) // && !list[i].type.IsValueType && !list[i].type.IsSealed) // { // Debug.Log(list[i].type.Name); // } //} for (int i = 0; i < list.Count; i++) { try { ToLuaExport.Clear(); ToLuaExport.className = list[i].name; ToLuaExport.type = list[i].type; ToLuaExport.isStaticClass = list[i].IsStatic; ToLuaExport.baseClassName = list[i].baseName; ToLuaExport.wrapClassName = list[i].wrapName; ToLuaExport.libClassName = list[i].libName; ToLuaExport.Generate(null); } catch (Exception e) { Debug.LogWarning("Generate wrap file error: " + e.ToString()); } } GenLuaBinder(); Debug.Log("Generate lua binding files over, Generate " + list.Count + " files"); AssetDatabase.Refresh(); }
static void GenClassApi(ToLuaMenu.BindType bt) { Type type = bt.type; if (type.IsGenericType)//泛型类被tolua处理成全局库了,如果都加成api自动提示的时候反而不方便 { return; } //计算lua中的全局名和继承者 string name = bt.name; string inherits = null; if (bt.baseType != null && !bt.baseType.IsGenericType) { inherits = ToLuaExport.GetBaseTypeStr(bt.baseType); } //创建api类 var api = GetClassApi(name, inherits); string returns = null, valueType = null; //注册成员函数,参考的是ToLuaExport.GenRegisterFuncItems for (int i = 0; i < ToLuaExport.methods.Count; i++) { MethodInfo m = ToLuaExport.methods[i].Method as MethodInfo; int count = 1; string methodName = ToLuaExport.GetMethodName(m); if (ToLuaExport.nameCounter.TryGetValue(methodName, out count)) { ToLuaExport.nameCounter[methodName] = count + 1; continue; } ToLuaExport.nameCounter[methodName] = 1; if (m.IsGenericMethod || methodName == "set_Item" || methodName == "get_Item" || methodName.StartsWith("op_")) { continue; } //获取返回值信息 GetReturnTypeStr(m.ReturnType, ref returns, ref valueType); //获取参数信息 ParameterInfo[] paramInfos = m.GetParameters(); s_paramName.Clear(); s_paramName.Append('('); for (int j = 0; j < paramInfos.Length; ++j) { s_paramName.Append(paramInfos[j].Name); if (j != paramInfos.Length - 1) { s_paramName.Append(','); } } s_paramName.Append(')'); string param = s_paramName.ToString(); if (m.IsStatic) { api.AddFunction(methodName, param, returns, valueType); } else { api.AddMethod(methodName, param, returns, valueType); } } //注册成员变量和属性 for (int i = 0; i < ToLuaExport.fields.Length; i++) { GetReturnTypeStr(ToLuaExport.fields[i].FieldType, ref returns, ref valueType); api.AddValue(ToLuaExport.fields[i].Name, valueType); } for (int i = 0; i < ToLuaExport.props.Length; i++) { GetReturnTypeStr(ToLuaExport.props[i].PropertyType, ref returns, ref valueType); api.AddValue(ToLuaExport.props[i].Name, valueType); } //注册操作符,暂时不需要 //注册构造函数,暂时不需要 //注册索引器,暂时不需要 }
static void GenLuaBinder() { if (!beAutoGen && EditorApplication.isCompiling) { EditorUtility.DisplayDialog("警告", "请等待编辑器完成编译再执行此功能", "确定"); return; } allTypes.Clear(); ToLuaTree <string> tree = InitTree(); StringBuilder sb = new StringBuilder(); List <DelegateType> dtList = new List <DelegateType>(); List <DelegateType> list = new List <DelegateType>(); list.AddRange(CustomSettings.customDelegateList); HashSet <Type> set = GetCustomTypeDelegates(); List <BindType> backupList = new List <BindType>(); backupList.AddRange(allTypes); ToLuaNode <string> root = tree.GetRoot(); string libname = null; foreach (Type t in set) { if (null == list.Find((p) => { return(p.type == t); })) { DelegateType dt = new DelegateType(t); AddSpaceNameToTree(tree, root, ToLuaExport.GetNameSpace(t, out libname)); list.Add(dt); } } sb.AppendLineEx("//this source code was auto-generated by tolua#, do not modify it"); sb.AppendLineEx("using System;"); sb.AppendLineEx("using UnityEngine;"); sb.AppendLineEx("using LuaInterface;"); sb.AppendLineEx(); sb.AppendLineEx("public static class LuaBinder"); sb.AppendLineEx("{"); sb.AppendLineEx("\tpublic static void Bind(LuaState L)"); sb.AppendLineEx("\t{"); sb.AppendLineEx("\t\tfloat t = Time.realtimeSinceStartup;"); sb.AppendLineEx("\t\tL.BeginModule(null);"); GenRegisterInfo(null, sb, list, dtList); Action <ToLuaNode <string> > begin = (node) => { if (node.value == null) { return; } sb.AppendFormat("\t\tL.BeginModule(\"{0}\");\r\n", node.value); string space = GetSpaceNameFromTree(node); GenRegisterInfo(space, sb, list, dtList); }; Action <ToLuaNode <string> > end = (node) => { if (node.value != null) { sb.AppendLineEx("\t\tL.EndModule();"); } }; tree.DepthFirstTraversal(begin, end, tree.GetRoot()); sb.AppendLineEx("\t\tL.EndModule();"); if (CustomSettings.dynamicList.Count > 0) { sb.AppendLineEx("\t\tL.BeginPreLoad();"); for (int i = 0; i < CustomSettings.dynamicList.Count; i++) { Type t1 = CustomSettings.dynamicList[i]; BindType bt = backupList.Find((p) => { return(p.type == t1); }); if (bt != null) { sb.AppendFormat("\t\tL.AddPreLoad(\"{0}\", LuaOpen_{1}, typeof({0}));\r\n", bt.name, bt.wrapName); } } sb.AppendLineEx("\t\tL.EndPreLoad();"); } sb.AppendLineEx("\t\tDebugger.Log(\"Register lua type cost time: {0}\", Time.realtimeSinceStartup - t);"); sb.AppendLineEx("\t}"); for (int i = 0; i < dtList.Count; i++) { ToLuaExport.GenEventFunction(dtList[i].type, sb); } if (CustomSettings.dynamicList.Count > 0) { for (int i = 0; i < CustomSettings.dynamicList.Count; i++) { Type t = CustomSettings.dynamicList[i]; BindType bt = backupList.Find((p) => { return(p.type == t); }); if (bt != null) { GenPreLoadFunction(bt, sb); } } } sb.AppendLineEx("}\r\n"); allTypes.Clear(); string file = CustomSettings.saveDir + "LuaBinder.cs"; using (StreamWriter textWriter = new StreamWriter(file, false, Encoding.UTF8)) { textWriter.Write(sb.ToString()); textWriter.Flush(); textWriter.Close(); } AssetDatabase.Refresh(); Debugger.Log("Generate LuaBinder over !"); }
static void GetReturnTypeStr(Type t, ref string returns, ref string valueType) { returns = null; valueType = null; if (t == typeof(void)) { returns = "void"; return; } if (t.IsByRef) { t = t.GetElementType(); } //如果是基础类型,不提示 if (t.IsPrimitive) { returns = t.Name; return; } else if (t == typeof(string)) { returns = "System.String"; return; } else if (t == typeof(Vector3)) { returns = "Vector3"; return; } else if (t == typeof(Quaternion)) { returns = "Quaternion"; return; } else if (t == typeof(Vector2)) { returns = "Vector2"; return; } else if (t == typeof(Vector4)) { returns = "Vector4"; return; } else if (t == typeof(Color)) { returns = "Color"; return; } else if (t == typeof(Ray)) { returns = "Ray"; return; } else if (t == typeof(Bounds)) { returns = "Bounds"; return; } else if (t == typeof(LayerMask)) { returns = "LayerMask"; return; } else if (t.IsSubclassOf(typeof(UnityEngine.Events.UnityEvent))) { returns = valueType = "UnityEngine.Events.UnityEvent"; return; } //如果是集合类,那么转下 if (t.IsArray) { returns = valueType = "System.Array"; return; } if (t.GetInterface("System.Collections.IList") != null) { returns = valueType = "List"; return; } if (t.GetInterface("System.Collections.IDictionary") != null) { returns = valueType = "Dictionary"; return; } if (t.GetInterface("System.Collections.IEnumerable") != null) { returns = valueType = "System.Collections.IEnumerable"; return; } if (t.GetInterface("System.Collections.IEnumerator") != null) { returns = valueType = "System.Collections.IEnumerator"; return; } //如果不是集合类,但又是泛型,tolua是处理成全局库的,这里直接忽略 if (t.IsGenericType) { return; } if (!s_apiTypeIdx.ContainsKey(t)) { return; } //最后剩下的类型就只有c#导出到lua的类型了 returns = valueType = ToLuaExport.GetBaseTypeStr(t); }