Skip to content

Commit d5ea266

Browse files
committed
Replace fixed-length lists with tuples
1 parent 8eef1da commit d5ea266

File tree

6 files changed

+159
-52
lines changed

6 files changed

+159
-52
lines changed

src/genieutils/common.py

Lines changed: 113 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from abc import ABC
22
from enum import IntEnum
3-
from typing import TypeVar
3+
from typing import TypeVar, Sequence
44

55
from genieutils.datatypes import Int, Float, String
66

@@ -45,25 +45,25 @@ def write_string(self, length: int, value: str) -> bytes:
4545
def write_int_8(self, value: int) -> bytes:
4646
return Int.to_bytes(value, length=1, signed=False)
4747

48-
def write_int_8_array(self, value: list[int]) -> bytes:
48+
def write_int_8_array(self, value: Sequence[int]) -> bytes:
4949
return b''.join(self.write_int_8(v) for v in value)
5050

5151
def write_int_16(self, value: int, signed=True) -> bytes:
5252
return Int.to_bytes(value, length=2, signed=signed)
5353

54-
def write_int_16_array(self, value: list[int]) -> bytes:
54+
def write_int_16_array(self, value: Sequence[int]) -> bytes:
5555
return b''.join(self.write_int_16(v) for v in value)
5656

5757
def write_int_32(self, value: int, signed=True) -> bytes:
5858
return Int.to_bytes(value, length=4, signed=signed)
5959

60-
def write_int_32_array(self, value: list[int]) -> bytes:
60+
def write_int_32_array(self, value: Sequence[int]) -> bytes:
6161
return b''.join(self.write_int_32(v) for v in value)
6262

6363
def write_float(self, value: float) -> bytes:
6464
return Float.to_bytes(value)
6565

66-
def write_float_array(self, value: list[float]) -> bytes:
66+
def write_float_array(self, value: Sequence[float]) -> bytes:
6767
return b''.join(self.write_float(v) for v in value)
6868

6969
def write_class(self, value: 'GenieClass') -> bytes:
@@ -72,7 +72,7 @@ def write_class(self, value: 'GenieClass') -> bytes:
7272
return retval
7373
return b''
7474

75-
def write_class_array(self, value: list['GenieClass']) -> bytes:
75+
def write_class_array(self, value: Sequence['GenieClass']) -> bytes:
7676
retval = b''.join(self.write_class(v) for v in value)
7777
if retval:
7878
return retval
@@ -117,6 +117,48 @@ def read_int_8_array(self, size: int) -> list[int]:
117117
elements.append(self.read_int_8())
118118
return elements
119119

120+
def read_int_8_array_2(self) -> tuple[int, int]:
121+
element_0 = self.read_int_8()
122+
element_1 = self.read_int_8()
123+
return element_0, element_1
124+
125+
def read_int_8_array_3(self) -> tuple[int, int, int]:
126+
element_0 = self.read_int_8()
127+
element_1 = self.read_int_8()
128+
element_2 = self.read_int_8()
129+
return element_0, element_1, element_2
130+
131+
def read_int_8_array_5(self) -> tuple[int, int, int, int, int]:
132+
element_0 = self.read_int_8()
133+
element_1 = self.read_int_8()
134+
element_2 = self.read_int_8()
135+
element_3 = self.read_int_8()
136+
element_4 = self.read_int_8()
137+
return element_0, element_1, element_2, element_3, element_4
138+
139+
def read_int_8_array_6(self) -> tuple[int, int, int, int, int, int]:
140+
element_0 = self.read_int_8()
141+
element_1 = self.read_int_8()
142+
element_2 = self.read_int_8()
143+
element_3 = self.read_int_8()
144+
element_4 = self.read_int_8()
145+
element_5 = self.read_int_8()
146+
return element_0, element_1, element_2, element_3, element_4, element_5
147+
148+
def read_int_8_array_10(self) -> tuple[int, int, int, int, int, int, int, int, int, int]:
149+
element_0 = self.read_int_8()
150+
element_1 = self.read_int_8()
151+
element_2 = self.read_int_8()
152+
element_3 = self.read_int_8()
153+
element_4 = self.read_int_8()
154+
element_5 = self.read_int_8()
155+
element_6 = self.read_int_8()
156+
element_7 = self.read_int_8()
157+
element_8 = self.read_int_8()
158+
element_9 = self.read_int_8()
159+
return (element_0, element_1, element_2, element_3, element_4, element_5, element_6, element_7, element_8,
160+
element_9)
161+
120162
def read_int_16(self, signed=True) -> int:
121163
return Int.from_bytes(self.consume_range(2), signed=signed)
122164

@@ -126,6 +168,33 @@ def read_int_16_array(self, size: int) -> list[int]:
126168
elements.append(self.read_int_16())
127169
return elements
128170

171+
def read_int_16_array_2(self) -> tuple[int, int]:
172+
element_0 = self.read_int_16()
173+
element_1 = self.read_int_16()
174+
return element_0, element_1
175+
176+
def read_int_16_array_3(self) -> tuple[int, int, int]:
177+
element_0 = self.read_int_16()
178+
element_1 = self.read_int_16()
179+
element_2 = self.read_int_16()
180+
return element_0, element_1, element_2
181+
182+
def read_int_16_array_4(self) -> tuple[int, int, int, int]:
183+
element_0 = self.read_int_16()
184+
element_1 = self.read_int_16()
185+
element_2 = self.read_int_16()
186+
element_3 = self.read_int_16()
187+
return element_0, element_1, element_2, element_3
188+
189+
def read_int_16_array_6(self) -> tuple[int, int, int, int, int, int]:
190+
element_0 = self.read_int_16()
191+
element_1 = self.read_int_16()
192+
element_2 = self.read_int_16()
193+
element_3 = self.read_int_16()
194+
element_4 = self.read_int_16()
195+
element_5 = self.read_int_16()
196+
return element_0, element_1, element_2, element_3, element_4, element_5
197+
129198
def read_int_32(self, signed=True) -> int:
130199
return Int.from_bytes(self.consume_range(4), signed=signed)
131200

@@ -135,6 +204,20 @@ def read_int_32_array(self, size: int) -> list[int]:
135204
elements.append(self.read_int_32())
136205
return elements
137206

207+
def read_int_32_array_10(self) -> tuple[int, int, int, int, int, int, int, int, int, int]:
208+
element_0 = self.read_int_32()
209+
element_1 = self.read_int_32()
210+
element_2 = self.read_int_32()
211+
element_3 = self.read_int_32()
212+
element_4 = self.read_int_32()
213+
element_5 = self.read_int_32()
214+
element_6 = self.read_int_32()
215+
element_7 = self.read_int_32()
216+
element_8 = self.read_int_32()
217+
element_9 = self.read_int_32()
218+
return (element_0, element_1, element_2, element_3, element_4, element_5, element_6, element_7, element_8,
219+
element_9)
220+
138221
def read_float(self) -> float:
139222
return Float.from_bytes(self.consume_range(4))
140223

@@ -144,6 +227,17 @@ def read_float_array(self, size: int) -> list[float]:
144227
elements.append(self.read_float())
145228
return elements
146229

230+
def read_float_array_2(self) -> tuple[float, float]:
231+
element_0 = self.read_float()
232+
element_1 = self.read_float()
233+
return element_0, element_1
234+
235+
def read_float_array_3(self) -> tuple[float, float, float]:
236+
element_0 = self.read_float()
237+
element_1 = self.read_float()
238+
element_2 = self.read_float()
239+
return element_0, element_1, element_2
240+
147241
def read_class(self, class_: type[C]) -> C:
148242
element = class_.from_bytes(self)
149243
return element
@@ -155,6 +249,19 @@ def read_class_array(self, class_: type[C], size: int) -> list[C]:
155249
elements.append(element)
156250
return elements
157251

252+
def read_class_array_3(self, class_: type[C]) -> tuple[C, C, C]:
253+
element_0 = class_.from_bytes(self)
254+
element_1 = class_.from_bytes(self)
255+
element_2 = class_.from_bytes(self)
256+
return element_0, element_1, element_2
257+
258+
def read_class_array_4(self, class_: type[C]) -> tuple[C, C, C, C]:
259+
element_0 = class_.from_bytes(self)
260+
element_1 = class_.from_bytes(self)
261+
element_2 = class_.from_bytes(self)
262+
element_3 = class_.from_bytes(self)
263+
return element_0, element_1, element_2, element_3
264+
158265
def read_class_array_with_pointers(self, class_: type[C], size: int, pointers: list[int]) -> list[C | None]:
159266
elements = []
160267
for i in range(size):

src/genieutils/graphic.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class Graphic(GenieClass):
8888
layer: int
8989
player_color: int
9090
transparent_selection: int
91-
coordinates: list[int]
91+
coordinates: tuple[int, int, int, int]
9292
delta_count: int
9393
sound_id: int
9494
wwise_sound_id: int
@@ -116,7 +116,7 @@ def from_bytes(cls, content: ByteHandler) -> 'Graphic':
116116
layer = content.read_int_8()
117117
player_color = content.read_int_16()
118118
transparent_selection = content.read_int_8()
119-
coordinates = content.read_int_16_array(4)
119+
coordinates = content.read_int_16_array_4()
120120
delta_count = content.read_int_16()
121121
sound_id = content.read_int_16()
122122
wwise_sound_id = content.read_int_32()

src/genieutils/tech.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ def to_bytes(self) -> bytes:
2727

2828
@dataclass
2929
class Tech(GenieClass):
30-
required_techs: list[int]
31-
resource_costs: list[ResearchResourceCost]
30+
required_techs: tuple[int, int, int, int, int, int]
31+
resource_costs: tuple[ResearchResourceCost, ResearchResourceCost, ResearchResourceCost]
3232
required_tech_count: int
3333
civ: int
3434
full_tech_mode: int
@@ -49,8 +49,8 @@ class Tech(GenieClass):
4949
@classmethod
5050
def from_bytes(cls, content: ByteHandler) -> 'Tech':
5151
return cls(
52-
required_techs=content.read_int_16_array(6),
53-
resource_costs=content.read_class_array(ResearchResourceCost, 3),
52+
required_techs=content.read_int_16_array_6(),
53+
resource_costs=content.read_class_array_3(ResearchResourceCost),
5454
required_tech_count=content.read_int_16(),
5555
civ=content.read_int_16(),
5656
full_tech_mode=content.read_int_16(),

src/genieutils/techtree.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
@dataclass
77
class Common(GenieClass):
88
slots_used: int
9-
unit_research: list[int]
10-
mode: list[int]
9+
unit_research: tuple[int, int, int, int, int, int, int, int, int, int]
10+
mode: tuple[int, int, int, int, int, int, int, int, int, int]
1111

1212
@classmethod
1313
def from_bytes(cls, content: ByteHandler) -> 'Common':
1414
return cls(
1515
slots_used=content.read_int_32(),
16-
unit_research=content.read_int_32_array(10),
17-
mode=content.read_int_32_array(10),
16+
unit_research=content.read_int_32_array_10(),
17+
mode=content.read_int_32_array_10(),
1818
)
1919

2020
def to_bytes(self) -> bytes:
@@ -37,8 +37,8 @@ class TechTreeAge(GenieClass):
3737
techs: list[int]
3838
common: Common
3939
num_building_levels: int
40-
buildings_per_zone: list[int]
41-
group_length_per_zone: list[int]
40+
buildings_per_zone: tuple[int, int, int, int, int, int, int, int, int, int]
41+
group_length_per_zone: tuple[int, int, int, int, int, int, int, int, int, int]
4242
max_age_length: int
4343
line_mode: int
4444

@@ -54,8 +54,8 @@ def from_bytes(cls, content: ByteHandler) -> 'TechTreeAge':
5454
techs = content.read_int_32_array(techs_count)
5555
common = content.read_class(Common)
5656
num_building_levels = content.read_int_8()
57-
buildings_per_zone = content.read_int_8_array(10)
58-
group_length_per_zone = content.read_int_8_array(10)
57+
buildings_per_zone = content.read_int_8_array_10()
58+
group_length_per_zone = content.read_int_8_array_10()
5959
max_age_length = content.read_int_8()
6060
line_mode = content.read_int_32()
6161
return cls(
@@ -106,8 +106,8 @@ class BuildingConnection(GenieClass):
106106
techs: list[int]
107107
common: Common
108108
location_in_age: int
109-
units_techs_total: list[int]
110-
units_techs_first: list[int]
109+
units_techs_total: tuple[int, int, int, int, int]
110+
units_techs_first: tuple[int, int, int, int, int]
111111
line_mode: int
112112
enabling_research: int
113113

@@ -123,8 +123,8 @@ def from_bytes(cls, content: ByteHandler) -> 'BuildingConnection':
123123
techs = content.read_int_32_array(techs_count)
124124
common = content.read_class(Common)
125125
location_in_age = content.read_int_8()
126-
units_techs_total = content.read_int_8_array(5)
127-
units_techs_first = content.read_int_8_array(5)
126+
units_techs_total = content.read_int_8_array_5()
127+
units_techs_first = content.read_int_8_array_5()
128128
line_mode = content.read_int_32()
129129
enabling_research = content.read_int_32()
130130
return cls(

src/genieutils/terrainblock.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ class Terrain(GenieClass):
4242
blend_priority: int
4343
blend_type: int
4444
overlay_mask_name: str
45-
colors: list[int]
46-
cliff_colors: list[int]
45+
colors: tuple[int, int, int]
46+
cliff_colors: tuple[int, int]
4747
passable_terrain: int
4848
impassable_terrain: int
4949
is_animated: int
@@ -58,7 +58,7 @@ class Terrain(GenieClass):
5858
drawn: int
5959
frame_data: list[FrameData]
6060
terrain_to_draw: int
61-
terrain_dimensions: list[int]
61+
terrain_dimensions: tuple[int, int]
6262
terrain_unit_masked_density: list[int]
6363
terrain_unit_id: list[int]
6464
terrain_unit_density: list[int]
@@ -84,8 +84,8 @@ def from_bytes(cls, content: ByteHandler) -> 'Terrain':
8484
blend_priority=content.read_int_32(),
8585
blend_type=content.read_int_32(),
8686
overlay_mask_name=content.read_debug_string(),
87-
colors=content.read_int_8_array(3),
88-
cliff_colors=content.read_int_8_array(2),
87+
colors=content.read_int_8_array_3(),
88+
cliff_colors=content.read_int_8_array_2(),
8989
passable_terrain=content.read_int_8(),
9090
impassable_terrain=content.read_int_8(),
9191
is_animated=content.read_int_8(),
@@ -100,7 +100,7 @@ def from_bytes(cls, content: ByteHandler) -> 'Terrain':
100100
drawn=content.read_int_8(),
101101
frame_data=content.read_class_array(FrameData, TILE_TYPE_COUNT),
102102
terrain_to_draw=content.read_int_16(),
103-
terrain_dimensions=content.read_int_16_array(2),
103+
terrain_dimensions=content.read_int_16_array_2(),
104104
terrain_unit_masked_density=content.read_int_16_array(TERRAIN_UNITS_SIZE),
105105
terrain_unit_id=content.read_int_16_array(TERRAIN_UNITS_SIZE),
106106
terrain_unit_density=content.read_int_16_array(TERRAIN_UNITS_SIZE),

0 commit comments

Comments
 (0)