CSharpMetadataTableGenerater.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. namespace etoy
  2. {
  3. class CSharpMetadataTableGenerater : IGenerater
  4. {
  5. private const string RELATIVE_PATH = "Metadatas";
  6. public void Generate(Context context)
  7. {
  8. var tables = context.Blackboard.MetadataTables;
  9. foreach (var table in tables)
  10. GenSingle(table, context);
  11. }
  12. private void GenSingle(MetadataTable table, Context context)
  13. {
  14. string directory = Path.Combine(context.Option.ClientCodeOutput, RELATIVE_PATH).ToPath();
  15. if (!Directory.Exists(directory))
  16. Directory.CreateDirectory(directory);
  17. foreach (var row in table.Rows)
  18. {
  19. var key = row.Struct.StructType;
  20. switch (key)
  21. {
  22. case MetadataStructType.Struct:
  23. GenStruct(context, row, directory);
  24. break;
  25. case MetadataStructType.Enum:
  26. GenEnum(row, directory);
  27. break;
  28. }
  29. }
  30. }
  31. private void GenStruct(Context context, MetadataRow row, string directory)
  32. {
  33. string csharpTypeName = row.Struct.Name;
  34. string fileName = csharpTypeName + ".cs";
  35. string path = Path.Combine(directory, fileName);
  36. var serializes = new List<string>(); //序列化属性
  37. var deserializes = new List<string>(); //反序列化属性
  38. using var writer = new CodeWriter(path);
  39. writer.WriteLine("// Generate By EToy");
  40. writer.WriteLine("// Don't Edit It!!");
  41. writer.WriteLine();
  42. writer.WriteLine("using XGame.Framework.Serialization;");
  43. // namespace
  44. writer.Bracket("namespace XGame.Database");
  45. {
  46. // class
  47. writer.WriteLine("/// <summary>");
  48. writer.WriteLine($"/// {row.Struct.Description}");
  49. writer.WriteLine("/// </summary>");
  50. writer.Bracket($"public sealed class {csharpTypeName} : ISerializable");
  51. {
  52. // 属性定义
  53. foreach (var field in row.Struct.Fields)
  54. {
  55. //string repeated = field.StructRepeated ? "[]" : string.Empty;
  56. //bool isContainsMetadataType = context.Blackboard.ContainsMetadataType(field.FieldType);
  57. string fieldType = field.FieldType;// isContainsMetadataType ? $"{field.FieldType}" : field.FieldType;
  58. var fieldName = field.Name.ToTitleCase();
  59. if (field.StructRepeated)
  60. {
  61. // 数组
  62. writer.WriteLine($"public {fieldType}[] {fieldName} {{ get; private set; }}");
  63. deserializes.Add($"{fieldName} = reader.ReadEnumerable<{fieldType}[]>();");
  64. serializes.Add($"writer.Write({fieldName});");
  65. }
  66. else
  67. { // 字段
  68. writer.WriteLine($"public {fieldType} {fieldName} {{ get; private set; }}");
  69. if (context.Blackboard.TryGetMetadata(fieldType, out var metadata))
  70. {
  71. if (metadata.StructType == MetadataStructType.Enum)
  72. {// 枚举
  73. deserializes.Add($"{fieldName} = ({fieldType})reader.ReadInt();");
  74. serializes.Add($"writer.Write((int){fieldName});");
  75. }
  76. else
  77. { // 数据结构
  78. deserializes.Add($"{fieldName} = reader.ReadSerializable<{fieldType}>();");
  79. serializes.Add($"writer.Write({fieldName});");
  80. }
  81. }
  82. else
  83. { // 普通字段
  84. deserializes.Add($"{fieldName} = reader.Read{fieldType.ToTitleCase()}();");
  85. serializes.Add($"writer.Write({fieldName});");
  86. }
  87. }
  88. }
  89. // 反序列化数据
  90. writer.WriteLine();
  91. writer.Bracket("void ISerializable.Deserialize(IReader reader)");
  92. {
  93. for (var i = 0; i < deserializes.Count; i++)
  94. {
  95. writer.WriteLine(deserializes[i]);
  96. }
  97. }
  98. writer.EndBracket();
  99. // 序列化数据
  100. writer.WriteLine();
  101. writer.Bracket("void ISerializable.Serialize(IWriter writer)");
  102. {
  103. for (var i = 0; i < serializes.Count; i++)
  104. {
  105. writer.WriteLine(serializes[i]);
  106. }
  107. }
  108. writer.EndBracket();
  109. }
  110. writer.EndBracket();
  111. }
  112. writer.EndBracket();
  113. }
  114. private void GenEnum(MetadataRow row, string directory)
  115. {
  116. string csharpTypeName = row.Struct.Name;
  117. string fileName = csharpTypeName + ".cs";
  118. string path = Path.Combine(directory, fileName);
  119. using CodeWriter writer = new CodeWriter(path);
  120. // namespace
  121. writer.WriteLine("// Generate By EToy");
  122. writer.WriteLine("// Don't Edit It!!");
  123. writer.WriteLine();
  124. writer.Bracket("namespace XGame.Database");
  125. {
  126. // enum
  127. writer.WriteLine("/// <summary>");
  128. writer.WriteLine($"/// {row.Struct.Description}");
  129. writer.WriteLine("/// </summary>");
  130. writer.Bracket($"public enum {csharpTypeName} : int");
  131. {
  132. foreach (var field in row.Struct.Fields)
  133. {
  134. if (string.IsNullOrEmpty(field.EnumValue))
  135. writer.WriteLine($"{field.Name},");
  136. else
  137. writer.WriteLine($"{field.Name} = {field.EnumValue},");
  138. }
  139. writer.EndBracket();
  140. }
  141. writer.EndBracket();
  142. }
  143. }
  144. }
  145. }