vrclient: Use Struct and Field class for conversions.

CW-Bug-Id: #22729
This commit is contained in:
Rémi Bernon 2023-09-28 14:49:12 +02:00
parent 683d7bd14e
commit b0aa728ca4

View File

@ -208,9 +208,6 @@ PATH_CONV_METHODS_WTOU = {
# TODO: LaunchInternalProcess, need steam cooperation # TODO: LaunchInternalProcess, need steam cooperation
} }
struct_conversion_cache = {}
struct_needs_size_adjustment_cache = {}
all_classes = {} all_classes = {}
all_records = {} all_records = {}
all_structs = {} all_structs = {}
@ -285,12 +282,14 @@ class Struct:
self._sdkver = sdkver self._sdkver = sdkver
self._abi = abi self._abi = abi
self._fields = None self._fields = None
self._conv_cache = {}
self.name = canonical_typename(self._cursor) self.name = canonical_typename(self._cursor)
self.name = self.name.removeprefix("vr::") self.name = self.name.removeprefix("vr::")
self.type = self._cursor.type.get_canonical() self.type = self._cursor.type.get_canonical()
self.size = self.type.get_size() self.size = self.type.get_size()
self.align = self.type.get_align() self.align = self.type.get_align()
self.id = f'{abi}_{self.name}_{sdkver}'
@property @property
def padded_fields(self): def padded_fields(self):
@ -325,6 +324,10 @@ class Struct:
return [f for f in self.padded_fields if type(f) is not Padding] return [f for f in self.padded_fields if type(f) is not Padding]
def needs_conversion(self, other): def needs_conversion(self, other):
if other.id in self._conv_cache:
return self._conv_cache[other.id]
self._conv_cache[other.id] = other._conv_cache[self.id] = True
if self.name in SIZED_STRUCTS and self.size != other.size: if self.name in SIZED_STRUCTS and self.size != other.size:
return True return True
if len(self.fields) != len(other.fields): if len(self.fields) != len(other.fields):
@ -333,6 +336,7 @@ class Struct:
for a, b in zip(self.fields, other.fields)]): for a, b in zip(self.fields, other.fields)]):
return True return True
self._conv_cache[other.id] = other._conv_cache[self.id] = False
return False return False
def get_children(self): def get_children(self):
@ -943,46 +947,49 @@ def find_struct_abis(name):
return structs[sdkver] return structs[sdkver]
def struct_needs_conversion_nocache(struct): def struct_needs_conversion(struct):
name = canonical_typename(struct) name = canonical_typename(struct)
abis = find_struct_abis(name) abis = find_struct_abis(name)
if abis is None: if abis is None:
return False, False return False
if abis['w32'].needs_conversion(abis['u32']): if abis['w32'].needs_conversion(abis['u32']):
return True, False return True
if abis['w64'].needs_conversion(abis['u64']): if abis['w64'].needs_conversion(abis['u64']):
return True, False return True
assert abis['u32'].size <= abis['w32'].size assert abis['u32'].size <= abis['w32'].size
if abis['u32'].size < abis['w32'].size: if abis['u32'].size < abis['w32'].size:
return False, True return False
assert abis['u64'].size <= abis['w64'].size assert abis['u64'].size <= abis['w64'].size
if abis['u64'].size < abis['w64'].size: if abis['u64'].size < abis['w64'].size:
return False, True return False
return False, False return False
def struct_needs_conversion(struct): def struct_needs_size_adjustment(struct):
name = canonical_typename(struct) name = canonical_typename(struct)
if name in EXEMPT_STRUCTS: if name in EXEMPT_STRUCTS:
return False return False
if not sdkver in struct_conversion_cache: abis = find_struct_abis(name)
struct_conversion_cache[sdkver] = {} if abis is None:
struct_needs_size_adjustment_cache[sdkver] = {} return False
if abis['w32'].needs_conversion(abis['u32']):
return False
if abis['w64'].needs_conversion(abis['u64']):
return False
if not name in struct_conversion_cache[sdkver]: assert abis['u32'].size <= abis['w32'].size
struct_conversion_cache[sdkver][name], \ if abis['u32'].size < abis['w32'].size:
struct_needs_size_adjustment_cache[sdkver][name] = \ return True
struct_needs_conversion_nocache(struct) assert abis['u64'].size <= abis['w64'].size
if abis['u64'].size < abis['w64'].size:
return True
return struct_conversion_cache[sdkver][name] return False
def struct_needs_size_adjustment(struct):
name = canonical_typename(struct)
return not struct_needs_conversion(struct) and struct_needs_size_adjustment_cache[sdkver][name]
def get_field_attribute_str(field): def get_field_attribute_str(field):
ftype = field.type.get_canonical() ftype = field.type.get_canonical()