Hey Christopher,
Thanks a lot for the additional explanation!
>> > 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.
Regarding names, Quentin's idea was "no name-based references in CoreObject;
UUID's everywhere" - which is pretty much what you suggest. You can then map
human-readable names to UUID's, freely edit the names without fear of breaking
anything, full-text-search index the names, etc. :-)
> 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.
Sounds good. I think I was working along similar lines in my first
"ObjectMerging" prototype. The COHistoryGraphNode objects were the branch
history nodes. I was pretty much stealing Git's idea of a Commit object
(http://book.git-scm.com/1_the_git_object_model.html)
> 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.
Right, I think this is essentially the idea of using immutable objects for
undo/redo:
http://stackoverflow.com/questions/1812978/undo-redo-with-immutable-objects
> 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).
Right.
> 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.
Yeah, I was thinking about this as well.
I could be interesting to have switching from list mode to icon mode be
undoable..
As another example, Xcode has those little back/forward buttons which act as
undo/redo for scrolling and navigating between files. Sometimes it's really
handy when editing a huge file to have undo for scrolling.
> Hope that helps.
>
Thanks!
I'm trying to put together another prototype and discussing this is a big help.
Regards,
Eric
_______________________________________________
Etoile-dev mailing list
Etoile-dev@gna.org
https://mail.gna.org/listinfo/etoile-dev