generate_resource_id_header.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. # Copyright 2024 Google LLC
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. from waflib import Task, TaskGen
  15. from resources.types.resource_ball import ResourceBall
  16. from resources.types.resource_definition import ResourceDefinition
  17. enum_header = (
  18. """#pragma once
  19. //
  20. // AUTOGENERATED BY BUILD
  21. // DO NOT MODIFY - CHANGES WILL BE OVERWRITTEN
  22. //
  23. typedef enum {
  24. INVALID_RESOURCE = 0,
  25. RESOURCE_ID_INVALID = 0,
  26. DEFAULT_MENU_ICON = 0,
  27. """)
  28. define_header = (
  29. """#pragma once
  30. //
  31. // AUTOGENERATED BY BUILD
  32. // DO NOT MODIFY - CHANGES WILL BE OVERWRITTEN
  33. //
  34. #define DEFAULT_MENU_ICON 0
  35. """
  36. )
  37. extern_header = (
  38. """#pragma once
  39. #include <stdint.h>
  40. //
  41. // AUTOGENERATED BY BUILD
  42. // DO NOT MODIFY - CHANGES WILL BE OVERWRITTEN
  43. //
  44. """)
  45. definitions_file = (
  46. """#include <stdint.h>
  47. //
  48. // AUTOGENERATED BY BUILD
  49. // DO NOT MODIFY - CHANGES WILL BE OVERWRITTEN
  50. //
  51. """)
  52. class generate_resource_id_header(Task.Task):
  53. def run(self):
  54. use_extern = getattr(self, 'use_extern', False)
  55. use_define = getattr(self, 'use_define', False)
  56. published_media = getattr(self, 'published_media', [])
  57. if use_extern:
  58. RESOURCE_ID_DECLARATION = "extern uint32_t RESOURCE_ID_{};"
  59. PUBLISHED_ID_DECLARATION = "extern uint32_t PUBLISHED_ID_{};"
  60. elif use_define:
  61. RESOURCE_ID_DECLARATION = "#define RESOURCE_ID_{} {}"
  62. PUBLISHED_ID_DECLARATION = "#define PUBLISHED_ID_{} {}"
  63. else:
  64. RESOURCE_ID_DECLARATION = " RESOURCE_ID_{} = {},"
  65. INVALID_RESOURCE_ID_DECLARATION = " RESOURCE_ID_{} = INVALID_RESOURCE,"
  66. if published_media:
  67. self.generator.bld.fatal("publishedMedia is only supported for resource headers "
  68. "using externs and defines. Check your "
  69. "generate_resource_id_header arguments.")
  70. resource_ball = ResourceBall.load(self.inputs[0].abspath())
  71. declarations_dict = {d.name: d for d in resource_ball.get_all_declarations()}
  72. self.outputs[0].parent.mkdir()
  73. with open(self.outputs[0].abspath(), 'w') as output_file:
  74. if use_extern:
  75. output_file.write(extern_header)
  76. elif use_define:
  77. output_file.write(define_header)
  78. else:
  79. output_file.write(enum_header)
  80. # Write out all the fonts and their aliases
  81. for i, declaration in enumerate(resource_ball.get_all_declarations(), start=1):
  82. output_file.write(RESOURCE_ID_DECLARATION.format(declaration.name, i) + "\n")
  83. if isinstance(declaration, ResourceDefinition):
  84. for alias in declaration.aliases:
  85. output_file.write(RESOURCE_ID_DECLARATION.format(alias, i) + " // alias\n")
  86. for item in published_media:
  87. output_file.write(
  88. PUBLISHED_ID_DECLARATION.format(item['name'], item['id'] or 0) + "\n")
  89. # Handle defining extended font ids for extended fonts that don't actually exist.
  90. # Every font should have a matching ID defined, but if the resource itself doesn't
  91. # exist we generate a fake ID for them.
  92. if not use_extern and not use_define:
  93. def write_invalid_id_if_needed(name):
  94. extended_name = name + '_EXTENDED'
  95. if extended_name not in declarations_dict:
  96. output_file.write(INVALID_RESOURCE_ID_DECLARATION.format(extended_name) +
  97. "\n")
  98. for o in resource_ball.resource_objects:
  99. if o.definition.type == 'font':
  100. write_invalid_id_if_needed(o.definition.name)
  101. for alias in o.definition.aliases:
  102. write_invalid_id_if_needed(alias)
  103. output_file.write('} ResourceId;')
  104. class generate_resource_id_definitions(Task.Task):
  105. def run(self):
  106. RESOURCE_ID_DEFINITION = "uint32_t RESOURCE_ID_{} = {};"
  107. PUBLISHED_ID_DEFINITION = "uint32_t PUBLISHED_ID_{} = {};"
  108. resource_ball = ResourceBall.load(self.inputs[0].abspath())
  109. published_media = getattr(self, 'published_media', [])
  110. self.outputs[0].parent.mkdir()
  111. with open(self.outputs[0].abspath(), 'w') as output_file:
  112. output_file.write(definitions_file)
  113. for i, declaration in enumerate(resource_ball.get_all_declarations(), start=1):
  114. output_file.write(RESOURCE_ID_DEFINITION.format(declaration.name, i) + "\n")
  115. if isinstance(declaration, ResourceDefinition):
  116. for alias in declaration.aliases:
  117. output_file.write(RESOURCE_ID_DEFINITION.format(alias, i) + " // alias\n")
  118. for item in published_media:
  119. output_file.write(PUBLISHED_ID_DEFINITION.format(item['name'], item['id']))
  120. @TaskGen.feature('generate_resource_id_header')
  121. @TaskGen.before_method('process_source', 'process_rule')
  122. def process_generate_resource_id_header(self):
  123. task = self.create_task('generate_resource_id_header',
  124. self.resource_ball,
  125. self.resource_id_header_target)
  126. task.use_extern = getattr(self, 'use_extern', False)
  127. task.use_define = getattr(self, 'use_define', False)
  128. task.published_media = getattr(self, 'published_media', [])
  129. @TaskGen.feature('generate_resource_id_definitions')
  130. @TaskGen.before_method('process_source', 'process_rule')
  131. def generate_resource_id_definitions(self):
  132. task = self.create_task('generate_resource_id_definitions',
  133. self.resource_ball,
  134. self.resource_id_definitions_target)
  135. task.published_media = getattr(self, 'published_media', [])