The open source OpenXR runtime

a/bindings: improve reproducibility of bindings generation

Signed-off-by: Sefa Eyeoglu <contact@scrumplex.net>
Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2338>

+17 -22
+16 -21
src/xrt/auxiliary/bindings/bindings.py
··· 7 7 import argparse 8 8 import json 9 9 import copy 10 - import itertools 11 - 10 + from operator import attrgetter 12 11 13 12 def find_component_in_list_by_name(name, component_list, subaction_path=None, identifier_json_path=None): 14 13 """Find a component with the given name in a list of components.""" ··· 124 123 Turn a Identifier's component paths into a list of Component objects. 125 124 """ 126 125 127 - monado_bindings = json_subpath["monado_bindings"] 128 126 component_list = [] 129 127 for component_name in json_subpath["components"]: # click, touch, ... 130 128 matched_dpad_emulation = None ··· 132 130 json_subpath["dpad_emulation"]["position"] == component_name): 133 131 matched_dpad_emulation = json_subpath["dpad_emulation"] 134 132 135 - monado_binding = None 136 - if component_name in monado_bindings: 137 - monado_binding = monado_bindings[component_name] 133 + monado_binding = json_subpath["monado_bindings"].get(component_name, None) 138 134 139 135 steamvr_path = steamvr_subpath_name(identifier_json_path, json_subpath["type"]) 140 136 if "steamvr_path" in json_subpath: ··· 224 220 225 221 identifier_list = [] 226 222 for subaction_path in json_subaction_paths: # /user/hand/* 227 - for json_sub_path_itm in json_subpaths.items(): # /input/*, /output/* 228 - json_path = json_sub_path_itm[0] # /input/trackpad 223 + for json_path in sorted(json_subpaths.keys()): # /input/*, /output/* 229 224 # json object associated with a subpath (type, localized_name, ...) 230 - json_subpath = json_sub_path_itm[1] 225 + json_subpath = json_subpaths[json_path] 231 226 232 227 # Oculus Touch a,b/x,y components only exist on one controller 233 228 if "side" in json_subpath and "/user/hand/" + json_subpath["side"] != subaction_path: ··· 370 365 def __update_component_list(self): 371 366 self.components = [] 372 367 for identifier in self.identifiers: 373 - for component in identifier.components: 374 - self.components.append(component) 368 + self.components += identifier.components 369 + self.components = sorted(self.components, key=attrgetter("steamvr_path")) 375 370 376 371 377 372 oxr_verify_extension_status_struct_name = "oxr_verify_extension_status" ··· 395 390 396 391 def __init__(self, json_root): 397 392 """Construct a bindings from a dictionary of profiles.""" 398 - self.profiles = [Profile(profile_name, json_profile) for 399 - profile_name, json_profile in json_root["profiles"].items()] 393 + self.profiles = [Profile(profile_name, json_root["profiles"][profile_name]) for 394 + profile_name in sorted(json_root["profiles"].keys())] 400 395 self.__set_parent_profile_refs() 401 396 self.__mine_for_diamond_errors() 402 397 ··· 422 417 if profile.name in parent_path_set: 423 418 return True 424 419 parent_path_set.append(profile.name) 425 - for parent in profile.parent_profiles: 420 + for parent in sorted(profile.parent_profiles, key=attrgetter("name")): 426 421 if self.__has_diamonds(parent, parent_path_set): 427 422 return True 428 423 return False ··· 468 463 Input is a file to write the code into, a dict where keys are length and 469 464 the values are lists of strings of that length. And a suffix if any.""" 470 465 f.write(f"{tab_char}\tswitch (length) {{\n") 471 - for length in dict_of_lists: 466 + for length in sorted(dict_of_lists.keys()): 472 467 f.write(f"{tab_char}\tcase {str(length)}:\n\t\t") 473 - for path in dict_of_lists[length]: 468 + for path in sorted(dict_of_lists[length]): 474 469 f.write(if_strcmp.format(exttab=tab_char, check=path)) 475 470 f.write(f"{tab_char}{{\n{tab_char}\t\t\tbreak;\n{tab_char}\t\t}}\n") 476 471 f.write(f"{tab_char}\tdefault: break;\n{tab_char}\t}}\n") ··· 514 509 profile, dict_name), profile, profile.name, profile.extension_name) 515 510 if profile.parent_profiles is None: 516 511 return 517 - for pp in profile.parent_profiles: 512 + for pp in sorted(profile.parent_profiles, key=attrgetter("name")): 518 513 write_verify_func_body(f, pp, dict_name) 519 514 520 515 ··· 722 717 f.write('{\n') 723 718 f.write('\tswitch(input)\n') 724 719 f.write('\t{\n') 725 - for input in inputs: 720 + for input in sorted(inputs): 726 721 f.write(f'\tcase {input}: return "{input}";\n') 727 722 f.write(f'\tdefault: return "UNKNOWN";\n') 728 723 f.write('\t}\n') ··· 731 726 f.write('enum xrt_input_name\n') 732 727 f.write('xrt_input_name_enum(const char *input)\n') 733 728 f.write('{\n') 734 - for input in inputs: 729 + for input in sorted(inputs): 735 730 f.write(f'\tif(strcmp("{input}", input) == 0) return {input};\n') 736 731 f.write(f'\treturn XRT_INPUT_GENERIC_TRACKER_POSE;\n') 737 732 f.write('}\n') ··· 741 736 f.write('{\n') 742 737 f.write('\tswitch(output)\n') 743 738 f.write('\t{\n') 744 - for output in outputs: 739 + for output in sorted(outputs): 745 740 f.write(f'\tcase {output}: return "{output}";\n') 746 741 f.write(f'\tdefault: return "UNKNOWN";\n') 747 742 f.write('\t}\n') ··· 750 745 f.write('enum xrt_output_name\n') 751 746 f.write('xrt_output_name_enum(const char *output)\n') 752 747 f.write('{\n') 753 - for output in outputs: 748 + for output in sorted(outputs): 754 749 f.write(f'\tif(strcmp("{output}", output) == 0) return {output};\n') 755 750 f.write(f'\treturn XRT_OUTPUT_NAME_SIMPLE_VIBRATION;\n') 756 751 f.write('}\n')
+1 -1
src/xrt/auxiliary/bindings/steamvr_profiles.py
··· 114 114 115 115 # print("Creating SteamVR input profile", f.name) 116 116 117 - json.dump(j, f, indent=2) 117 + json.dump(j, f, indent=2, sort_keys=True) 118 118 119 119 f.close() 120 120