Skip to content
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

Clean up M_RoundWalk #2284

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Clean up M_RoundWalk #2284

wants to merge 1 commit into from

Conversation

AJenbo
Copy link
Member

@AJenbo AJenbo commented Jul 3, 2021

No description provided.

@AJenbo AJenbo requested review from julealgon, ephphatha and StephenCWills and removed request for julealgon and ephphatha July 3, 2021 01:46
@@ -3334,7 +3349,7 @@ void MAI_Round(int i, bool special)
int dist = std::max(abs(mx), abs(my));
if ((Monst->_mgoalvar1++ >= 2 * dist && DirOK(i, md)) || dTransVal[Monst->position.tile.x][Monst->position.tile.y] != dTransVal[fx][fy]) {
Monst->_mgoal = MGOAL_NORMAL;
} else if (!M_RoundWalk(i, md, &Monst->_mgoalvar2)) {
} else if (!M_RoundWalk(i, md, (RotationDirection *)&Monst->_mgoalvar2)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're casting pointers, shouldn't we specify the underlying type of the enum?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_mgoalvar2 os one of those nasty temp variables that are used as different things in various contexts. Some times is a relative direciton (left/right) some times it's a cardinal Direciton, some times it's the X component of a position.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it was unclear what I was suggesting because of the line that I chose to comment on. Since the type of _mgoalvar2 is int, I think the underlying type of the RotationDirection enum should also be int. From what I'm reading, unless we explicitly specify the type, the standard only specifies that the underlying type will be big enough to represent all its values.

enum RotationDirection : int {
	RotateRight,
	RotateLeft
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is undefined behaviour territory.

Given it's a new enum that isn't used anywhere else I'd really like to use scoped enums (enum class|struct) instead. They default to a backing type of int which avoids this issue.

@@ -3334,7 +3349,7 @@ void MAI_Round(int i, bool special)
int dist = std::max(abs(mx), abs(my));
if ((Monst->_mgoalvar1++ >= 2 * dist && DirOK(i, md)) || dTransVal[Monst->position.tile.x][Monst->position.tile.y] != dTransVal[fx][fy]) {
Monst->_mgoal = MGOAL_NORMAL;
} else if (!M_RoundWalk(i, md, &Monst->_mgoalvar2)) {
} else if (!M_RoundWalk(i, md, (RotationDirection *)&Monst->_mgoalvar2)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is undefined behaviour territory.

Given it's a new enum that isn't used anywhere else I'd really like to use scoped enums (enum class|struct) instead. They default to a backing type of int which avoids this issue.

}

bool M_RoundWalk(int i, Direction direction, int *dir)
bool M_RoundWalk(int i, Direction direction, RotationDirection *spin)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only time this updates monster[i]->mgoalvar2 is if the direction checks fail. I think it'd be easier to take this argument by value as that makes the conversion easier and lets it get passed straight through to Rotate().

This does mean updating _mgoalvar2 explicitly as a side effect at the end of the function, ideally that side-effect gets removed in a later refactor.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you suggesting to take MonsterStruct & instead of RotationDirection * as the second argument?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RotationDirection by value as the third argument unless you wanted to unpick the use of the monster struct and array index further down the call stack :)

bool M_RoundWalk(int i, Direction direction, RotationDirection spin) {
    // existing logic updated to not dereference spin
    monster[i]._mgoalvar2 = monster[i].mgoalvar2 == RotationDirection::RotateRight ? RotationDirection::RotateLeft : RotationDirection::RotateRight;
}

(That said I think only DirOk uses the i value in a way that makes refactoring slightly complicated.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be further simplified?
The spin parameter is always read from and always written to _mgoalvar2 or?

bool RoundWalk(int i, Direction direction)
{
   RotationDirection spin = static_cast<RotationDirection>(monster[i]._mgoalvar2)
   // existing logic
   monster[i]._mgoalvar2 = static_cast<int>(spin);
}

@AJenbo AJenbo added this to the 1.5.0 milestone Mar 28, 2022
@AJenbo AJenbo removed this from the 1.5.0 milestone Apr 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants