A stable modding interface between Techblox and mods https://mod.exmods.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
3.9KB

  1. using System.CodeDom;
  2. using System.CodeDom.Compiler;
  3. using System.IO;
  4. using System.Linq;
  5. using RobocraftX.Common;
  6. using Svelto.ECS;
  7. using Techblox.EngineBlock;
  8. namespace CodeGenerator
  9. {
  10. public class BlockClassGenerator
  11. {
  12. public void Generate(string name, string group)
  13. {
  14. if (group is null)
  15. {
  16. group = GetGroup(name) + "_BLOCK_GROUP";
  17. if (typeof(CommonExclusiveGroups).GetFields().All(field => field.Name != group))
  18. group = GetGroup(name) + "_BLOCK_BUILD_GROUP";
  19. }
  20. var codeUnit = new CodeCompileUnit();
  21. var ns = new CodeNamespace("TechbloxModdingAPI.Blocks");
  22. ns.Imports.Add(new CodeNamespaceImport("RobocraftX.Common"));
  23. ns.Imports.Add(new CodeNamespaceImport("Svelto.ECS"));
  24. var cl = new CodeTypeDeclaration(name);
  25. cl.BaseTypes.Add(new CodeTypeReference("Block"));
  26. cl.Members.Add(new CodeConstructor
  27. {
  28. Parameters = {new CodeParameterDeclarationExpression("EGID", "egid")},
  29. Comments = {new CodeCommentStatement($"{name} constructor", true)},
  30. BaseConstructorArgs = {new CodeVariableReferenceExpression("egid")}
  31. });
  32. cl.Members.Add(new CodeConstructor
  33. {
  34. Parameters =
  35. {
  36. new CodeParameterDeclarationExpression(typeof(uint), "id")
  37. },
  38. Comments = {new CodeCommentStatement($"{name} constructor", true)},
  39. BaseConstructorArgs =
  40. {
  41. new CodeObjectCreateExpression("EGID", new CodeVariableReferenceExpression("id"),
  42. new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("CommonExclusiveGroups"),
  43. group))
  44. }
  45. });
  46. GenerateProperties<EngineBlockComponent>(cl);
  47. ns.Types.Add(cl);
  48. codeUnit.Namespaces.Add(ns);
  49. var provider = CodeDomProvider.CreateProvider("CSharp");
  50. using (var sw = new StreamWriter($"{name}.cs"))
  51. {
  52. provider.GenerateCodeFromCompileUnit(codeUnit, sw, new CodeGeneratorOptions {BracingStyle = "C"});
  53. }
  54. }
  55. private static string GetGroup(string name)
  56. {
  57. var ret = "";
  58. foreach (var ch in name)
  59. {
  60. if (char.IsUpper(ch) && ret.Length > 0)
  61. ret += "_" + ch;
  62. else
  63. ret += char.ToUpper(ch);
  64. }
  65. return ret;
  66. }
  67. private void GenerateProperties<T>(CodeTypeDeclaration cl) where T : IEntityComponent
  68. {
  69. var type = typeof(T);
  70. foreach (var field in type.GetFields())
  71. {
  72. var propName = char.ToUpper(field.Name[0]) + field.Name.Substring(1);
  73. var structFieldReference = new CodeFieldReferenceExpression(new CodeMethodInvokeExpression(
  74. new CodeMethodReferenceExpression(new CodeSnippetExpression("BlockEngine"),
  75. "GetBlockInfo", new CodeTypeReference(type)),
  76. new CodeThisReferenceExpression()), field.Name);
  77. cl.Members.Add(new CodeMemberProperty
  78. {
  79. Name = propName,
  80. HasGet = true,
  81. HasSet = true,
  82. GetStatements =
  83. {
  84. new CodeMethodReturnStatement(structFieldReference)
  85. },
  86. SetStatements =
  87. {
  88. new CodeAssignStatement(structFieldReference, new CodePropertySetValueReferenceExpression())
  89. },
  90. Type = new CodeTypeReference(field.FieldType)
  91. });
  92. }
  93. }
  94. }
  95. }