namespace etoy { class CSharpCommonTableGenerater : IGenerater { private const string CLASS_TAIL = "Table"; // C# Table作为类型后缀 private const string RELATIVE_PATH = "Tables"; public void Generate(Context context) { var tables = context.Blackboard.Tables; foreach (var table in tables) { if (table.TableTag.HasFlag(TableTag.Client)) { GenSingle(context, table); GenEnum(context, table); } } } private void GenSingle(Context context, Table table) { string fileName = table.Name + $"{CLASS_TAIL}.cs"; string directory = Path.Combine(context.Option.ClientCodeOutput, RELATIVE_PATH).ToPath(); if (!Directory.Exists(directory)) Directory.CreateDirectory(directory); string path = Path.Combine(directory, fileName); var serializes = new List(); //序列化属性 var deserializes = new List(); //反序列化属性 using var writer = new CodeWriter(path); writer.WriteLine("// Generate By EToy"); writer.WriteLine("// Don't Edit It!!"); writer.WriteLine(); writer.WriteLine("using XGame.Framework.Database;"); writer.WriteLine("using XGame.Framework.Serialization;"); writer.WriteLine(); // namespace writer.Bracket("namespace XGame.Database"); { // class writer.Summary(table.Description); writer.Bracket($"public sealed class {table.Name}{CLASS_TAIL} : ITable"); { var pkFieldInfo = table.GetPKFieldInfo(); if (pkFieldInfo != null) { writer.WriteLine($"long ITable.Key => {pkFieldInfo.FieldName.ToTitleCase()};"); } else { throw new Exception($"配置表生成CSharp代码, 表结构未设置PrimaryKey的字段. {table.Path}"); } // 属性定义 for (int i = 0, length = table.FieldInfos.Length; i < length; i++) { var fieldInfo = table.FieldInfos[i]; // no export server’s field if (!fieldInfo.IsClientField) continue; writer.WriteLine(); writer.Summary(fieldInfo.Description); string notes = string.IsNullOrEmpty(fieldInfo.Tags) ? string.Empty : $" // {fieldInfo.Tags}"; string fieldType = fieldInfo.FieldType;// isContainsMetadataType ? $"{fieldInfo.FieldType}{STRUCT_TAIL}" : fieldInfo.FieldType; //bool isContainsMetadataType = context.Blackboard.ContainsMetadataType(fieldType); var fieldName = fieldInfo.FieldName.ToTitleCase(); if (fieldInfo.IsRepeated) { // 数组 writer.WriteLine($"public {fieldType}[] {fieldName} {{ get; private set; }}{notes}"); deserializes.Add($"{fieldName} = reader.ReadEnumerable<{fieldType}[]>();"); serializes.Add($"writer.Write({fieldName});"); } else { // 字段 writer.WriteLine($"public {fieldType} {fieldName} {{ get; private set; }}{notes}"); if (context.Blackboard.TryGetMetadata(fieldType, out var metadata)) { if (metadata.StructType == MetadataStructType.Enum) {// 枚举 deserializes.Add($"{fieldName} = ({fieldType})reader.ReadInt();"); serializes.Add($"writer.Write((int){fieldName});"); } else { // 数据结构 deserializes.Add($"{fieldName} = reader.ReadSerializable<{fieldType}>();"); serializes.Add($"writer.Write({fieldName});"); } } else { // 普通字段 deserializes.Add($"{fieldName} = reader.Read{fieldType.ToTitleCase()}();"); serializes.Add($"writer.Write({fieldName});"); } } } // 反序列化数据 writer.WriteLine(); writer.Bracket("void ISerializable.Deserialize(IReader reader)"); { for (var i = 0; i < deserializes.Count; i++) { writer.WriteLine(deserializes[i]); } } writer.EndBracket(); // 序列化数据 writer.WriteLine(); writer.Bracket("void ISerializable.Serialize(IWriter writer)"); { for(var i = 0;i < serializes.Count;i++) { writer.WriteLine(serializes[i]); } } writer.EndBracket(); } writer.EndBracket(); } writer.EndBracket(); //writer.Flush(); } /// /// 生成配置表的枚举 /// /// /// private void GenEnum(Context context, Table table) { if (table.tableEnum == null) return; var enumName = table.tableEnum.name; var filePath = $"{context.Option.ClientCodeOutput}/{enumName}.cs"; using var writer = new CodeWriter(filePath); writer.WriteLine("// Generate By EToy"); writer.WriteLine("// Don't Edit It!!"); writer.WriteLine(); writer.Bracket("namespace XGame.Database"); { writer.Summary($"{table.Name} 转枚举 {enumName}\nKey : {table.tableEnum.key} \nValue :{table.tableEnum.value}"); writer.Bracket($"public enum {enumName} : int"); { for (int i = 0, rowCount = table.Rows.Count; i < rowCount; i++) { var row = table.Rows[i]; GetEnumProperty(row, table.tableEnum, out var name, out var value, out var summary); if (string.IsNullOrEmpty(name)) continue; writer.Summary(summary); writer.WriteLine($"{name} = {value},"); } writer.EndBracket(); } writer.EndBracket(); } } private void GetEnumProperty(Row row, TableEnum @enum, out string name, out string value, out string summary) { name = value = summary = string.Empty; foreach (var cell in row.Cells) { if (@enum.key.Equals(cell.FieldInfo.FieldName, StringComparison.OrdinalIgnoreCase)) { name = cell.Value.ToTitleCase(); } else if (@enum.value.Equals(cell.FieldInfo.FieldName, StringComparison.OrdinalIgnoreCase)) { value = cell.Value; } else if (@enum.summary.Equals(cell.FieldInfo.FieldName, StringComparison.OrdinalIgnoreCase)) { summary = cell.Value; } } } } }