protected override void OnLoadFinished() { base.OnLoadFinished(); luaState.DoString(script, "PassStruct.cs"); NewRect = luaState.GetFunction("Rect.New"); GetRect = luaState.GetFunction("Rect.Get"); StackTraits <Rect> .Init(PushRect, CheckRectValue, ToRectValue); //支持压入lua以及从lua栈读取 TypeTraits <Rect> .Init(CheckRectType); //支持重载函数TypeCheck.CheckTypes TypeTraits <Nullable <Rect> > .Init(CheckNullRectType); //支持重载函数TypeCheck.CheckTypes LuaValueTypeName.names[LuaValueType.Rect] = "Rect"; //CheckType失败提示的名字 TypeChecker.LuaValueTypeMap[LuaValueType.Rect] = typeof(Rect); //用于支持类型匹配检查操作 ToLua.ToVarMap[LuaValueType.Rect] = ToRectTable; //Rect作为object读取 ToLua.VarPushMap[typeof(Rect)] = (L, o) => { PushRect(L, (Rect)o); }; //Rect作为object压入 //测试例子 LuaFunction func = luaState.GetFunction("PrintRect"); func.BeginPCall(); func.PushValue(new Rect(10, 20, 120, 50)); func.PCall(); Rect rt = func.CheckValue <Rect>(); func.EndPCall(); Debugger.Log(rt); Debugger.Log(Vector3.one.ToString()); }
static void Run() { string serverroot = Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("Assets")); KillRunningServer(); string model = "SimpleHTTPServer"; ProcessStartInfo startInfo = new ProcessStartInfo("python", string.Format("-m {0} {1}", model, port)); startInfo.WorkingDirectory = serverroot; startInfo.UseShellExecute = false; startInfo.CreateNoWindow = true; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; Process launchProcess = Process.Start(startInfo); if (launchProcess == null || launchProcess.HasExited == true || launchProcess.Id == 0) { Debugger.LogError("Unable Start AssetServer process"); } else { instance.m_serverPID = launchProcess.Id; Debugger.Log("Local AssetServer Listen: {0}, Root Dir: {1}", port, serverroot); } }
static void AutoAddBaseType(BindType bt, bool beDropBaseType) { Type t = bt.baseType; if (t == null) { return; } if (t.IsInterface) { Debugger.LogWarning("{0} has a base type {1} is Interface, use SetBaseType to jump it", bt.name, t.FullName); bt.baseType = t.BaseType; } else if (dropType.IndexOf(t) >= 0) { Debugger.LogWarning("{0} has a base type {1} is a drop type", bt.name, t.FullName); bt.baseType = t.BaseType; } else if (!beDropBaseType || baseType.IndexOf(t) < 0) { int index = allTypes.FindIndex((iter) => { return(iter.type == t); }); if (index < 0) { #if JUMP_NODEFINED_ABSTRACT if (t.IsAbstract && !t.IsSealed) { Debugger.LogWarning("not defined bindtype for {0}, it is abstract class, jump it, child class is {1}", t.FullName, bt.name); bt.baseType = t.BaseType; } else { Debugger.LogWarning("not defined bindtype for {0}, autogen it, child class is {1}", t.FullName, bt.name); bt = new BindType(t); allTypes.Add(bt); } #else Debugger.LogWarning("not defined bindtype for {0}, autogen it, child class is {1}", t.FullName, bt.name); bt = new BindType(t); allTypes.Add(bt); #endif } else { return; } } else { return; } AutoAddBaseType(bt, beDropBaseType); }
/// <summary> /// 生成绑定素材 /// </summary> public static void BuildAssetResource(BuildTarget target) { if (Directory.Exists(Util.DataPath)) { Directory.Delete(Util.DataPath, true); } string streamPath = Application.streamingAssetsPath; if (Directory.Exists(streamPath)) { Directory.Delete(streamPath, true); if (!File.Exists(streamPath)) { Directory.CreateDirectory(streamPath); } } AssetDatabase.Refresh(); maps.Clear(); if (AppConst.LuaBundleMode) { HandleLuaBundle(); } else { HandleLuaFile(); } if (AppConst.ExampleMode) { HandleExampleBundle(); } string resPath = "Assets/" + AppConst.AssetDir; BuildAssetBundleOptions options = BuildAssetBundleOptions.DeterministicAssetBundle; BuildPipeline.BuildAssetBundles(resPath, maps.ToArray(), options, target); BuildFileIndex(); string streamDir = Application.dataPath + "/" + AppConst.LuaTempDir; if (Directory.Exists(streamDir)) { Directory.Delete(streamDir, true); } AssetDatabase.Refresh(); if (File.Exists("Assets/Art/Movie/LoginMain.mp4") && File.Exists("Assets/" + AppConst.AssetDir + "/LoginMain.mp4") == false) { File.Copy("Assets/Art/Movie/LoginMain.mp4", "Assets/" + AppConst.AssetDir + "/LoginMain.mp4"); Debugger.Log("Copy video to complete!!!"); } }
static string GetFileContentMD5(string file) { try { FileStream fs = new FileStream(file, FileMode.Open); System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] retVal = md5.ComputeHash(fs); fs.Close(); StringBuilder sb = StringBuilderCache.Acquire(); for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } return(StringBuilderCache.GetStringAndRelease(sb)); } catch (System.Exception ex) { Debugger.LogError("Md5file() fail, error:" + ex.Message); return(string.Empty); } }
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 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> /// (自动)添加参数 BindType bt 的基类类型到 List<BindType> allTypes /// </summary> static void AutoAddBaseType(BindType bt, bool beDropBaseType) { // 获取参数 bt 中 baseType 的值 Type t = bt.baseType; // 如果基类为空直接返回 if (t == null) { return; } // 如果是接口类型则打印警告 if (t.IsInterface) { Debugger.LogWarning("{0} has a base type {1} is Interface, use SetBaseType to jump it", bt.name, t.FullName); // 将参数 bt 的基类设为类型 t 的基类(object?) bt.baseType = t.BaseType; } // 如果存在于不导出 list 中,同样打印警告 else if (dropType.IndexOf(t) >= 0) { Debugger.LogWarning("{0} has a base type {1} is a drop type", bt.name, t.FullName); // 将参数 bt 的基类设为类型 t 的基类(object?) bt.baseType = t.BaseType; } // 如果参数 beDropBaseType 为假,或可导出类型中没有类型 t else if (!beDropBaseType || baseType.IndexOf(t) < 0) { // 找到 t 位于 List<BindType> allTypes 中类型相同的 BindType 元素位置 int index = allTypes.FindIndex((iter) => { return(iter.type == t); }); // 如果没有找到就打印警告并新建 BindType 加入到 allTypes 中去,否则返回空(已经被添加过了) if (index < 0) { #if JUMP_NODEFINED_ABSTRACT if (t.IsAbstract && !t.IsSealed) { Debugger.LogWarning("not defined bindtype for {0}, it is abstract class, jump it, child class is {1}", t.FullName, bt.name); bt.baseType = t.BaseType; } else { Debugger.LogWarning("not defined bindtype for {0}, autogen it, child class is {1}", t.FullName, bt.name); bt = new BindType(t); allTypes.Add(bt); } #else Debugger.LogWarning("not defined bindtype for {0}, autogen it, child class is {1}", t.FullName, bt.name); bt = new BindType(t); allTypes.Add(bt); #endif } else { return; } } else { return; } // 调用自身以验证添加结果(如果有进行添加的话则进行相应处理,无添加则返回) AutoAddBaseType(bt, beDropBaseType); }