Newer
Older
DungeonShooting / DungeonShooting_Godot / src / framework / generator / UiGenerator.cs
  1.  
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Text.RegularExpressions;
  5. using Godot;
  6.  
  7. namespace Generator;
  8.  
  9. /// <summary>
  10. /// Ui类生成器
  11. /// </summary>
  12. public static class UiGenerator
  13. {
  14. private static int _nodeIndex = 0;
  15.  
  16. /// <summary>
  17. /// 根据指定ui节点生成相应的Ui类, 并保存到指定路径下
  18. /// </summary>
  19. public static void GenerateUi(Control control, string path)
  20. {
  21. _nodeIndex = 0;
  22. var uiNode = EachNode(control);
  23. var code = GenerateClassCode(uiNode);
  24. File.WriteAllText(path, code);
  25. }
  26.  
  27. private static string GenerateClassCode(UiNode uiNode)
  28. {
  29. return $"namespace UI.{uiNode.OriginName};\n\n" +
  30. $"/// <summary>\n" +
  31. $"/// Ui代码, 该类是根据ui场景自动生成的, 请不要手动编辑该类, 以免造成代码丢失\n" +
  32. $"/// </summary>\n" +
  33. $"public abstract partial class {uiNode.OriginName} : UiBase\n" +
  34. $"{{\n" +
  35. GeneratePropertyListClassCode("", uiNode.OriginName + ".", uiNode, " ") +
  36. $"\n\n" +
  37. GenerateAllChildrenClassCode(uiNode.OriginName + ".", uiNode, " ") +
  38. $"}}\n";
  39. }
  40.  
  41. private static string GenerateAllChildrenClassCode(string parent, UiNode uiNode, string retraction)
  42. {
  43. var str = "";
  44. if (uiNode.Children != null)
  45. {
  46. for (var i = 0; i < uiNode.Children.Count; i++)
  47. {
  48. var item = uiNode.Children[i];
  49. str += GenerateAllChildrenClassCode(parent + item.OriginName + ".", item, retraction);
  50. str += GenerateChildrenClassCode(parent, item, retraction);
  51. }
  52. }
  53.  
  54. return str;
  55. }
  56. private static string GenerateChildrenClassCode(string parent, UiNode uiNode, string retraction)
  57. {
  58. return retraction + $"/// <summary>\n" +
  59. retraction + $"/// 类型: <see cref=\"{uiNode.TypeName}\"/>, 路径: {parent}{uiNode.OriginName}\n" +
  60. retraction + $"/// </summary>\n" +
  61. retraction + $"public class {uiNode.ClassName}\n" +
  62. retraction + $"{{\n" +
  63. retraction + $" /// <summary>\n" +
  64. retraction + $" /// Ui节点实例, 节点类型: <see cref=\"{uiNode.TypeName}\"/>, 节点路径: {parent}{uiNode.OriginName}\n" +
  65. retraction + $" /// </summary>\n" +
  66. retraction + $" public {uiNode.TypeName} Instance {{ get; }}\n\n" +
  67. GeneratePropertyListClassCode("Instance.", parent, uiNode, retraction + " ") +
  68. retraction + $" public {uiNode.ClassName}({uiNode.TypeName} node) => Instance = node;\n" +
  69. retraction + $" public {uiNode.ClassName} Clone() => new (({uiNode.TypeName})Instance.Duplicate());\n" +
  70. retraction + $"}}\n\n";
  71. }
  72.  
  73. private static string GeneratePropertyListClassCode(string target, string parent, UiNode uiNode, string retraction)
  74. {
  75. var str = "";
  76. if (uiNode.Children != null)
  77. {
  78. for (var i = 0; i < uiNode.Children.Count; i++)
  79. {
  80. var item = uiNode.Children[i];
  81. str += GeneratePropertyCode(target, parent, item, retraction);
  82. }
  83. }
  84.  
  85. return str;
  86. }
  87. private static string GeneratePropertyCode(string target, string parent, UiNode uiNode, string retraction)
  88. {
  89. return retraction + $"/// <summary>\n" +
  90. retraction + $"/// 使用 Instance 属性获取当前节点实例对象, 节点类型: <see cref=\"{uiNode.TypeName}\"/>, 节点路径: {parent}{uiNode.OriginName}\n" +
  91. retraction + $"/// </summary>\n" +
  92. retraction + $"public {uiNode.ClassName} {uiNode.Name}\n" +
  93. retraction + $"{{\n" +
  94. retraction + $" get\n" +
  95. retraction + $" {{\n" +
  96. retraction + $" if (_{uiNode.Name} == null) _{uiNode.Name} = new {uiNode.ClassName}({target}GetNode<{uiNode.TypeName}>(\"{uiNode.OriginName}\"));\n" +
  97. retraction + $" return _{uiNode.Name};\n" +
  98. retraction + $" }}\n" +
  99. retraction + $"}}\n" +
  100. retraction + $"private {uiNode.ClassName} _{uiNode.Name};\n\n";
  101. }
  102. private static UiNode EachNode(Node node)
  103. {
  104. var name = Regex.Replace(node.Name, "[^\\w_]", "");
  105. var uiNode = new UiNode("L_" + name, name, "UiNode" + (_nodeIndex++) + "_" + name, node.GetType().FullName);
  106.  
  107. var childCount = node.GetChildCount();
  108. if (childCount > 0)
  109. {
  110. for (var i = 0; i < childCount; i++)
  111. {
  112. var children = node.GetChild(i);
  113. if (children != null)
  114. {
  115. if (uiNode.Children == null)
  116. {
  117. uiNode.Children = new List<UiNode>();
  118. }
  119.  
  120. uiNode.Children.Add(EachNode(children));
  121. }
  122. }
  123. }
  124.  
  125. return uiNode;
  126. }
  127.  
  128. private class UiNode
  129. {
  130. public string Name;
  131. public string OriginName;
  132. public string ClassName;
  133. public string TypeName;
  134. public List<UiNode> Children;
  135.  
  136. public UiNode(string name, string originName, string className, string typeName)
  137. {
  138. Name = name;
  139. OriginName = originName;
  140. ClassName = className;
  141. TypeName = typeName;
  142. }
  143. }
  144. }