From 6a3447715c662861b06e263a20c579558059448b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Wed, 20 Sep 2023 22:21:42 +0200
Subject: [PATCH] vrclient: Split loading, parsing, and generating steps.

CW-Bug-Id: #22729
---
 vrclient_x64/gen_wrapper.py | 55 +++++++++++++++++++++++++++++++------
 1 file changed, 46 insertions(+), 9 deletions(-)

diff --git a/vrclient_x64/gen_wrapper.py b/vrclient_x64/gen_wrapper.py
index ccd9e75f..6689e32a 100755
--- a/vrclient_x64/gen_wrapper.py
+++ b/vrclient_x64/gen_wrapper.py
@@ -244,7 +244,12 @@ PATH_CONV = [
 struct_conversion_cache = {}
 struct_needs_size_adjustment_cache = {}
 
+all_records = {}
+all_sources = {}
+all_versions = {}
+
 class_versions = {}
+iface_versions = {}
 
 def get_params(f):
     return [p for p in f.get_children() if p.kind == CursorKind.PARM_DECL]
@@ -1362,13 +1367,12 @@ def parse(sources, abi):
     return build, structs
 
 
-prog = re.compile("^.*const\s*char.* \*?(\w*)_Version.*\"(.*)\"")
-for sdkver in SDK_VERSIONS:
-    print(f'parsing SDK version {sdkver}...')
+def load(sdkver):
+    prog = re.compile("^.*const\s*char.* \*?(\w*)_Version.*\"(.*)\"")
     sdkdir = f'openvr_{sdkver}'
 
     sources = {}
-    iface_versions = {}
+    versions = {}
     has_vrclientcore = False
     for file in os.listdir(sdkdir):
         x = open(f"{sdkdir}/{file}", "r")
@@ -1380,7 +1384,7 @@ for sdkver in SDK_VERSIONS:
                 result = prog.match(l)
                 if result:
                     iface, version = result.group(1, 2)
-                    iface_versions[iface] = version
+                    versions[iface] = version
 
     if not has_vrclientcore:
         source = [f'#include "{sdkdir}/openvr.h"']
@@ -1389,10 +1393,22 @@ for sdkver in SDK_VERSIONS:
                   for file in SDK_SOURCES.keys()]
     sources["source.cpp"] = "\n".join(source)
 
-    linux_build32, linux_structs32 = parse(sources, 'u32')
-    linux_build64, linux_structs64 = parse(sources, 'u64')
-    windows_build32, windows_structs32 = parse(sources, 'w32')
-    windows_build64, windows_structs64 = parse(sources, 'w64')
+    return versions, sources
+
+
+def generate(sdkver, records):
+    global linux_structs32
+    global linux_structs64
+    global windows_structs32
+    global windows_structs64
+    global iface_versions
+
+    print(f'generating SDK version {sdkver}...')
+    linux_build32, linux_structs32 = records['u32']
+    linux_build64, linux_structs64 = records['u64']
+    windows_build32, windows_structs32 = records['w32']
+    windows_build64, windows_structs64 = records['w64']
+    iface_versions = all_versions[sdkver]
 
     for child in enumerate_structs(linux_build32.cursor, vr_only=True):
         if child.kind == CursorKind.CLASS_DECL and child.displayname in SDK_CLASSES:
@@ -1400,6 +1416,27 @@ for sdkver in SDK_VERSIONS:
         if child.kind in [CursorKind.STRUCT_DECL, CursorKind.CLASS_DECL]:
             handle_struct(sdkver, child)
 
+
+for i, sdkver in enumerate(SDK_VERSIONS):
+    print(f'loading SDKs... {i * 100 // len(SDK_VERSIONS)}%', end='\r')
+    all_versions[sdkver], all_sources[sdkver] = load(sdkver)
+print(u'loading SDKs... 100%')
+
+for i, sdkver in enumerate(SDK_VERSIONS):
+    print(f'parsing SDKs... {i * 100 // len(SDK_VERSIONS)}%', end='\r')
+    sources = all_sources[sdkver]
+    records = {}
+    records['u32'] = parse(sources, 'u32')
+    records['u64'] = parse(sources, 'u64')
+    records['w32'] = parse(sources, 'w32')
+    records['w64'] = parse(sources, 'w64')
+    all_records[sdkver] = records
+print(u'parsing SDKs... 100%')
+
+for sdkver, records in all_records.items():
+    generate(sdkver, records)
+
+
 for f in cpp_files_need_close_brace:
     m = open(f, "a")
     m.write("\n}\n")