[josm-dev] josm-ng progress

Petr Nejedly Petr.Nejedly at Sun.COM
Thu Feb 14 23:03:59 GMT 2008


... is limited.

Well, I have declared I have little time for the baby (have real babies
to look after ;-) among other things), but I manage to make a commit from
time to time.

For now I concentrate on the very basics of the design, as the initial
implementation was made in the mode of "do the minimum necessary to validate
the concept".

I'll try to summarize the architecture over the weekend but for the last
two evenings, I have at least managed to put more thoughts into the undo
system, updated the code to implement the idea well, and even cover it
with few tests.

Here is how is it meant to work. Please look at it and try to find weak
points where the scheme would broke.

1) No commands. User actions perform DataSet modifications directly (through the
API of DataSet and individual primitives).

2) DataSet exports UndoableEdits to a registered UndoManager (there is one per editable
layer), after slight processing inside a special UndoableEditSupport.

3) Each DS/Primitive modification metod first creates an UndoableEdit of proper kind.
The edit samples current value of the field to be modified and keeps it.

4) undo/redo of given edit just switches the current and saved value. The infrastructure
enforces that you can't do an out-of-order undo/redo, so switch is safe.

5) To support grouping of edits, DataSet exports runAtomic(Runnable) method.
Anything running inside it's run will be posted to the UndoManager as single
(Compound)UndoableEdit, so you can undo/redo it atomically.

6) To support incremental edits (like if you're dragging around the selection - that
modifies the DataSet on every mouse move event), runAtomic takes a token that can
be compared. If you perform two (or more) consecutive runAtomic()s with the same
token, all the UndoableEdits generated during the second (subsequent) round
are discarded. This works thanks to 3 and 4:
  user action: [change x from 1 to 2| save x was 1]
  user action: [change x from 2 to 3|discard]
  user undo:   [undo change - set x to 1, save x was 3]
  user redo:   [redo change - set x to 3, save x was 1]
The only thing that needs to be taken care of in such case is that you use the same
token only for relevant groups of edits.
The use case for this is to generate new token on mouse down, use the token
throughout the whole drag (thus the complete drag operation of the node
selection/way/whatever ends up being single undoable edit) and then
discard the token on mouse-up.

That's all the magic in there. It should cover complicated edits, composition
of edits and simple undo. Is there a hole in it?

-- 
Petr "Nenik" Nejedly, NetBeans/Sun Microsystems, http://www.netbeans.org
355/113 -- Not the famous irrational number PI, but an incredible simulation!




More information about the josm-dev mailing list