-
Notifications
You must be signed in to change notification settings - Fork 10
Add more methods to BRSA #280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
for more information, see https://pre-commit.ci
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #280 +/- ##
==========================================
+ Coverage 78.85% 79.12% +0.27%
==========================================
Files 80 80
Lines 4323 4365 +42
==========================================
+ Hits 3409 3454 +45
+ Misses 914 911 -3 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you're returning a Container from an API it should probably have its own type too
That's already used in various places, and it's something I plan to clean up once I finish generating classes for every type. We can leave it as a Container for now imo |
To elaborate: That said, I just remembered I should be wrapping some of those lists in ListContainers, so I'll fix that soon. |
I fixed those ListContainers, and I also raised ValueErrors if the subarea config/setup/charclass group already exists, so this PR should be ready now. |
ignore_camera_offsets: bool = False, | ||
charclass_group: str = "No Enemies", | ||
camera_ids: list[str] = [], | ||
cutscene_ids: list[str] = [], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as a rule, you should never use a mutable value as a default argument
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to show that if it's not provided, it defaults to empty, hence the ternaries below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in that case do cutscene_ids: list[str] | None = None
and if cutscene_ids is None: cutscene_ids = []
and drop the ternaries
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
facepalming at myself for not doing that to begin with. thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, are the ternaries actually that bad? I feel like it only needs to default to None and then the ternary is just more compact.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if cutscene_ids is None:
cutscene_ids = []
{"vsCutsceneIds": ListContainer(cutscene_ids)}
is more compact and readable imo than
{"vsCutsceneIds": ListContainer(cutscene_ids) if cutscene_ids is not None else ListContainer()}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to be fair, you only need if cutscene_ids
there. I also personally like inlining it, but maybe that's the JavaScript background talking, haha. if the former way is more pythonic, I'll just go with that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, please do. though if you're making a new wrapper class, you should also convert this function into a classmethod to create the wrapper and then have this function accept an instance of the wrapper class
"sCharclassGroupId": charclass_group, | ||
"asItemsIds": ListContainer([""] * 9), | ||
"vsCameraCollisionsIds": ListContainer(camera_ids) if camera_ids else ListContainer(), | ||
"vsCutscenesIds": ListContainer(cutscene_ids) if cutscene_ids else ListContainer(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's with these ternaries?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are here because of the mutable default arguments
param subarea_id: the name of the subarea | ||
param preset_name: the name of the preset | ||
param setup_id: the name of the setup the subarea is in""" | ||
self.get_subarea_config(subarea_id, setup_id).asItemsIds[8] = preset_name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok I appreciate your concern about it being out of scope of this PR to abolish the use of Container
here, and that's fine, but these functions are a problem. at the very minimum I need you to manually write a wrapper class for subarea configs cuz these are just untenable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you mean just asItemsIds
or the whole config? I can see this in particular being made a lot simpler by it and I wouldn't mind doing so as a temporary solution. something like BMSAD?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it would be easiest to add a wrapper that gets returned by get_subarea_config()
. otherwise you would have to deal with some really messy code to couple the asItemsIds
wrapper to the internal container, which is way more work than just adding properties to the config wrapper.
something like the BMSLD pr: https://github.com/randovania/mercury-engine-data-structures/pull/258/files#diff-bf70997618c433f3cb8e9e854527f73c9a3a8327c932b8bd6101897ec7c55857R145
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, definitely seems easiest.
returns: the charclass group""" | ||
return next(group for group in self.charclass_groups if group.sId == group_id) | ||
|
||
def add_charclass_group(self, group_id: str, charclasses: list[str] = []) -> Container: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mutable default argument
raise ValueError(f"Charclass {group_id} is already present") | ||
|
||
new_group = Container( | ||
{"sId": group_id, "vsCharClassesIds": ListContainer(charclasses) if charclasses else ListContainer()} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
another weird ternary
Also achieves full coverage of BRSA and adds docstrings to every method (both new and old)