游戏表格数据序列化自动生成工具
来源:互联网 发布:最值得看的电影 知乎 编辑:程序博客网 时间:2024/05/01 03:50
先看效果:
指定目录下的excel表格:
开始编译文件:
反序列读取数据:
在unity中读取结果:
嗯。首先开始写代码。
1.读取excel表格中的表单 根据表单的列定义数据结构。
1.1配置表格
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Data;using System.Data.OleDb;using System.IO;using System.Diagnostics;using System.Threading;namespace ORMTool{ /// <summary> /// 在这里面进行配置Excel里面内的表单名字 /// </summary> public class TableConfig { public static Dictionary<string, List<string>> arryTable = new Dictionary<string, List<string>>(); public static List<string> GetArryTable(string excelName) { List<string> arry; arryTable.TryGetValue(excelName, out arry); return arry; } public static void CheckExcelIsConfig() { string excelDirectory=Program.excelDirectory; //***************************改变excel的存放目录 string[] excelPaths= Directory.GetFiles(excelDirectory); arryTable.Clear(); for (int i = 0; i < excelPaths.Length; i++) { string excelName = Path.GetFileNameWithoutExtension(excelPaths[i]); if(Path.GetExtension(excelPaths[i])==".xls") //只能打开指定类型的xls文件 { string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + excelPaths[i] + ";" + "Extended Properties=Excel 8.0;"; //2007及以下的excel版本 //string strConn = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0;HDR=Yes;IMEX=0;'", Path);//2010以上的excel版本 OleDbConnection conn = new OleDbConnection(strConn); try { conn.Open(); DataTable daOle=conn.GetSchema("Tables"); DataTableReader dtReader = new DataTableReader(daOle); List<string> tableName = new List<string>(); while (dtReader.Read()) { if (dtReader["Table_Name"].ToString().Contains("Config")) { tableName.Add(dtReader["Table_Name"].ToString().Replace('$',' ').Trim()); } } arryTable.Add(excelName, tableName); dtReader = null; daOle = null; conn.Close(); } catch (Exception e) { Console.WriteLine(e.Message); } } } } }}这段代码 意思是 检查指定目录下的excel文件 是否合法,如果是指定需要编译的表单 将其加入到字典中 等待编译。
1.2创建临时空文件夹 以备将生成的cs文件和 批处理命令放入其中。
public void GetExcel() { if (!Directory.Exists("E:\\TempFloder")) { Console.WriteLine(" no exist"); Directory.CreateDirectory("E:\\TempFloder"); } CreateApiStringHead(); CreateBaseClass();//先创建基类 foreach (var key in TableConfig.arryTable.Keys) { path = @"E:\ExcelTest\" + key + ".xls"; ExcelToDS(path,TableConfig.GetArryTable(key)); } CreateApiStringEnd(); CreateTableType();//增加枚举 }1.3读取excel表单 生成cs文件 xml文件 。一个表单对应一个类,然后将类的成员信息加入到xml文件中 为了能够在用的时候有提示。
/// <summary> /// 连接excel,并编译成实体类 /// </summary> /// <param name="Path">excel路径</param> /// <param name="arryTable">此excel下的表单名字数组</param> public void ExcelToDS(string Path, List<string> arryTable) { string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Path + ";" + "Extended Properties=Excel 8.0;"; //2007及以下的excel版本 //string strConn = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0;HDR=Yes;IMEX=0;'", Path);//2010以上的excel版本 OleDbConnection conn = new OleDbConnection(strConn); try { conn.Open(); string strExcel = ""; OleDbDataAdapter myCommand = null; DataSet ds = null; if (arryTable.Count > 0) { for (int i = 0; i < arryTable.Count; i++) { strExcel = "select * from [" + arryTable[i] + "$]"; myCommand = new OleDbDataAdapter(strExcel, strConn); ds = new DataSet(); myCommand.Fill(ds, arryTable[i]); int attributeCount = ds.Tables[0].Columns.Count;//赋值属性个数 CreateEntity(ds.Tables[0], arryTable[i], attributeCount); CreateApiXml(ds.Tables[0], attributeCount, arryTable[i]); } } conn.Close(); } catch (Exception e) { Console.WriteLine(e.Message); } } /// <summary> /// 创建基类 /// </summary> public void CreateBaseClass() { StringBuilder cs = new StringBuilder(); string line = "\r\n"; //加入命名空间 cs.Append("using System;").Append(line); cs.Append("using System.Collections.Generic;").Append(line).Append(line); cs.Append("namespace ").Append(_namespce).Append(line); cs.Append("{"); cs.Append(line).Append(line); //加入序列化标识 cs.Append("[Serializable]").Append(line); //加入类名 cs.Append(" public abstract class ").Append("SerializabBaseObject").Append(line); cs.Append(" {"); cs.Append(line); cs.Append(" public int m_id {get;set;}").Append(line); cs.Append(" abstract public void Parse(List<SerializabBaseObject> config);").Append(line); cs.Append(" abstract public SerializabBaseObject GetRowData(int id);").Append(line); cs.Append(" abstract public List<SerializabBaseObject> GetDatas();").Append(line); cs.Append(" }"); cs.Append(line); cs.Append("}"); string pathSave = "E:\\TempFloder\\" + "SerializabBaseObject.cs"; //在此修改生成实体类的路径 if (System.IO.File.Exists(pathSave)) { System.IO.File.Delete(pathSave); } System.IO.StreamWriter sw = System.IO.File.CreateText(pathSave); sw.Write(cs.ToString()); sw.Flush(); sw.Close(); } /// <summary> /// 创建实体类 /// </summary> /// <param name="_dataTable">表数据</param> /// <param name="className">类名</param> /// <param name="attributeCount">属性个数</param> public void CreateEntity(DataTable _dataTable, string className, int attributeCount) { Console.WriteLine("Gening "+className+"..." ); StringBuilder cs = new StringBuilder(); string line = "\r\n"; //加入命名空间 cs.Append("using System;").Append(line); cs.Append("using System.Collections.Generic;").Append(line).Append(line); cs.Append("namespace ").Append(_namespce).Append(line); cs.Append("{"); cs.Append(line).Append(line) ; //加入序列化标识 cs.Append("[Serializable]").Append(line); //加入类名 cs.Append(" public class ").Append(className).Append(":SerializabBaseObject").Append(line); cs.Append(" {"); cs.Append(line); //添加私有字段 for (int i = 0; i < attributeCount; i++) { ColumnAttribute ca = GetAttributeName(_dataTable.Columns[i].ColumnName); cs.Append(" private ").Append(ca.DataType + " ").Append("m_" + ca.AttributeName + "; "); cs.Append(line).Append(line); } //添加属性 for (int i = 0; i < attributeCount; i++) { //return m_ID; } set { m_ID = value; ColumnAttribute ca = GetAttributeName(_dataTable.Columns[i].ColumnName); cs.Append(" /// <summary>").Append(line); cs.Append(" ///").Append(ca.Description).Append(line); cs.Append(" /// </summary>").Append(line); string _str = "{ get { return "+"m_"+ca.AttributeName+"; } set { "+"m_"+ca.AttributeName+" = value; } }"; cs.Append(" public ").Append(ca.DataType + " ").Append(ca.AttributeName + " ").Append(_str); cs.Append(line).Append(line); } //添加抽象方法 cs.Append(" private Dictionary<int, SerializabBaseObject> m_datas = null;").Append(line); cs.Append(" private List<SerializabBaseObject> m_listDatas = null;").Append(line); cs.Append(" public override void Parse(List<SerializabBaseObject> config)").Append(line); cs.Append(" {").Append(line); cs.Append(" if (m_datas == null)").Append(line); cs.Append(" m_datas = new Dictionary<int, SerializabBaseObject>();").Append(line); cs.Append(" if(m_listDatas==null)").Append(line); cs.Append(" m_listDatas = new List<SerializabBaseObject>();").Append(line); cs.Append(" m_datas.Clear();").Append(line); cs.Append(" m_listDatas.Clear();").Append(line); cs.Append(" for (int i = 0; i < config.Count; i++)").Append(line); cs.Append(" {").Append(line); cs.Append(" m_datas.Add(config[i].m_id, config[i]);").Append(line); cs.Append(" }").Append(line); cs.Append(" m_listDatas = config;").Append(line); cs.Append(" }").Append(line).Append(line); cs.Append(" public override SerializabBaseObject GetRowData(int id)").Append(line); cs.Append(" {").Append(line); cs.Append(" SerializabBaseObject data = null;").Append(line); cs.Append(" if (m_datas.TryGetValue(id, out data))").Append(line); cs.Append(" {").Append(line); cs.Append(" return data;").Append(line); cs.Append(" }").Append(line); cs.Append(" return null;").Append(line); cs.Append(" }").Append(line).Append(line); cs.Append(" public override List<SerializabBaseObject> GetDatas()").Append(line); cs.Append(" {").Append(line); cs.Append(" if (m_listDatas != null)").Append(line); cs.Append(" return m_listDatas;").Append(line); cs.Append(" else").Append(line); cs.Append(" return null;").Append(line); cs.Append(" }").Append(line).Append(line); cs.Append(" }"); cs.Append(line); cs.Append("}"); string pathSave = "E:\\TempFloder\\" + className + ".cs"; //在此修改生成实体类的路径 if(System.IO.File.Exists(pathSave)) { System.IO.File.Delete(pathSave); } System.IO.StreamWriter sw= System.IO.File.CreateText(pathSave); sw.Write(cs.ToString()); sw.Flush(); sw.Close(); Console.WriteLine(className + " Gen Success!"); } /// <summary> /// 创建xml 头 /// </summary> public void CreateApiStringHead() { string line = "\r\n"; sbApiXml.Append("<?xml version=\"1.0\"?>").Append(line); sbApiXml.Append("<doc>").Append(line); sbApiXml.Append(" <assembly>").Append(line); string spceName = string.Format(" <name>{0}</name>",_namespce); sbApiXml.Append(spceName).Append(line); sbApiXml.Append(" </assembly>").Append(line); sbApiXml.Append(" <members>").Append(line); } /// <summary> /// 创建xml 尾 /// </summary> public void CreateApiStringEnd() { string line = "\r\n"; sbApiXml.Append(" </members>").Append(line); sbApiXml.Append("</doc>"); StreamWriter sw = File.CreateText("E:\\TempFloder\\" + dllName+".XML"); sw.Write(sbApiXml.ToString()); sw.Flush(); sw.Close(); } public void CreateApiXml(DataTable _dataTable, int attCount, string className) { string line = "\r\n"; for (int i = 0; i < attCount; i++) { ColumnAttribute ca = GetAttributeName(_dataTable.Columns[i].ColumnName); string attName = string.Format(" <member name=\"P:{0}.{1}.{2}\">", _namespce,className, ca.AttributeName); sbApiXml.Append(attName).Append(line); sbApiXml.Append(" <summary>").Append(line); string attDesc = string.Format(" {0}", ca.Description); sbApiXml.Append(attDesc).Append(line); sbApiXml.Append(" </summary>").Append(line); sbApiXml.Append(" </member>").Append(line); } } /// <summary> /// 获取列名转化为属性对象 /// 列名命名规范 列名描述|列名(数据类型) 如 编号|ID(int) /// </summary> /// <param name="columnName">列名</param> /// <returns>属性对象</returns> public ColumnAttribute GetAttributeName(string columnName) { ColumnAttribute ca = new ColumnAttribute(); ca.Description = columnName.Split('|')[0].ToString(); ca.AttributeName = columnName.Split('|')[1].Split('(')[0].ToString(); ca.DataType = columnName.Split('|')[1].Split('(')[1].Split(')')[0].ToString(); return ca; } /// <summary> /// 创建临时文件夹 存放生成的实体类 /// </summary> public void CreateTempFloder() { string tempFloderPath = "E:\\TempFloder"; try { if (Directory.Exists(tempFloderPath)) { if (Directory.GetFiles(tempFloderPath).Length != 0) { for (int i = 0; i < Directory.GetFiles(tempFloderPath).Length; i++) { File.Delete(Directory.GetFiles(tempFloderPath)[i]); } } Directory.Delete(tempFloderPath, true); } Directory.CreateDirectory(tempFloderPath); } catch (Exception e) { Console.WriteLine(e.Message); } }
public void CreateTableType() { string line = "\r\n"; StringBuilder sb = new StringBuilder(); sb.Append("using System;").Append(line).Append(line); sb.Append("namespace ").Append(_namespce).Append(line); sb.Append("{").Append(line).Append(line); sb.Append("[Serializable]").Append(line); sb.Append(" public enum TableType").Append(line); sb.Append(" {").Append(line); foreach (var key in TableConfig.arryTable.Keys) { List<string> tablename= TableConfig.GetArryTable(key); for (int i = 0; i < tablename.Count; i++) { sb.Append(" " + tablename[i]+",").Append(line); } } sb.Append(" }").Append(line); sb.Append("}").Append(line); StreamWriter sw = new StreamWriter("E:\\TempFloder\\TableType.cs"); sw.Write(sb.ToString()); sw.Flush(); sw.Close(); } } public class ColumnAttribute { public string Description { get; set; } public string AttributeName{get;set;} public string DataType { get; set; } }
1.3生成bat批处理命令 并编译cs文件打包成dll。
/// <summary> /// 编译dll /// </summary> public void GenDll() { //创建bat 编译命名 StreamWriter sw = System.IO.File.CreateText(@"E:\TempFloder\gen.bat"); StringBuilder sb = new StringBuilder(); sb.Append("@echo off").Append("\r\n"); //sb.Append(@"cd\").Append("\r\n"); //sb.Append("C:").Append("\r\n"); //sb.Append(@"cd WINDOWS\Microsoft.NET\Framework\v3.5").Append("\r\n"); //string dllNameStr = string.Format(@"csc /target:library /out:e:\TempFloder\{0}.dll e:\TempFloder\*.cs",dllName); //sb.Append(dllNameStr).Append("\r\n"); sb.Append(@"c://WINDOWS/Microsoft.NET/Framework/v3.5/csc /target:library /out:e:\TempFloder\Serializable_0.dll e:\TempFloder\*.cs").Append("\r\n"); sb.Append("exit"); sw.Write(sb.ToString()); sw.Flush(); sw.Close(); Process proc = null; try { proc = new Process(); proc.StartInfo.WorkingDirectory = "E:\\TempFloder"; proc.StartInfo.FileName = "gen.bat"; proc.StartInfo.CreateNoWindow = false; proc.Start(); proc.StartInfo.RedirectStandardInput = true; proc.WaitForExit(); while (!isGendllComplte) { isGendllComplte = proc.HasExited; } proc.Close(); } catch (Exception ex) { Console.WriteLine("Exception Occurred :{0},{1}", ex.Message, ex.StackTrace.ToString()); } }1.4将生成的dll 拷贝到指定的目录 然后再删除临时文件夹。
/// <summary> /// 将dll剪贴到指定的位置 /// </summary> public void MoveDll() { if (!isGendllComplte) { MoveDll(); return; } string movePath = "E:\\Libs"; string dllStr = string.Format("{0}.dll",dllName); if (!Directory.Exists(movePath)) { Console.WriteLine("!Error:此目录不存在"+movePath+" ,新建新的目录"); Directory.CreateDirectory(movePath); //return; } if (File.Exists(movePath + "\\" + dllStr)) { File.Delete(movePath + "\\"+dllStr); } File.Move("E:\\TempFloder\\"+dllStr, movePath + "\\"+dllStr); string[] xmlPaths= Directory.GetFileSystemEntries("E:\\Libs", "*.XML"); string[] xmlPathsRes = Directory.GetFileSystemEntries("E:\\TempFloder", "*.XML"); if (xmlPaths.Length != 0) { for (int i = 0; i < xmlPaths.Length; i++) { File.Delete(xmlPaths[i]); } } for (int i = 0; i < xmlPathsRes.Length; i++) { if (File.Exists(movePath + "\\" + Path.GetFileName(xmlPathsRes[i]))) { File.Delete(movePath + "\\" + Path.GetFileName(xmlPathsRes[i])); } File.Move(xmlPathsRes[i],movePath+"\\"+Path.GetFileName(xmlPathsRes[i])); } if (File.Exists(movePath + "\\" + dllStr)) { string tempFloderPath = "E:\\TempFloder"; if (Directory.Exists(tempFloderPath)) { Directory.Delete(tempFloderPath, true); } } }2.这样表单对应的就有了数据结构,接下来要序列化表单数据。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Data;using System.Data.OleDb;using System.IO;using System.Diagnostics;using System.Threading;using System.Reflection;using System.Runtime.Serialization.Formatters.Binary;namespace ORMTool{ public class SerializableFile { static private SerializableFile m_inist; private readonly string token = "dabe54f00f27e733afcad4bdd91b8675"; public static SerializableFile Inist { get { if (m_inist == null) return new SerializableFile(); else return m_inist; } } public SerializableFile() { m_inist = this; } public void Serializable() { Console.WriteLine("--------开始序列化------"); foreach (var key in TableConfig.arryTable.Keys) { string path = @"E:\ExcelTest\" + key + ".xls"; //暂时只支持2007版一下版本 因为太高版本需要下载组件。麻烦 List<string> arryTable=TableConfig.GetArryTable(key); string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + path + ";" + "Extended Properties=Excel 8.0;"; //2007及以下的excel版本 //string strConn = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0;HDR=NO;IMEX=1'", path);//2010以上的excel版本 OleDbConnection conn = new OleDbConnection(strConn); try { conn.Open(); string strExcel = ""; OleDbDataAdapter myCommand = null; DataSet ds = null; if (arryTable.Count > 0) { for (int i = 0; i < arryTable.Count; i++) { strExcel = "select * from [" + arryTable[i] + "$]"; myCommand = new OleDbDataAdapter(strExcel, strConn); ds = new DataSet(); myCommand.Fill(ds, arryTable[i]); FillDate(ds.Tables[0],arryTable[i]); } } conn.Close(); } catch (Exception e) { Console.WriteLine(e.Message); return; } } Console.WriteLine("--------序列化完毕------"); } private void FillDate(DataTable dt,string genFileName) { Console.WriteLine("------Serializeing "+genFileName); List<object> serObjs = new List<object>(); string dllPath = "E:\\Libs\\Serializable_0.dll"; Assembly ass = Assembly.LoadFile(dllPath); Type objectType = ass.GetType(Program._namespce+"." + genFileName); //******** Program pro=new Program(); for (int i = 0; i < dt.Rows.Count; i++) { object obj = Activator.CreateInstance(objectType);// 创建实例 PropertyInfo[] infos = obj.GetType().GetProperties(); for (int n = 0; n < dt.Columns.Count; n++) { ColumnAttribute ca = pro.GetAttributeName(dt.Columns[n].ColumnName); if (n == 0) //第一行id列 { PropertyInfo[] memberInfos = obj.GetType().GetProperties(); foreach (PropertyInfo item in memberInfos) { if(item.Name=="m_id") { item.SetValue(obj, int.Parse(dt.Rows[i][0].ToString())); } } } foreach (PropertyInfo info in infos) { if (info.Name == ca.AttributeName && info.CanWrite) { if (dt.Rows[i][n] == null || string.IsNullOrEmpty(dt.Rows[i][n].ToString())) { break; } if (IsType(info.PropertyType, "System.String")) //在此添加所支持的数据类型 { ReflectionSetProperty(obj, ca.AttributeName, dt.Rows[i][n].ToString()); break; } else if (IsType(info.PropertyType, "System.Boolean")) { ReflectionSetProperty(obj, ca.AttributeName, (Boolean.Parse(dt.Rows[i][n].ToString()))); break; } else if (IsType(info.PropertyType, "System.Int32")) { ReflectionSetProperty(obj, ca.AttributeName, int.Parse(dt.Rows[i][n].ToString())); break; } else if (IsType(info.PropertyType, "System.Int64")) { ReflectionSetProperty(obj, ca.AttributeName, (Int64.Parse(dt.Rows[i][n].ToString()))); break; } else if (IsType(info.PropertyType, "System.Single")) { ReflectionSetProperty(obj, ca.AttributeName, float.Parse(dt.Rows[i][n].ToString())); break; } } } } serObjs.Add(obj); } //序列化 BinaryFormatter bf = new BinaryFormatter(); FileStream sw = File.Create("E:\\Libs\\" + genFileName+".bin"); //*************c此处修改生成的二进制扩展名 bf.Serialize(sw, serObjs); sw.Close(); Console.WriteLine("------Serialize Complte " + genFileName); } /// <summary> /// 给属性赋值 /// </summary> /// <param name="objClass"></param> /// <param name="propertyName"></param> /// <param name="value"></param> private void ReflectionSetProperty(object objClass, string propertyName,object value) { PropertyInfo[] infos=objClass.GetType().GetProperties(); foreach (PropertyInfo info in infos) { if(info.Name==propertyName&&info.CanWrite) { info.SetValue(objClass, value, null); break; } } } /// <summary> /// 反序列化 返回值为object 需要在泛型类中进行类型转化 /// </summary> /// <param name="binPath">需要反序列化的二进制文件路径</param> /// <returns></returns> public object DeSerialize(string binPath) { if (!File.Exists(binPath)) { Console.WriteLine("!warring: Not Found "+binPath); return null; } FileStream fs = File.Open(binPath, FileMode.Open); //序列化 BinaryFormatter bf = new BinaryFormatter(); object oj= bf.Deserialize(fs); fs.Close(); return oj; } /// <summary> /// 类型匹配 /// </summary> /// <param name="type"></param> /// <param name="typeName"></param> /// <returns></returns> public bool IsType(Type type, string typeName) { if (type.ToString() == typeName) return true; if (type.ToString() == "System.Object") return false; return IsType(type.BaseType, typeName); } }}
这里面用的是反射技术。不懂得小伙伴可以百度查资料。
这样生成完成后 就有了一个二进制bin文件。有了dll类库,那么就可以去读取数据利用反射可以创建对象。
3.定义泛型对象。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Collections;using System.IO;using System.Runtime.Serialization.Formatters.Binary;namespace ORMTool{ /// <summary> /// 泛型类 /// author:wangyunfei /// email:1172906928@qq.com /// </summary> /// <typeparam name="T"></typeparam> public class ProtoData<T> : IEnumerable where T : ORMTool.SerializabBaseObject { public T[] items; public ProtoData(byte[] bytes) { MemoryStream ms = new MemoryStream(bytes); BinaryFormatter bt = new BinaryFormatter(); object ob= bt.Deserialize(ms); if (ob == null) return; List<object> list = ob as List<object>; if (list == null) return; items = new T[list.Count]; for (int i = 0; i < list.Count; i++) { T t = list[i] as T; if (t != null) { items[i] = t; } } } public ProtoData(object ob) { if (ob == null) return; List<object> list = ob as List<object>; if (list == null) return; items = new T[list.Count]; for (int i = 0; i < list.Count; i++) { T t= list[i] as T; if (t != null) { items[i] = t; } } } // Implementation for the GetEnumerator method. IEnumerator IEnumerable.GetEnumerator() { return (IEnumerator)GetEnumerator(); } /// <summary> /// 参考 https://msdn.microsoft.com/zh-cn/library/system.collections.ienumerable.getenumerator.aspx /// </summary> /// <returns></returns> public Node GetEnumerator() { return new Node(items); } /// <summary> /// 节点类 /// </summary> public class Node:IEnumerator { public T[] _node; int position = -1; public Node(T[] list) { _node = list; } public bool MoveNext() { position++; return (position < _node.Length); } public void Reset() { position = -1; } object IEnumerator.Current { get { return Current; } } public T Current { get { try { return _node[position]; } catch (IndexOutOfRangeException) { throw new InvalidOperationException(); } } } } }}这个代码的意思是 每个类都是派生出来的,都继承了SerializabBaseObject,在序列化时,我们知道派生类型,但是反序列出来后并不知道其类型。只是一个object类型,那么做个泛型类就很方便的根据读取的bin数据转化对应的数据类型。防止类型转化出现错误。
4.解析每个bin数据。
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Reflection;namespace ORMTool{ public class TableManager { private static TableManager m_Instance=null; public static TableManager Instance { get { if (m_Instance == null) return new TableManager(); else return m_Instance; } } private Dictionary<TableType, SerializabBaseObject> tables = null; public TableManager() { m_Instance = this; if (tables == null) { tables = new Dictionary<TableType, SerializabBaseObject>(); } tables.Clear(); _Parse(); //Parse(); } /// <summary> /// 此方法暂时有问题 /// </summary> private void Parse() { string dllPath = "E:\\Libs\\Serializable_0.dll"; Assembly ass = Assembly.LoadFile(dllPath); string[] enumNames= Enum.GetNames(typeof(TableType)); for (int i = 0; i < enumNames.Length; i++) { if (!string.IsNullOrEmpty(enumNames[i])) { object oj = SerializableFile.Inist.DeSerialize(string.Format("E:\\Libs\\{0}.bin",enumNames[i])); ProtoData<SerializabBaseObject> s = new ProtoData<SerializabBaseObject>(oj); List<SerializabBaseObject> items = s.items.ToList<SerializabBaseObject>(); Type objectType = ass.GetType(Program._namespce + "." + enumNames[i]); //Type generic = typeof(List<SerializabBaseObject>); //Type constructed = generic.MakeGenericType(new Type[] { typeof(SerializabBaseObject) }); object obj = Activator.CreateInstance(objectType);// 创建实例 MethodInfo methodInfo = obj.GetType().GetMethod("Parse"); methodInfo.Invoke(obj, new object[]{items}); SerializabBaseObject obActor = (SerializabBaseObject)obj; tables.Add(GetEnume(enumNames[i]), obActor); Console.WriteLine("Parse "+enumNames[i]+" Complte------"); } } } private void _Parse() { string[] enumNames = Enum.GetNames(typeof(TableType)); for (int i = 0; i < enumNames.Length; i++) { if (!string.IsNullOrEmpty(enumNames[i])) { object oj = SerializableFile.Inist.DeSerialize(string.Format("E:\\Libs\\{0}.bin", enumNames[i])); ProtoData<SerializabBaseObject> s = new ProtoData<SerializabBaseObject>(oj); List<SerializabBaseObject> items = s.items.ToList<SerializabBaseObject>(); SerializabBaseObject config=null; switch (enumNames[i]) { case "MessageTextConfig": config = new MessageTextConfig(); break; default: break; } config.Parse(items); tables.Add(GetEnume(enumNames[i]), config); Console.WriteLine("Parse " + enumNames[i] + " Complte------"); } } } /// <summary> /// 注册类型 /// </summary> /// <param name="name"></param> /// <returns></returns> TableType GetEnume(string name) { switch (name) { case "MessageTextConfig": return TableType.MessageTextConfig; } return TableType.MessageTextConfig; } public SerializabBaseObject GetTableRowData(TableType type, int tableid) { SerializabBaseObject data = null; if (tables.TryGetValue(type, out data)) { data= data.GetRowData(tableid); } return data; } public List<SerializabBaseObject> GetTableDatas(TableType type) { SerializabBaseObject data = null; if (tables.TryGetValue(type, out data)) { return data.GetDatas(); } return null; } }}每个bin对应一个表单对象集合,需要从其中反射出来对应的对象,然后缓存到集合中以供使用。所以,每个派生类都实现了parse方法,就是解析bin数据映射到对应对象上。
5. unity中读取bin数据。
将生成的dll和xml放在Library\UnityAssemblies下面 这样的话属性就会有提示信息。也可以将dll直接放assets下面 xml 不用了 这样只是没有提示信息而已。
void OnGUI() { if (GUILayout.Button("load")) { StartCoroutine(Load((bytes) => { ProtoData<ORMTool.MessageTextConfig> _config = new ProtoData<ORMTool.MessageTextConfig>(bytes); foreach (ORMTool.MessageTextConfig item in _config) { Debug.Log(item.ID+"-"+item.ChineseText+"-"+item.KokrText); } })); } } IEnumerator Load(CallBack callback) { string url = "file:///"+Application.streamingAssetsPath + "/MessageTextConfig.bin"; WWW www = new WWW(url); yield return www; if (string.IsNullOrEmpty(www.error)) { if (callback != null) callback(www.bytes); } else { Debug.LogError(www.error); } }至此,全部完毕。如有不清楚的可以联系我QQ 1172906928. 个人原创,不喜勿喷,仅供相互学习,不足之处多多指点。
源码链接:http://pan.baidu.com/s/1c1BCvc8(提取码:3wan)
0 0
- 游戏表格数据序列化自动生成工具
- 一个简单数据序列生成工具
- .NET中数据层自动生成工具
- .NET中数据层自动生成工具
- thinkphp自动生成表格
- 解析WordprocessingML(二)通过数据集自动生成表格
- php自定义方法:自动生成数据表格(支持分页)
- 利用EditorWindow配制序列化数据表格
- IDEA自动生成序列化ID
- .net自动生成表格解决方案
- js实现自动生成表格
- js实现自动生成表格
- wps 表格 自动生成序号
- 简单自动生成表格方法
- 数据自动生成工具 DataFactory 的简单使用
- 数据自动生成工具 DataFactory 的简单使用
- 移动开发数据访问层自动生成工具
- mysql导出脚本自动生成word 数据字段perl工具
- 斐波那契数列-Fibonacci Sequence
- Docker 入门教程(三)
- Centos Yum安装Chrome浏览器
- worldwind java导入栅格影像时的无效区域透明问题
- EasyUI combobox 多选及回显赋值
- 游戏表格数据序列化自动生成工具
- 剑指offer面试题9-青蛙跳台阶及其变种问题
- 从银行窗口业务办理来看锁的实现
- 几种Web服务器比较-(Apache、IIS、Lighttpd、Nginx、LiteSpeed、Zeus
- Windows 开启“上帝模式”
- ABAP标准列表和选择屏幕
- mybatis自定义类型转换器
- 同一类消息或命令映射到同一个函数
- 考勤系统 人员排班设置