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

Reply via email to