Hi Eric On Fri, 24 Jun 2011 00:06 +0200, "Christopher Armstrong" <carmstr...@fastmail.com.au> wrote:
Hi Eric ----- Original message ----- > Unfortunately I haven't coded anything since our chat a few months ago > :-(. I'm still thinking about how to build an editor with persistent > undo/redo including actions like selection changes or revision control > operations like revert or merge. I had some thoughts about how to make this work. The main idea is to introduce a concept of branches or branch pointers, where we not only store the history of the object, but also the linear undo/redo history of the branch pointer. Each time the user makes a change, we update the branch pointer and we also create an undo history node of the change we made to the branch pointer in a sort of branch history. Views then point to a branch pointer, and not to an object. Importantly, views do not have history (they are merely persisted/restored). Things like selections are handled by storing them in the branch pointer history, not in the object or view. This way, multiple views of the same object can exist with different selections in each. Selections can then be undone. Multiple views pointing to the same branch would have the same branch history. Cloning an object would involve creating a new branch with the first history node pointing to the same revision of the object. I don't know anything about Quentin's history track idea, so this could be the same thing. I thought I should provide some details about how I think this should be implemented, as I get the impression I wasn't very clear :-(. Each element in the core-object history is stored as it is presently, i.e. with a revision number and the set of changes to all the objects in a core-object tree. Parallel to this is a concept of named branches on a object. Each object can have zero or more branches that "point" to a particular revision of an object. For simplicity, object branches should probably be named to distinguish them from one another, but we could autogenerate the names to make sure they are unique for an object and permit the user to rename them later as they saw fit. The branch also has a history. This consists of nodes that store a pointer value to an object revision, and the previous and next node in the history. These nodes will probably need some space for auxilliary information so that they can store things like selection state. The present state of the branch is a pointer to one of these history nodes (instead of a pointer to an object revision). Each time the user makes a change to an object, the system * creates a new object revision, * create a new branch pointer history node pointing to the new object revision * set the branch to point to the new branch pointer history node * set the back pointer of the history node to point to the previous branch history node * changes the forward pointer of the previous history node to point to the new branch history node. An undo is performed as just winding back to a previous branch pointer history node by following the back pointer in the history node and updating the branch to point to the history node. A redo is similar (follow the forward pointer in the history node). A change in the object revision (for example from a new change, a merge or a revert to a previous version) is just by creating a new branch pointer history node. A selection is also a new branch pointer history node, but with the same object revision and the selection information stored in the auxilliary field. All these operations suddenly become undoable because they are separate from the object history. Furthermore, cloning an object is just a matter of creating a new branch on it with no branch history. Each time a new node is created, we set the back pointer to point to the previous history node, and we update the forward pointer of the previous node to point to the new node. That way, when the user moves a one or more of paces back along the node tree, and then starts making new changes, it is still possible to follow the track both backwards and forwards again. In this case, there will be history node tracks that are no longer used, but they could still be visualised somehow if the user wanted to explore them and view them, or just deleted (as they can no longer be followed). The primary consequence is that a view merely references a branch, and that a view has NO history. I'm not sure if this is a bad limitation - if a view stores only the state of the view (such as e.g. list mode or icon mode in a file explorer), this is not the kind of operation that should be "undoable". On the other hand, if it is possible to edit a view (such as the layout of toolbar buttons) in a special editing mode, a view should have history like any other object. My thinking is that this is workable if a view's design is its own object with its own branch. Hope that helps. Chris -- Christopher Armstrong carmstrong ^^AT^ fastmail dOT com /Dot/ au
_______________________________________________ Etoile-dev mailing list Etoile-dev@gna.org https://mail.gna.org/listinfo/etoile-dev