Keep a trimmed stack dirty at -1 through save, load, and restore [major] - #122
Merged
Merged
Conversation
The "initial state is clean" flag on SaveBoundaryManager was not part of the saved state, and RestoreFromState's Clear() reset it to true. A stack whose oldest commands were trimmed, with no save boundary, reported no unsaved changes at -1 after every LoadStateAsync or RestoreFromState, which is #76 again. Breaking changes, per the maintainer's decision on #83: - ISaveBoundaryManager gains InitialStateIsClean and SetInitialStateClean(bool) - IUndoRedoSerializer.SerializeAsync takes an initialStateIsClean parameter - UndoRedoStackState gains an InitialStateIsClean init property, default true JsonUndoRedoSerializer writes the flag and reads a missing one as true, so data saved before this change still loads with its old meaning. Fixes #83 Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01XEFMRMk4z5RaHqHVp4rTtj
|
This was referenced Sep 29, 2026
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.



Fixes #83
What was wrong
SaveBoundaryManagertracks whether position -1 still holds the clean initial state. That flag was never saved, andRestoreFromStatecallsClear(), which sets it back totrue. Take a stack whose oldest commands were trimmed and that has no save boundary. After anyLoadStateAsyncorRestoreFromState, including a restore from its ownGetCurrentState(), it reported no unsaved changes at -1. This brought back #76.Change (option 1 from the maintainer's decision, a major bump)
ISaveBoundaryManagergainsInitialStateIsClean { get; }andSetInitialStateClean(bool).IUndoRedoSerializer.SerializeAsyncgains aninitialStateIsCleanparameter, placed before the cancellation token.UndoRedoStackStategainsInitialStateIsClean { get; init; } = true.GetCurrentState()fills it in.RestoreFromStaterestores the flag afterClear()and before recreating save boundaries. Restoring a boundary still clears the flag.JsonUndoRedoSerializerwritesinitialStateIsClean. When the field is missing it reads it astrue, so data saved before this change still loads with the meaning it had.docs/serialization.mdshows the new signature and property.Tests
New tests in
SerializationTests:maxStackSize: 2, execute 3, undo 2). Each one now reportsHasUnsavedChanges == true.initialStateIsCleanfield, still loads.With the
SetInitialStateCleancall inRestoreFromStatetaken out, the three repro tests fail. With it in place, all 121 tests pass on net10.0.Existing
SerializeAsynccall sites in the tests now pass the new argument.Notes
dotnet packreports ApiCompat cross-TFM errors (CP0014/CP0001 on polyfilled BCL types) with the local SDK 10.0.401.mainshows the same errors, so they don't come from this change.RestoreFromStatepath, so watch for overlap there.🤖 Generated with Claude Code
https://claude.ai/code/session_01XEFMRMk4z5RaHqHVp4rTtj
Generated by Claude Code