Skip to content

Commit

Permalink
Merge pull request #212 from randovania/feature/speed-up-tests
Browse files Browse the repository at this point in the history
Speedup parsing/building BCSKLA and BMSAS
  • Loading branch information
henriquegemignani committed Sep 8, 2024
2 parents bb88289 + 5f5f887 commit 6b6a4b9
Show file tree
Hide file tree
Showing 14 changed files with 57 additions and 51 deletions.
45 changes: 20 additions & 25 deletions src/mercury_engine_data_structures/formats/bcskla.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from enum import Enum

import construct
from construct.core import (
Adapter,
Expand All @@ -22,50 +20,47 @@
this,
)

from mercury_engine_data_structures.adapters.enum_adapter import EnumAdapter
from mercury_engine_data_structures.common_types import Float, VersionAdapter
from mercury_engine_data_structures.construct_extensions.alignment import AlignTo
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.formats.property_enum import PropertyEnumDoubleUnsafe
from mercury_engine_data_structures.game_check import Game


class TimingTypeEnum(Enum):
ONE_BYTE = 8
TWO_BYTE = 0


class DreadKFVAdapter(Adapter):
class TimingType:
ONE_BYTE = 8
TWO_BYTE = 0

SUBCON = Struct(
timing_type=EnumAdapter(TimingTypeEnum, Int16ul),
timing_type=Int16ul,
count=Int16ul,
timings=IfThenElse(this.timing_type == TimingTypeEnum.TWO_BYTE, Int16ul[this.count], Int8ul[this.count]),
timings=IfThenElse(this.timing_type == TimingType.TWO_BYTE, Int16ul[this.count], Int8ul[this.count]),
_padding=AlignTo(4, b"\xff"),
values=Array(this.count, Struct(value=Float, derivative=Float)),
)
values=Array(this.count, Float[2]),
).compile()

def __init__(self):
super().__init__(self.SUBCON)

def _decode(self, obj, context, path):
res = ListContainer()
for i in range(obj.count):
res.append(
Container(
time=obj.timings[i],
value=obj["values"][i].value,
derivative=obj["values"][i].derivative,
)
return ListContainer(
Container(
time=time,
value=values[0],
derivative=values[1],
)

return res
for time, values in zip(obj["timings"], obj["values"], strict=True)
)

def _encode(self, obj, context, path):
res = Container(
timing_type=TimingTypeEnum.TWO_BYTE if obj[-1].time > 0xFF else TimingTypeEnum.ONE_BYTE,
timing_type=DreadKFVAdapter.TimingType.TWO_BYTE
if obj[-1].time > 0xFF
else DreadKFVAdapter.TimingType.ONE_BYTE,
count=len(obj),
timings=ListContainer([v.time for v in obj]),
values=ListContainer([Container(value=v.value, derivative=v.derivative) for v in obj]),
timings=[v.time for v in obj],
values=[[v.value, v.derivative] for v in obj],
)

return res
Expand Down
18 changes: 11 additions & 7 deletions src/mercury_engine_data_structures/formats/bmsas.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import functools

import construct
from construct.core import (
Array,
Byte,
Const,
Construct,
Error,
Flag,
Hex,
If,
Expand All @@ -22,7 +23,7 @@
from mercury_engine_data_structures.construct_extensions.strings import PascalStringRobust
from mercury_engine_data_structures.formats.base_resource import BaseResource
from mercury_engine_data_structures.formats.property_enum import PropertyEnum, PropertyEnumDoubleUnsafe
from mercury_engine_data_structures.game_check import Game
from mercury_engine_data_structures.game_check import Game, GameSpecificStruct

StrId = PascalStringRobust(Int16ul, "utf-8")

Expand Down Expand Up @@ -294,9 +295,12 @@ def build_arg_list_sr(obj_data: dict, io, this):

class Bmsas(BaseResource):
@classmethod
@functools.lru_cache
def construct_class(cls, target_game: Game) -> Construct:
if target_game == Game.DREAD:
return BMSAS_Dread
if target_game == Game.SAMUS_RETURNS:
return BMSAS_SR
return Error
return GameSpecificStruct(
{
Game.SAMUS_RETURNS: BMSAS_SR,
Game.DREAD: BMSAS_Dread,
}[target_game],
target_game,
).compile()
2 changes: 1 addition & 1 deletion tests/formats/test_bcmdl.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@


@pytest.mark.parametrize("bcmdl_path", dread_data.all_files_ending_with(".bcmdl", dread_bcmdl_duplicate))
def test_compare_dread_all(dread_tree_100, bcmdl_path):
def test_compare_bcmdl_dread(dread_tree_100, bcmdl_path):
if bcmdl_path in dread_bcmdl_expected_failure:
expectation = pytest.raises(AssertionError)
else:
Expand Down
13 changes: 10 additions & 3 deletions tests/formats/test_bctex.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
from mercury_engine_data_structures import dread_data, samus_returns_data
from mercury_engine_data_structures.formats.bctex import Bctex

dread_exclusions = [
# exceptionally slow file
"textures/system/fx/tests/watertank/textures/watertank_col.bctex",
]

# these are existing textures that bytematch existing ones. likely put in the bossrush pkgs for performance.
dread_210_ignore = [
"actors/characters/centralunitcave/fx/textures/centralunit_flash.bctex",
Expand Down Expand Up @@ -1396,8 +1401,10 @@
]


@pytest.mark.parametrize("bctex_path", dread_data.all_files_ending_with(".bctex", dread_210_ignore + dread_210_only))
def test_compare_dread_100(dread_tree_100, bctex_path):
@pytest.mark.parametrize(
"bctex_path", dread_data.all_files_ending_with(".bctex", dread_210_ignore + dread_210_only + dread_exclusions)
)
def test_compare_bctex_dread_100(dread_tree_100, bctex_path):
parse_build_compare_editor_parsed(Bctex, dread_tree_100, bctex_path)


Expand All @@ -1407,5 +1414,5 @@ def test_compare_dread_210(dread_tree_210, bctex_path):


@pytest.mark.parametrize("bctex_path", samus_returns_data.all_files_ending_with(".bctex", sr_missing))
def test_compare_sr(samus_returns_tree, bctex_path):
def test_compare_bctex_sr(samus_returns_tree, bctex_path):
parse_build_compare_editor_parsed(Bctex, samus_returns_tree, bctex_path)
2 changes: 1 addition & 1 deletion tests/formats/test_bmbls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@


@pytest.mark.parametrize("bmbls_path", dread_data.all_files_ending_with(".bmbls"))
def test_compare_dread(dread_tree_100, bmbls_path):
def test_compare_bmbls_dread(dread_tree_100, bmbls_path):
parse_build_compare_editor(Bmbls, dread_tree_100, bmbls_path)
2 changes: 1 addition & 1 deletion tests/formats/test_bmsad.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@


@pytest.mark.parametrize("bmsad_path", dread_data.all_files_ending_with(".bmsad"))
def test_compare_dread_all(dread_tree_100, bmsad_path):
def test_compare_bmsad_dread_all(dread_tree_100, bmsad_path):
if bmsad_path in dread_must_reencode:
parse_build_compare_editor_parsed(Bmsad, dread_tree_100, bmsad_path)
else:
Expand Down
2 changes: 1 addition & 1 deletion tests/formats/test_bmscu.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@


@pytest.mark.parametrize("bmscu_path", dread_data.all_files_ending_with(".bmscu"))
def test_compare_dread(dread_tree_100, bmscu_path):
def test_compare_bmscu_dread(dread_tree_100, bmscu_path):
parse_build_compare_editor(Bmscu, dread_tree_100, bmscu_path)
4 changes: 2 additions & 2 deletions tests/formats/test_bmssd.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@


@pytest.mark.parametrize("bmssd_path", dread_data.all_files_ending_with(".bmssd", bossrush_assets))
def test_compare_dread_100(dread_tree_100, bmssd_path):
def test_compare_bmssd_dread_100(dread_tree_100, bmssd_path):
parse_build_compare_editor(Bmssd, dread_tree_100, bmssd_path)


Expand All @@ -47,5 +47,5 @@ def test_compare_dread_210(dread_tree_210, bmssd_path):


@pytest.mark.parametrize("bmssd_path", samus_returns_data.all_files_ending_with(".bmssd", sr_missing))
def test_compare_msr(samus_returns_tree, bmssd_path):
def test_compare_bmssd_msr(samus_returns_tree, bmssd_path):
parse_build_compare_editor(Bmssd, samus_returns_tree, bmssd_path)
2 changes: 1 addition & 1 deletion tests/formats/test_bsmat.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


@pytest.mark.parametrize("bsmat_path", dread_data.all_files_ending_with(".bsmat"))
def test_compare_dread_all(dread_tree_100, bsmat_path):
def test_compare_bsmat_dread(dread_tree_100, bsmat_path):
parse_build_compare_editor(Bsmat, dread_tree_100, bsmat_path)


Expand Down
4 changes: 2 additions & 2 deletions tests/formats/test_collision.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
dread_data.all_files_ending_with(".bmscc", bossrush_assets)
+ dread_data.all_files_ending_with(".bmscd", bossrush_assets),
)
def test_compare_dread_100(dread_tree_100, file_path):
def test_compare_collision_dread_100(dread_tree_100, file_path):
parse_build_compare_editor_parsed(Bmscc, dread_tree_100, file_path)


Expand All @@ -88,5 +88,5 @@ def test_compare_dread_210(dread_tree_210, file_path):
samus_returns_data.all_files_ending_with(".bmscc", sr_missing_cc)
+ samus_returns_data.all_files_ending_with(".bmscd", sr_missing_cd),
)
def test_compare_msr(samus_returns_tree, file_path):
def test_compare_collision_msr(samus_returns_tree, file_path):
parse_build_compare_editor_parsed(Bmscc, samus_returns_tree, file_path)
4 changes: 2 additions & 2 deletions tests/formats/test_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
"gui/scripts/extrasmenucomposition.bmscp",
"gui/scripts/iconshudcomposition.bmscp",
"gui/scripts/mainmenucomposition.bmscp",
"gui/scripts/mainmenucomposition.bmssk",
# "gui/scripts/mainmenucomposition.bmssk", very slow
"gui/scripts/slotselectioncomposition.bmscp",
"gui/scripts/slotselectioncomposition.bmssk",
# "gui/scripts/slotselectioncomposition.bmssk", very slow
]

dread_expected_failures = [
Expand Down
4 changes: 2 additions & 2 deletions tests/formats/test_pkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,12 @@


@pytest.mark.parametrize("pkg_path", dread_data.all_files_ending_with(".pkg"))
def test_compare_dread(dread_path_100, pkg_path):
def test_compare_pkg_dread(dread_path_100, pkg_path):
parse_and_build_compare(Pkg.construct_class(Game.DREAD), Game.DREAD, dread_path_100.joinpath(pkg_path))


@pytest.mark.parametrize("pkg_path", samus_returns_data.all_files_ending_with(".pkg", sr_missing))
def test_compare_sr(samus_returns_path, pkg_path):
def test_compare_pkg_sr(samus_returns_path, pkg_path):
if pkg_path in wrong_build_sr:
raw = samus_returns_path.joinpath(pkg_path).read_bytes()
target_game = Game.SAMUS_RETURNS
Expand Down
2 changes: 1 addition & 1 deletion tests/formats/test_toc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from mercury_engine_data_structures.game_check import Game


def test_compare_dread(dread_path_100):
def test_compare_toc_dread(dread_path_100):
game = Game.DREAD
toc_class = Toc.construct_class(game)
toc_path = dread_path_100.joinpath("system/files.toc")
Expand Down
4 changes: 2 additions & 2 deletions tests/formats/test_txt.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


@pytest.mark.parametrize("txt_path", dread_data.all_files_ending_with(".txt"))
def test_compare_dread_100(dread_tree_100, txt_path):
def test_compare_txt_dread_100(dread_tree_100, txt_path):
parse_build_compare_editor(Txt, dread_tree_100, txt_path)


Expand All @@ -16,5 +16,5 @@ def test_compare_dread_210(dread_tree_210, txt_path):


@pytest.mark.parametrize("txt_path", samus_returns_data.all_files_ending_with(".txt"))
def test_compare_sr(samus_returns_tree, txt_path):
def test_compare_txt_sr(samus_returns_tree, txt_path):
parse_build_compare_editor(Txt, samus_returns_tree, txt_path)

0 comments on commit 6b6a4b9

Please sign in to comment.