# Copyright 2024 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from waflib import Task, TaskGen from resources.types.resource_ball import ResourceBall from resources.types.resource_definition import ResourceDefinition enum_header = ( """#pragma once // // AUTOGENERATED BY BUILD // DO NOT MODIFY - CHANGES WILL BE OVERWRITTEN // typedef enum { INVALID_RESOURCE = 0, RESOURCE_ID_INVALID = 0, DEFAULT_MENU_ICON = 0, """) define_header = ( """#pragma once // // AUTOGENERATED BY BUILD // DO NOT MODIFY - CHANGES WILL BE OVERWRITTEN // #define DEFAULT_MENU_ICON 0 """ ) extern_header = ( """#pragma once #include // // AUTOGENERATED BY BUILD // DO NOT MODIFY - CHANGES WILL BE OVERWRITTEN // """) definitions_file = ( """#include // // AUTOGENERATED BY BUILD // DO NOT MODIFY - CHANGES WILL BE OVERWRITTEN // """) @Task.update_outputs class generate_resource_id_header(Task.Task): def run(self): use_extern = getattr(self, 'use_extern', False) use_define = getattr(self, 'use_define', False) published_media = getattr(self, 'published_media', []) if use_extern: RESOURCE_ID_DECLARATION = "extern uint32_t RESOURCE_ID_{};" PUBLISHED_ID_DECLARATION = "extern uint32_t PUBLISHED_ID_{};" elif use_define: RESOURCE_ID_DECLARATION = "#define RESOURCE_ID_{} {}" PUBLISHED_ID_DECLARATION = "#define PUBLISHED_ID_{} {}" else: RESOURCE_ID_DECLARATION = " RESOURCE_ID_{} = {}," INVALID_RESOURCE_ID_DECLARATION = " RESOURCE_ID_{} = INVALID_RESOURCE," if published_media: self.generator.bld.fatal("publishedMedia is only supported for resource headers " "using externs and defines. Check your " "generate_resource_id_header arguments.") resource_ball = ResourceBall.load(self.inputs[0].abspath()) declarations_dict = {d.name: d for d in resource_ball.get_all_declarations()} self.outputs[0].parent.mkdir() with open(self.outputs[0].abspath(), 'w') as output_file: if use_extern: output_file.write(extern_header) elif use_define: output_file.write(define_header) else: output_file.write(enum_header) # Write out all the fonts and their aliases for i, declaration in enumerate(resource_ball.get_all_declarations(), start=1): output_file.write(RESOURCE_ID_DECLARATION.format(declaration.name, i) + "\n") if isinstance(declaration, ResourceDefinition): for alias in declaration.aliases: output_file.write(RESOURCE_ID_DECLARATION.format(alias, i) + " // alias\n") for item in published_media: output_file.write( PUBLISHED_ID_DECLARATION.format(item['name'], item['id'] or 0) + "\n") # Handle defining extended font ids for extended fonts that don't actually exist. # Every font should have a matching ID defined, but if the resource itself doesn't # exist we generate a fake ID for them. if not use_extern and not use_define: def write_invalid_id_if_needed(name): extended_name = name + '_EXTENDED' if extended_name not in declarations_dict: output_file.write(INVALID_RESOURCE_ID_DECLARATION.format(extended_name) + "\n") for o in resource_ball.resource_objects: if o.definition.type == 'font': write_invalid_id_if_needed(o.definition.name) for alias in o.definition.aliases: write_invalid_id_if_needed(alias) output_file.write('} ResourceId;') @Task.update_outputs class generate_resource_id_definitions(Task.Task): def run(self): RESOURCE_ID_DEFINITION = "uint32_t RESOURCE_ID_{} = {};" PUBLISHED_ID_DEFINITION = "uint32_t PUBLISHED_ID_{} = {};" resource_ball = ResourceBall.load(self.inputs[0].abspath()) published_media = getattr(self, 'published_media', []) self.outputs[0].parent.mkdir() with open(self.outputs[0].abspath(), 'w') as output_file: output_file.write(definitions_file) for i, declaration in enumerate(resource_ball.get_all_declarations(), start=1): output_file.write(RESOURCE_ID_DEFINITION.format(declaration.name, i) + "\n") if isinstance(declaration, ResourceDefinition): for alias in declaration.aliases: output_file.write(RESOURCE_ID_DEFINITION.format(alias, i) + " // alias\n") for item in published_media: output_file.write(PUBLISHED_ID_DEFINITION.format(item['name'], item['id'])) @TaskGen.feature('generate_resource_id_header') @TaskGen.before_method('process_source', 'process_rule') def process_generate_resource_id_header(self): task = self.create_task('generate_resource_id_header', self.resource_ball, self.resource_id_header_target) task.use_extern = getattr(self, 'use_extern', False) task.use_define = getattr(self, 'use_define', False) task.published_media = getattr(self, 'published_media', []) @TaskGen.feature('generate_resource_id_definitions') @TaskGen.before_method('process_source', 'process_rule') def generate_resource_id_definitions(self): task = self.create_task('generate_resource_id_definitions', self.resource_ball, self.resource_id_definitions_target) task.published_media = getattr(self, 'published_media', [])