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

fix: filter undone event groups before moving them to the redo stack #7069

Merged
merged 1 commit into from
May 11, 2023

Conversation

ewpatton
Copy link
Contributor

The basics

  • I branched from develop
  • My pull request is against develop
  • My code follows the style guide
  • I ran npm run format and npm run lint

The details

Resolves

Fixes #7026

Proposed Changes

This PR filters events in a group prior to undoing them.

Behavior Before Change

Events being undone were not filtered before being put onto the redo stack. If there were multiple events that needed to be merged, this can result in inconsistent changes on the undo and redo stacks.

Behavior After Change

During undo, events within a group are passed through the Event.utils.filter function so that any sequence of events that result in a no-op will be removed from the undo/redo stack.

Reason for Changes

The issue was appropriately described in #7026.

Test Coverage

I ran npm test and all tests passed. However, we may want to add more tests to evaluate the specific sequence of events that lead to #7026.

Documentation

Additional Information

@ewpatton ewpatton requested a review from a team as a code owner May 10, 2023 01:35
@ewpatton ewpatton requested a review from NeilFraser May 10, 2023 01:35
@ewpatton ewpatton changed the title Filter undone event groupss before moving them to the redo stack Filter undone event groups before moving them to the redo stack May 10, 2023
@conventional-commit-lint-gcf
Copy link

🤖 I detect that the PR title and the commit message differ and there's only one commit. To use the PR title for the commit history, you can use Github's automerge feature with squashing, or use automerge label. Good luck human!

-- conventional-commit-lint bot
https://conventionalcommits.org/

@ewpatton ewpatton force-pushed the hotfix/undo-event-merge branch from b922d0d to 33c1ab0 Compare May 10, 2023 01:37
@ewpatton ewpatton changed the title Filter undone event groups before moving them to the redo stack fix: Filter undone event groups before moving them to the redo stack May 10, 2023
@github-actions github-actions bot added the PR: fix Fixes a bug label May 10, 2023
@BeksOmega BeksOmega requested review from BeksOmega and removed request for NeilFraser May 10, 2023 15:36
@BeksOmega BeksOmega assigned BeksOmega and unassigned NeilFraser May 10, 2023
Copy link
Collaborator

@BeksOmega BeksOmega left a comment

Choose a reason for hiding this comment

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

This LGTM :D

My plan is just to accept this as is since it fixes the bug, but I think John's other idea is also a good one:

I would also suggest testing to see if the output of filtering/merging contains any non-null events. If not, then the undo/redo behavior should be repeated, trying the next group of events, until something actually changes, otherwise it feels weird to press undo and nothing happens.

So if you want to add that while you're in the area I wanted to give you an opportunity to!

@ewpatton
Copy link
Contributor Author

@BeksOmega Let me think about this a bit and get back to you.

@ewpatton ewpatton force-pushed the hotfix/undo-event-merge branch 3 times, most recently from 3bcd167 to 9529d45 Compare May 11, 2023 18:47
@ewpatton
Copy link
Contributor Author

@BeksOmega So what I decided would be the best approach is to filter any events at the top of the undo stack after firing events, possibly removing null events, so that the undo stack is always a minimal set of changes. Note that this implementation makes the assumption that event groups cannot be interleaved in the undo stack.

Copy link
Collaborator

@BeksOmega BeksOmega left a comment

Choose a reason for hiding this comment

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

Approach LGTM! Not sure if we still need the previous change or not. Once I get clarification on that I'll get this merged =) Thank you again for the fix!

Wrt event groups, they can be interleaved, but we've never handled that for undo and redo (we just stop if we hit a group that's different than the current one, even if the "breaking group" is in the middle of a group). So I see no reason to start handling it now.

@@ -634,12 +634,12 @@ export class Workspace implements IASTNodeLocation {
if (!event) continue;
events.push(event);
}
events = eventUtils.filter(events, redo);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this change still necessary now that we are filtering the undo stack itself?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It may still be semantically correct to filter events being processed in the undo stack before pushing them to the redo stack. Otherwise, Blockly ends up dropping events from the queue that happen to still be on the stack, which ultimately leads to what happened in the initial issue since there is an event that never gets cleaned up from the stack.

Copy link
Collaborator

Choose a reason for hiding this comment

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

So is this just a precautionary thing? My reading is that they're getting filtered before being run + pushed to the undo stack anyway because they're being filtered before they're even pushed to the undo stack.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm. That is a fair point. I can push an update with only the second commit. If there continue to be occasional issues then we can always reapply it.

Change-Id: I21eb3dfaaf5089d373b0f7e810da657c9b541b8b
@ewpatton ewpatton force-pushed the hotfix/undo-event-merge branch from 9529d45 to a03bc2d Compare May 11, 2023 21:20
@BeksOmega BeksOmega changed the title fix: Filter undone event groups before moving them to the redo stack fix: filter undone event groups before moving them to the redo stack May 11, 2023
@BeksOmega BeksOmega merged commit bef5526 into google:develop May 11, 2023
@github-actions github-actions bot added PR: fix Fixes a bug and removed PR: fix Fixes a bug labels May 11, 2023
@cpcallen cpcallen mentioned this pull request Jul 19, 2024
1 task
cpcallen added a commit to cpcallen/blockly that referenced this pull request Aug 19, 2024
Use of the filter function in Workspace.prototype.undo has caused
problems with repeated undo/redo (see issue google#7026), the
originally-chosen fix for which was the addition (in PR google#7069) of
code to fireNow to post-filter the .undoStack_ and .redoStack_ of
any workspace that had just been involved in dispatching events.

This apparently resolved the issue but added considerable
additional complexity and made it difficlut to reason about how
events are processed for undo/redo.

Instead, since this filtering typically does nothing (at least
nothing desirable), simply don't re-filter events on the undo
stack before replaying them.
cpcallen added a commit to cpcallen/blockly that referenced this pull request Aug 19, 2024
Use of the filter function in Workspace.prototype.undo has caused
problems with repeated undo/redo (see issue google#7026), the
originally-chosen fix for which was the addition (in PR google#7069) of
code to fireNow to post-filter the .undoStack_ and .redoStack_ of
any workspace that had just been involved in dispatching events.

This apparently resolved the issue but added considerable
additional complexity and made it difficlut to reason about how
events are processed for undo/redo.

Instead, since this filtering typically does nothing (at least
nothing desirable), simply don't re-filter events on the undo
stack before replaying them.
cpcallen added a commit to cpcallen/blockly that referenced this pull request Aug 19, 2024
Use of the filter function in Workspace.prototype.undo has caused
problems with repeated undo/redo (see issue google#7026), the
originally-chosen fix for which was the addition (in PR google#7069) of
code to fireNow to post-filter the .undoStack_ and .redoStack_ of
any workspace that had just been involved in dispatching events.

This apparently resolved the issue but added considerable
additional complexity and made it difficult to reason about how
events are processed for undo/redo.

Instead, since this filtering typically does nothing (at least
nothing desirable), simply don't re-filter events on the undo
stack before replaying them.
cpcallen added a commit to cpcallen/blockly that referenced this pull request Aug 19, 2024
Use of the filter function in Workspace.prototype.undo has caused
problems with repeated undo/redo (see issue google#7026), the
originally-chosen fix for which was the addition (in PR google#7069) of
code to fireNow to post-filter the .undoStack_ and .redoStack_ of
any workspace that had just been involved in dispatching events.

This apparently resolved the issue but added considerable
additional complexity and made it difficult to reason about how
events are processed for undo/redo.

Instead, since this filtering typically does nothing (at least
nothing desirable), simply don't re-filter events on the undo
stack before replaying them.
cpcallen added a commit that referenced this pull request Aug 20, 2024
Use of the filter function in Workspace.prototype.undo has caused
problems with repeated undo/redo (see issue #7026), the
originally-chosen fix for which was the addition (in PR #7069) of
code to fireNow to post-filter the .undoStack_ and .redoStack_ of
any workspace that had just been involved in dispatching events.

This apparently resolved the issue but added considerable
additional complexity and made it difficult to reason about how
events are processed for undo/redo.

Instead, since this filtering typically does nothing (at least
nothing desirable), simply don't re-filter events on the undo
stack before replaying them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PR: fix Fixes a bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Merged events producing no-op event result in incorrect state after repeated undo/redo.
3 participants