pebble/tools/resources/waftools/generate_resource_id_header.py
2025-01-27 11:38:16 -08:00

177 lines
6.3 KiB
Python

# 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 <stdint.h>
//
// AUTOGENERATED BY BUILD
// DO NOT MODIFY - CHANGES WILL BE OVERWRITTEN
//
""")
definitions_file = (
"""#include <stdint.h>
//
// 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', [])