-
Notifications
You must be signed in to change notification settings - Fork 793
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
base: master
Are you sure you want to change the base?
Clean up M_RoundWalk #2284
Conversation
@@ -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)) { |
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 we're casting pointers, shouldn't we specify the underlying type of the enum?
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.
_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.
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.
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
};
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, 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)) { |
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, 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) |
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.
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.
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.
Are you suggesting to take MonsterStruct &
instead of RotationDirection *
as the second 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.
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.)
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.
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);
}
No description provided.