Skip to content

Commit 3b57f20

Browse files
committed
astructs: lazy creation of fields
based on a patch submitted by @reinauer in #227
1 parent 567dc0f commit 3b57f20

1 file changed

Lines changed: 27 additions & 11 deletions

File tree

amitools/vamos/astructs/astruct.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -217,31 +217,47 @@ class AmigaStructFields:
217217
def __init__(self, astruct):
218218
self.astruct = astruct
219219
self.sdef = astruct.sdef
220-
self._fields = []
221-
self._name_to_field = {}
222-
for field_def in self.sdef.get_field_defs():
223-
field = self._create_field_type(field_def)
224-
self._fields.append(field)
225-
self._name_to_field[field_def.name] = field
220+
self._field_defs = list(self.sdef.get_field_defs())
221+
self._fields = [None] * len(self._field_defs) # Lazy placeholders
222+
self._name_to_field = {} # Populated lazily
223+
224+
def _ensure_field(self, index):
225+
"""Create field at index if not already created."""
226+
if self._fields[index] is None:
227+
field_def = self._field_defs[index]
228+
self._fields[index] = self._create_field_type(field_def)
229+
self._name_to_field[field_def.name] = self._fields[index]
230+
return self._fields[index]
226231

227232
def get_fields(self):
228233
"""return all field instances"""
234+
# Force creation of all fields
235+
for i in range(len(self._field_defs)):
236+
self._ensure_field(i)
229237
return self._fields
230238

231239
def get_field_by_index(self, index):
232240
"""return the type instance associated with the field"""
233-
return self._fields[index]
241+
return self._ensure_field(index)
234242

235243
def get_field_by_name(self, name):
236-
return self._name_to_field.get(name)
244+
# Check cache first
245+
field = self._name_to_field.get(name)
246+
if field is not None:
247+
return field
248+
# Find field def by name and create lazily
249+
field_def = self.sdef.find_field_def_by_name(name)
250+
if field_def is None:
251+
return None
252+
return self._ensure_field(field_def.index)
237253

238254
def get_field_by_name_or_alias(self, name, subfield_aliases=None):
239-
field = self._name_to_field.get(name)
255+
field = self.get_field_by_name(name)
240256
if field is None:
241257
# alias name
242258
alias_name = self.sdef.get_alias_name(name)
243259
if alias_name:
244-
field = self._name_to_field.get(alias_name)
260+
field = self.get_field_by_name(alias_name)
245261
# subfield alias
246262
if field is None and subfield_aliases:
247263
field_def_path = subfield_aliases.get(name)
@@ -254,7 +270,7 @@ def find_field_by_offset(self, offset):
254270
field_def, delta = self.sdef.find_field_def_by_offset(offset)
255271
if not field_def:
256272
return None, 0
257-
return self._fields[field_def.index], delta
273+
return self._ensure_field(field_def.index), delta
258274

259275
def find_sub_fields_by_offset(self, base_offset):
260276
"""return [fields], delta or None, 0"""

0 commit comments

Comments
 (0)