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

[Bugfix] Events should be undoable #942

Merged
merged 3 commits into from
May 23, 2021

Conversation

shaoster
Copy link
Contributor

See #940 (comment)

Checklist

  • Use a separate branch in your local repo (not master).
  • Test coverage is 100% (or you have a story for why it's ok).

@shaoster shaoster changed the title [Bugfix] Events should not leave invalid undoable undo entries [Bugfix] Events should not leave invalid undo entries May 22, 2021
@shaoster shaoster force-pushed the bugfix/undo-after-endStage branch from 348e169 to bc0311f Compare May 22, 2021 16:26
Copy link
Member

@delucis delucis left a comment

Choose a reason for hiding this comment

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

Thanks for tackling this. I don’t think this is actually the logic we want. It should be possible to undo just the endStage event in your test and not the event and the move. (An endStage called by a move via the ctx.events API won’t end up in the undo/redo stack, so you only have to account for the case where an event was explicitly called.)

My suggestion is to wrap this reducer check in if (last.moveType):

// Only allow undoable moves to be undone.
const lastMove: Move = game.flow.getMove(
restore.ctx,
last.moveType,
last.playerID
);
if (!CanUndoMove(state.G, state.ctx, lastMove)) {
return state;
}

i.e. we only check for move undoability if the thing to be undone is actually a move.

The undo/redo stacks are reset at the start of each turn/phase, so this only enables event undos for stages anyway. (And we already made sure we’re not undoing another player’s action, so this only allows a player to undo their own stage event.)

@shaoster
Copy link
Contributor Author

shaoster commented May 22, 2021

Thanks for tackling this. I don’t think this is actually the logic we want. It should be possible to undo just the endStage event in your test and not the event and the move. (An endStage called by a move via the ctx.events API won’t end up in the undo/redo stack, so you only have to account for the case where an event was explicitly called.)

My suggestion is to wrap this reducer check in if (last.moveType):

// Only allow undoable moves to be undone.
const lastMove: Move = game.flow.getMove(
restore.ctx,
last.moveType,
last.playerID
);
if (!CanUndoMove(state.G, state.ctx, lastMove)) {
return state;
}

i.e. we only check for move undoability if the thing to be undone is actually a move.

The undo/redo stacks are reset at the start of each turn/phase, so this only enables event undos for stages anyway. (And we already made sure we’re not undoing another player’s action, so this only allows a player to undo their own stage event.)

The main reason I didn't want to go the route of actually supporting undo of endStage is that changes existing behavior and smells more like a feature than a bugfix.

Remember the cause for tackling this was this stack trace where the last thing on the stack wasn't a move:

TypeError: Cannot read property 'undoable' of null

  47 | const CanUndoMove = (G: any, ctx: Ctx, move: Move): boolean => {
  48 |   function HasUndoable(move: Move): move is LongFormMove {
> 49 |     return (move as LongFormMove).undoable !== undefined;
     |                                   ^
  50 |   }
  51 | 
  52 |   function IsFunction(

  at HasUndoable (src/core/reducer.ts:49:35)
  at CanUndoMove (src/core/reducer.ts:58:8)
  at src/core/reducer.ts:417:14
  at dispatch (node_modules/redux/lib/redux.js:218:22)
  at Object.dispatch (src/core/reducer.ts:180:18)
  at Master.onUpdate (src/master/master.ts:271:11)
  at Object.<anonymous> (src/master/master.test.ts:402:20)

@delucis
Copy link
Member

delucis commented May 22, 2021

Well, whether it’s a feature or a bug fix, I still think it’s what we want :-D

I guess it’s just an argument as to whether the bug was the thing without a moveType ending up on the undo stack, or the code processing the undo stack failing to handle a thing without a moveType. I’d suggest the latter but 🤷

@shaoster
Copy link
Contributor Author

shaoster commented May 22, 2021

Well, whether it’s a feature or a bug fix, I still think it’s what we want :-D

I guess it’s just an argument as to whether the bug was the thing without a moveType ending up on the undo stack, or the code processing the undo stack failing to handle a thing without a moveType. I’d suggest the latter but 🤷

SGTM about that being the more reasonable behavior. Main concern is that it's bigger scope to test that "new" functionality because of the current test setup. I guess I can fix the tests accordingly to cover! 🚀

RE: i.e. we only check for move undoability if the thing to be undone is actually a move.: shouldn't we have exactly the same pre-conditions for undoing a move vs. an event? Edit: nvm stages don't seem to have that restriction

@shaoster shaoster changed the title [Bugfix] Events should not leave invalid undo entries [Bugfix] Events should be undoable May 22, 2021
@delucis
Copy link
Member

delucis commented May 22, 2021

Main concern is that it's bigger scope to test that "new" functionality because of the current test setup. I guess I can fix the tests accordingly to covera! 🚀

Thanks! I guess it shouldn’t be too different from the existing tests, just with the endStage undoing as expected.

@shaoster shaoster force-pushed the bugfix/undo-after-endStage branch from bc0311f to 65b8b0d Compare May 22, 2021 23:05
@shaoster shaoster requested a review from delucis May 22, 2021 23:06
Copy link
Member

@delucis delucis left a comment

Choose a reason for hiding this comment

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

Looks good @shaoster! Thank you.

@delucis delucis merged commit 49c2c12 into boardgameio:master May 23, 2021
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.

2 participants