Last modified 14 years ago Last modified on 01/23/09 18:41:44

Error: Macro BackLinksMenu(None) failed
compressed data is corrupt

Error: Macro TicketQuery(summary=PRO_CHANGE_MANAGER_R0, format=table, col=summary|owner|status|type|component|priority|effort|importance, rows=description|analysis_owners|analysis_reviewers|analysis_score|design_owners|design_reviewers|design_score|implementation_owners|implementation_reviewers|implementation_score|test_owners|test_reviewers|test_score|) failed
current transaction is aborted, commands ignored until end of transaction block



The Change Manager is meant to be a general manager for changes which supports a list of (mostly) all actions done in Sophie 2, implemented as changes.
It's meant to provide undo and redo functionality to the application, as well as help implementing online collaboration.

  • The Change Manager is meant to consist of a list of changes, and each of them should have a unique id (most likely a number)
  • The ids of the changes need to be in increasing though not mandatory consecutive order
  • Each of these changes should be able to handle 4 commands applied to them:
    • undo
    • redo
    • skip
    • unskip

Right now only the UndoManager exists but later it could evolve to ChangeManager (or less possibly exist as a separate entity).

Task requirements

  • review code in UndoManager that represents the current undo manager.
  • besides undo change and redo change the ChangeManager should also be capable of doing the following:
    • skip a change - the change will be skipped and the next in turn will be available if such exists. That is we simply act as if there has not been such change and the next state is the state as if the change has happened. Other changes may be skipped depending on certain situations.
    • unskip a change - will provide the opportunity to revert the skipping of a change. This should be possible only if a skip of the change had been done.
    • undo/redo - the undo/redo mechanism should behave in a generally accepted manner as in most applications nowadays.
    • Important:
      • skip/unskip and undo/redo are all going to be defined as changes. This way undoing a change can be skipped and later unskipped. Skipping a change can be undo. If one is unskipping the skip of the last change, that should act as if he/she is undoing the last change.
      • undo/redo should be possible to be skipped and unskipped.
      • skip/unskip should be possible to be undone and redone.
    • Provide unit tests for at least 5 scenarios.

Task result

  • review of current source code
  • more source code
  • unit tests

Implementation idea

  • review current code
  • add the new features
  • write unit tests

Example scenarios

  • each command will have a number as an id
  • these numbers should be in increasing order, though it's not mandatory for them to be consecutive. Every number represents a change and its position in the list:
  • each skip and unskip command has a single number as argument which is the id of the command it's meant to affect
   1. a = 5  | 5
   2. a = 6  | 6
   3. a = 7  | 7
   4. skip 2 | 7 because a new change has occurred after 2.

   1. b = 10   | 10
   2. b = 5    | 5
   3. skip 2   | 10 is the last change that is to be undone.
   4. undo     | 5 because the skip is undone.
   5. skip 4   | 10 because the last undo is skipped as a change.
   more complicated:
   1.  c = 5    | 5
   2.  c = 7    | 7
   3.  c = 10   | 10
   4.  c = 12   | 12
   5.  undo     | 10 this is the current value of c after the undo
   6.  skip 3   | 7 since 10 was last value after the undo which is the third change.
   7.  undo     | 10 again
   8.  skip 7   | 7 after skipping change 7 we should return to value 7.
   9.  redo     | 7 because this should not be possible since the corresponding undo is already missing so nothing changes.
   10. unskip 7 | 10 since the value after the undo should had been 7.
   11. skip 10  | 7 the previous value is returned.
   12. skip 11  | 10 the previous is unskip 10 so the value remains exactly 10.
   13. skip 12  | 7 again
   14. unskip 11| 10
   15. skip 1   | 10
   15. skip 2   | 10
   15. skip 3   | 10
   15. skip 4   | 10 at this point we cannot revert the initializing of c.


  • skipping the previous change acts like a undo
  • unskipping the previous change acts like a redo
  • in some cases some unskips act as opposite to certain skips, so they could be ruled out to increase performance but right now it's quite hard to deal with such cases, so this could possibly be reconsidered in a further revision of this task
  • there may be more interesting facts that can be observed. Design should take care of these...
  • Be careful to consider the UnmanagedChange type - a change that is supposed to be managed in a special way. Its undo and redo will be implemented as the situation requires. For example - save a book may be a unmanaged change. If the user creates a frame with a movie content (with a media file of over 700Mb), deletes the frame, deletes the media file and requests a undo - the change may become a unmanaged. If the user had not deleted the media file the change would have been a normal change that can be undone.
  • one can argue if actually all the four operations are needed internally but at least to the end user they should be available


How to demo

  • Show the skeleton code of the ChangeManager which is implemented
  • Run the corresponding unit tests