File indexing completed on 2024-05-19 15:25:46

0001 #!/usr/bin/env python3
0002 # SPDX-FileCopyrightText: 2019-2023 Mattia Basaglia <dev@dragon.best>
0003 # SPDX-License-Identifier: GPL-3.0-or-later
0004 import json
0005 import pathlib
0006 import argparse
0007 
0008 
0009 type_map = {
0010     "double":   "Float",
0011     "Id":       "VarUint",
0012     "String":   "String",
0013     "uint":     "VarUint",
0014     "Bytes":    "Bytes",
0015     "bool":     "Bool",
0016     "Color":    "Color"
0017 }
0018 
0019 def load_dir(path, data, types, props, relpath = pathlib.Path()):
0020     for item in path.iterdir():
0021         if item.is_dir():
0022             load_dir(item, data, types, props, relpath / item.name)
0023         elif item.suffix == ".json":
0024             load_file(item, data, types, props, relpath / item.name)
0025 
0026 
0027 def load_prop(name, pdef, props):
0028     id = pdef["key"]["int"]
0029     if props.get(id, name) != name:
0030         raise Exception("Mismatching prop %s %s %s" % (id, name, props[name]))
0031 
0032     props[id] = name
0033     return {
0034         "id": id,
0035         "name": name,
0036         "type": type_map[pdef["type"]]
0037     }
0038 
0039 def load_file(path, data, types, props, relpath):
0040     with open(path) as f:
0041         definition = json.load(f)
0042 
0043     id = definition["key"]["int"]
0044     data.append({
0045         "id": id,
0046         "extends": definition.get("extends"),
0047         "name": definition["name"],
0048         "properties": [
0049             load_prop(name, pdef, props)
0050             for name, pdef in definition.get("properties", {}).items()
0051             if pdef.get("runtime", True)
0052         ]
0053     })
0054     types[str(relpath)] = definition["name"]
0055 
0056 def fix_extends(data, types):
0057     for item in data:
0058         if item["extends"] is not None:
0059             item["extends"] = types[item["extends"]]
0060         else:
0061             item["extends"] = "NoType"
0062 
0063 
0064 def format_props(props):
0065     indent = " " * 16
0066     return "".join(
0067         "\n%(indent)s{%(name)r, %(id)d, PropertyType::%(type)s}," % dict(
0068             indent=indent,
0069             **prop
0070         )
0071         for prop in props
0072     )
0073 
0074 def disclaimer(cmd):
0075     print("""/**
0076  * NOTE: This file is generated automatically, do not edit manually
0077  * To generate this file run
0078  *       %s
0079  */
0080 """ % cmd)
0081 
0082 parser = argparse.ArgumentParser()
0083 parser.add_argument("--defs", type=pathlib.Path, default=pathlib.Path.home() / "src/rive-cpp/dev/defs/")
0084 parser.add_argument("--type", "-t", choices=["source", "ids"], default="source")
0085 args = parser.parse_args()
0086 
0087 
0088 data = []
0089 types = {}
0090 props = {}
0091 rive_def_root = args.defs
0092 load_dir(rive_def_root, data, types, props)
0093 data = sorted(data, key=lambda o: o["id"])
0094 
0095 if args.type == "source":
0096     fix_extends(data, types)
0097     disclaimer("./external/rive_typedef.py -t source >src/core/io/rive/type_def.cpp")
0098     print("""
0099 #include "type_def.hpp"
0100 
0101 using namespace glaxnimate::io::rive;
0102 
0103 std::unordered_map<TypeId, ObjectDefinition> glaxnimate::io::rive::defined_objects = {""")
0104     for obj in data:
0105         print(("""    {
0106         TypeId::%(name)s, {
0107             %(name)r, TypeId::%(name)s,
0108             TypeId::%(extends)s, {%(property_str)s
0109             }
0110         }
0111     },""" % dict(property_str=format_props(obj["properties"]), **obj)
0112         ).replace("'", '"'))
0113     print("};")
0114 elif args.type == "ids":
0115     print("#pragma once")
0116     disclaimer("./external/rive_typedef.py -t ids >src/core/io/rive/type_ids.hpp")
0117     print("namespace glaxnimate::io::rive {\nenum class TypeId {")
0118     print("    NoType = 0,")
0119     for obj in data:
0120         print("    %(name)s = %(id)d," % obj)
0121     #print("};\n")
0122     #print("enum class PropId {")
0123     #for id, name in sorted(props.items()):
0124         #print("    %(name)s = %(id)d," % {"id": id, "name": name})
0125     print("};\n} // namespace glaxnimate::io::rive")