template_builders.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. """Functions used to generate source files during build time
  2. All such functions are invoked in a subprocess on Windows to prevent build flakiness.
  3. """
  4. import os
  5. from io import StringIO
  6. from platform_methods import subprocess_main
  7. def parse_template(inherits, source, delimiter):
  8. script_template = {
  9. "inherits": inherits,
  10. "name": "",
  11. "description": "",
  12. "version": "",
  13. "script": "",
  14. "space-indent": "4",
  15. }
  16. meta_prefix = delimiter + " meta-"
  17. meta = ["name", "description", "version", "space-indent"]
  18. with open(source) as f:
  19. lines = f.readlines()
  20. for line in lines:
  21. if line.startswith(meta_prefix):
  22. line = line[len(meta_prefix) :]
  23. for m in meta:
  24. if line.startswith(m):
  25. strip_lenght = len(m) + 1
  26. script_template[m] = line[strip_lenght:].strip()
  27. else:
  28. script_template["script"] += line
  29. if script_template["space-indent"] != "":
  30. indent = " " * int(script_template["space-indent"])
  31. script_template["script"] = script_template["script"].replace(indent, "_TS_")
  32. if script_template["name"] == "":
  33. script_template["name"] = os.path.splitext(os.path.basename(source))[0].replace("_", " ").title()
  34. script_template["script"] = (
  35. script_template["script"].replace('"', '\\"').lstrip().replace("\n", "\\n").replace("\t", "_TS_")
  36. )
  37. return (
  38. '{ String("'
  39. + script_template["inherits"]
  40. + '"), String("'
  41. + script_template["name"]
  42. + '"), String("'
  43. + script_template["description"]
  44. + '"), String("'
  45. + script_template["script"]
  46. + '")'
  47. + " },\n"
  48. )
  49. def make_templates(target, source, env):
  50. dst = target[0]
  51. s = StringIO()
  52. s.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n\n")
  53. s.write("#ifndef _CODE_TEMPLATES_H\n")
  54. s.write("#define _CODE_TEMPLATES_H\n\n")
  55. s.write('#include "core/object/object.h"\n')
  56. s.write('#include "core/object/script_language.h"\n')
  57. delimiter = "#" # GDScript single line comment delimiter by default.
  58. if source:
  59. ext = os.path.splitext(source[0])[1]
  60. if ext == ".cs":
  61. delimiter = "//"
  62. parsed_template_string = ""
  63. number_of_templates = 0
  64. for filepath in source:
  65. node_name = os.path.basename(os.path.dirname(filepath))
  66. parsed_template = parse_template(node_name, filepath, delimiter)
  67. parsed_template_string += "\t" + parsed_template
  68. number_of_templates += 1
  69. s.write("\nstatic const int TEMPLATES_ARRAY_SIZE = " + str(number_of_templates) + ";\n")
  70. s.write("\nstatic const struct ScriptLanguage::ScriptTemplate TEMPLATES[" + str(number_of_templates) + "] = {\n")
  71. s.write(parsed_template_string)
  72. s.write("};\n")
  73. s.write("\n#endif\n")
  74. with open(dst, "w") as f:
  75. f.write(s.getvalue())
  76. s.close()
  77. if __name__ == "__main__":
  78. subprocess_main(globals())