The current architecture allows anything to add an entry to the undo history by calling AddCommandStep(). When called, it serializes all of the graphics in a deterministic way to a byte[] array. This is done in many places eagerly, such as a pointer tool mouse-up after dragging, or after adding a new graphic. If the previous state is identical to the current state, it is discarded.
This works very well most of the time and it's very unlikely that a change will be missed and not added to the history.
There are a couple things that can be improved:
If we are doing an operation like nudge, or changing object line width, it's possible for many entries to get added to the history as AddCommandStep() is triggered every time something is changed
Modifying an image crop causes an history entry for each modification of the crop window which produces some unexpected results as object state may be inconsistent while cropping. A crop operation should only be treated as a single entry.
We could store the entire undo/redo history so it is preserved for re-loaded sessions
Design considerations:
Undo manager ideally would have little/no knowledge about any specific graphic object. (ie. avoid specific checks looking for things like GraphicImage.Editing)
I considered serialising the objects to an XElement and comparing the XML element(s) that have changed between the previous and current entry instead of doing a binary comparison. This would help with (1) but we would need some additional consideration for things like Left, Top, etc. An object Move will update all of the coordinate properties, as well as content bounds. This implies that some knowledge of the specific graphics would be required.
The current architecture allows anything to add an entry to the undo history by calling
AddCommandStep()
. When called, it serializes all of the graphics in a deterministic way to abyte[]
array. This is done in many places eagerly, such as a pointer tool mouse-up after dragging, or after adding a new graphic. If the previous state is identical to the current state, it is discarded.This works very well most of the time and it's very unlikely that a change will be missed and not added to the history.
There are a couple things that can be improved:
AddCommandStep()
is triggered every time something is changedDesign considerations:
GraphicImage.Editing
)I considered serialising the objects to an XElement and comparing the XML element(s) that have changed between the previous and current entry instead of doing a binary comparison. This would help with (1) but we would need some additional consideration for things like
Left
,Top
, etc. An objectMove
will update all of the coordinate properties, as well as content bounds. This implies that some knowledge of the specific graphics would be required.