fix(unlockmode): Exit Without Saving now reverts a moved fallback anchor - #1233
Merged
Merged
Conversation
Reported by @grouch on 8.7.6: throw a fallback anchor far away to reach something underneath it, then Exit Without Saving, and it stays where it was thrown. This is ours, not an interaction with another addon. RevertPositions restored nine anchor fields from the snapshot and then deliberately re-attached the LIVE fallback on top. That carry-over existed because the snapshot never captured `fallback`, so without it a revert would have destroyed every fallback including ones from earlier sessions. It also meant a fallback edited during the session survived the discard, which is exactly the report: the anchor reverts, and then the edited fallback is put back over it. Fallbacks are positional. _NudgeSelectedFallbackGhost does fb.offsetX = (fb.offsetX or 0) + dx fb.offsetY = (fb.offsetY or 0) + dy so it mutates the table IN PLACE. The snapshot therefore has to copy it, not reference it, or the edit would drag the snapshot along and the revert would be a no-op. Snapshot `fallback` by copy, restore it from the snapshot by copy, and drop the carry-over it made redundant. Pre-session fallbacks are still preserved, which is what the carry-over was protecting; session edits now revert like every other position. The existing rule that a link reverting away takes its fallback with it still holds, because an entry with no snapshot is not recreated at all.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reported by @grouch on 8.7.6: throw a fallback anchor far away to reach something underneath it, then Exit Without Saving, and it stays where it was thrown. This is ours, not an interaction with another addon.
Cause
RevertPositionsrestored nine anchor fields from the snapshot and then deliberately re-attached the LIVE fallback on top.That carry-over existed for a good reason:
SnapshotPositionsnever capturedfallback, so without it a revert would have destroyed every fallback, including ones set in earlier sessions. The side effect was that a fallback edited during the session also survived the discard, which is exactly the report. The anchor reverts, and then the edited fallback is put back over it.Fix
Snapshot
fallbackby copy, restore it from the snapshot by copy, and drop the carry-over it made redundant.The copy is load-bearing. Fallbacks are positional, and
_NudgeSelectedFallbackGhostdoesso it mutates the table in place. A snapshot holding a reference would be dragged along by the edit and the revert would be a silent no-op. The restore copies for the same reason in the other direction, so the next session's nudges cannot reach back into the snapshot.
Pre-session fallbacks are still preserved, which is all the carry-over was protecting. Session edits now revert like every other position.
Why dropping the carry-over is safe
Both the old carry-over and the new snapshot iterate
pairs(anchorDB), so coverage is identical rather than merely similar. Entries created during the session are dropped by both, since an entry with no snapshot is not recreated at all, which preserves the existing rule that a link reverting away takes its fallback with it. Pre-session fallbacks survive in both.fallbackonly ever holds four scalars (target,side,offsetX,offsetY), with no frame references and no nesting, soCopyTablehas nothing deep or cyclic to walk.One deliberate widening
Removing a fallback mid-session now reverts too. Previously that survived Exit Without Saving, because the carry-over simply had nothing to re-attach. It is now discarded like any other session edit, which is what Exit Without Saving is supposed to mean, but it is behaviour beyond the reported case and worth knowing about.
Performance
SnapshotPositionshas one caller, at unlock-mode entry. Not per frame, no timers, nothing added to any update loop. The change costs one four-field table copy per anchored element, once, when unlock mode opens. The same function already copies the wholeunlockAnchors,unlockWidthMatch,unlockHeightMatch, andphantomBoundstables a few lines later, so this is a rounding error against work already being done, andCopyTableis the established idiom in this file.Ghost visuals need no extra handling:
RevertPositionsalready ends by hiding the fallback ghosts, and they recompute fromfb.offsetX/offsetYwhenever they are next shown.Notes
One file, net 16 insertions and 20 deletions, so it removes more than it adds. No new strings, no options changes, no saved-variable format changes.
Tested in game: a fallback anchor thrown during a session now returns to where it was on Exit Without Saving.