TestDatabase.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. using System;
  2. using System.IO;
  3. using System.Text;
  4. using UnityEditor;
  5. using UnityEngine;
  6. using XGame.Database;
  7. using XGame.Framework.Database;
  8. using XGame.Framework.Json;
  9. using XGame.Framework.Serialization;
  10. namespace FL.Editor.Tests
  11. {
  12. public static class TestDatabase
  13. {
  14. private static string CsvOutput => Application.dataPath.Replace("Assets", "ExtAssets/output/csv");
  15. [MenuItem("Test/TestDatabase/TablesToCsv")]
  16. public static void TablesToCsv()
  17. {
  18. var outputRoot = CsvOutput;
  19. if (Directory.Exists(outputRoot))
  20. {
  21. Directory.Delete(outputRoot, true);
  22. }
  23. Directory.CreateDirectory(outputRoot);
  24. TableToCsv<ChapterTable, ChapterTableRepo>(ChapterTableRepo.TableName);
  25. TableToCsv<MapTable, MapTableRepo>(MapTableRepo.TableName);
  26. TableToCsv<MonsterTable, MonsterTableRepo>(MonsterTableRepo.TableName);
  27. }
  28. private static void TableToCsv<TTable, TRepository>(string tableName) where TTable : class, ITable where TRepository : TableRepository<TTable, TRepository>
  29. {
  30. var tablePath = $"Assets/Res/Dynamic/Tables/{tableName}.bytes";
  31. var outputPath = $"{CsvOutput}/{tableName.Replace("Table", "")}.csv";
  32. var bytes = AssetDatabase.LoadAssetAtPath<TextAsset>(tablePath).bytes;
  33. var repo = SerializationUtils.Read<TRepository>(bytes);
  34. var sb = new StringBuilder();
  35. var tableType = typeof(TTable);
  36. var properties = tableType.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
  37. var fieldNames = string.Empty;
  38. var fieldTypes = string.Empty;
  39. var fieldCount = properties.Length;
  40. for (var i = 0; i < fieldCount; i++)
  41. {
  42. var separator = i == fieldCount - 1 ? "" : ",";
  43. fieldNames += $"\"{properties[i].Name}\"{separator}";
  44. fieldTypes += $"\"{properties[i].PropertyType.Name}\"{separator}";
  45. }
  46. sb.AppendLine(fieldNames);
  47. sb.AppendLine(fieldTypes);
  48. //空两行用于和etoy的csv文件保持一致
  49. sb.AppendLine();
  50. sb.AppendLine();
  51. foreach (var table in repo.GetAllTables())
  52. {
  53. var fieldValues = string.Empty;
  54. for (var i = 0; i < fieldCount; i++)
  55. {
  56. var separator = i == fieldCount - 1 ? "" : ",";
  57. var fieldType = properties[i].PropertyType;
  58. var value = properties[i].GetValue(table);
  59. if (fieldType.IsEnum == false && fieldType.Namespace.Contains("XGame.Database"))
  60. { // 自定义数据结构
  61. if (value is Array array)
  62. {
  63. var arrayVals = "[";
  64. for (var j = 0; j < array.Length; j++)
  65. {
  66. var item = array.GetValue(j);
  67. var itemType = item.GetType();
  68. arrayVals += ObjectToString(itemType, item);
  69. if (j < array.Length - 1)
  70. {
  71. arrayVals += ",";
  72. }
  73. }
  74. arrayVals += "]";
  75. value = arrayVals;
  76. }
  77. else
  78. {
  79. value = ObjectToString(fieldType, value);
  80. }
  81. }
  82. else
  83. {
  84. if (fieldType.IsArray)
  85. {
  86. value = XJson.ToJson(value);
  87. }
  88. }
  89. fieldValues += $"\"{value}\"{separator}";
  90. }
  91. sb.AppendLine(fieldValues);
  92. }
  93. File.WriteAllText(outputPath, sb.ToString());
  94. Debug.Log($"TableToCsv Path:{outputPath}");
  95. }
  96. private static string ObjectToString(Type type, object obj)
  97. {
  98. var fields = type.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
  99. var fieldCount = fields.Length;
  100. var fieldValues = "{";
  101. for (var i = 0; i < fieldCount; i++)
  102. {
  103. var separator = i == fieldCount - 1 ? "" : ",";
  104. var fieldType = fields[i].PropertyType;
  105. var value = fields[i].GetValue(obj);
  106. if (fieldType.IsArray)
  107. { //TODO 二次识别自定义数据结构
  108. value = XJson.ToJson(value);
  109. }
  110. fieldValues += $"{value}{separator}";
  111. }
  112. fieldValues += "}";
  113. return fieldValues;
  114. }
  115. //[UnityEditor.MenuItem("Test/TestDatabase/WriteTables")]
  116. //public static void WriteTables()
  117. //{
  118. // var length = 10;
  119. // var tables = new SimpleTable[length];
  120. // for (int i = 0; i < length; i++)
  121. // {
  122. // var table = new SimpleTable()
  123. // {
  124. // Id = i,
  125. // Name = typeof(SimpleTable).Name + i,
  126. // SimpleType = (SimpleType)(i % 2)
  127. // };
  128. // tables[i] = table;
  129. // }
  130. // var tableRepo = new SimpleTableRepo();
  131. // var fileInfo = typeof(SimpleTableRepo).GetField("_tables", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase);
  132. // if (fileInfo == null)
  133. // {
  134. // Debug.LogError($"没找到字段: _tables");
  135. // return;
  136. // }
  137. // fileInfo.SetValue(tableRepo, tables);
  138. // var writer = new Writer();
  139. // (tableRepo as ISerializable).Serialize(writer);
  140. // var bytes = writer.Finish();
  141. // var path = $"Assets/Res/Dynamic/Tables/SimpleTable.bytes";
  142. // File.WriteAllBytes(path, bytes);
  143. // var reader = new Reader(bytes);
  144. // var result = Activator.CreateInstance<SimpleTableRepo>() as ISerializable;
  145. // result.Deserialize(reader);
  146. // AssetDatabase.Refresh();
  147. // Debug.Log($"WriteTables End.");
  148. //}
  149. }
  150. }