On Wed, Dec 30, 2009 at 12:48 AM, Paul Davis <paul@xxxxxxxxxxxxxxxxxxxxx> wrote: > On Mon, Dec 28, 2009 at 12:02 PM, Holger Berndt <berndth@xxxxxx> wrote: >> Cross-posting to move the discussion to gtk-devel-list. Anybody interested >> in the topic, please follow up there. >> >> On Do, 24.09.2009 19:23, A. Walton wrote: >> >>>It's definitely something many developers would love to see in Gtk+, >>>but only a few have stepped up to the bat with patches and actually >>>discussed the problem, >> >> Why don't we take the opportunity to discuss the problem now, then? I >> can start by offering my view on how an undo stack should look like, >> and provide a reference implementation as a basis of discussion. > > We've been using a C++ type-safe Undo/Redo stack in Ardour for many > years. It was designed after looking at undo models in various other > applications, and finding them all to have various problems for what > we really needed (this included the GIMP). We've learned a number of > things over the years. > > 1) you need to be able to group individual actions into transactions > 2) serialization/deserialization is good, and hard > 3) its very hard to use only a Memento pattern without running into > efficiency problems > 4) it can be quite hard to correctly implement object lifetime > mamagement for objects involved in callbacks on the undo/redo stack > 5) deciding whether or not to support nested transactions can be important Hi Paul, Interesting discussion, I dont have loads of time to share either but I did have a hell of a time making undo/redo work properly in Glade, have to agree with all of the points above, cheers to point 4 and 5, have some things to add... Particularly point 5, nested transactions; I banged my head around that one for a while and finally did not implement this; my interpretation of nested transactions was something like this: o User initiates action o action goes and modifies data on the model o model data change callback initiates "nested action" a.) it was complex as hell to implement without re-creating commands when the data model changes due to undo/redo or something other than an action (and however nice the api, the complexity spills into the individual action initiating code). b.) I found that if I simply add callbacks to the editors modifying the data model instead of the model itself - I could achieve the same goals using command groups (or "nested transactions"). (i.e. connect to the editor before_commit/after_commit signal and push/pop a command group around the editor's commit phase). Another thing; one interesting feature not present in all undo/redo implementations I've come across (as a user of applications in general) that is present in Glade; is the ->unifies()/->collapse() methods of the GladeCommand; basically it allows you to make abundant changes to the same data set without making a huge unusable command stack (i.e. Glade uses this for instance; to make sure that 15 edits to a string property will only show up as one command). Also finally, it would be nice to see this targeted somewhere below GTK+ in the stack, would be a shame to do all this work and not be able to use it from; say; Clutter apps or such... Cheers, -Tristan > To browse the current implementation: > > http://subversion.ardour.org/svn/ardour2/branches/3.0/libs/pbd/undo.cc > http://subversion.ardour.org/svn/ardour2/branches/3.0/libs/pbd/pbd/undo.h > > I am not suggesting this as an alternative to your proposal, its just > a real life, battle-tested implementation that avoids pre-registration > of actions that can be undone, and allows arbitrary functors to be > used in the undo/redo stack (note that it uses boost::bind for this > purpose). > > --p > _______________________________________________ > gtk-list mailing list > gtk-list@xxxxxxxxx > http://mail.gnome.org/mailman/listinfo/gtk-list > _______________________________________________ gtk-list mailing list gtk-list@xxxxxxxxx http://mail.gnome.org/mailman/listinfo/gtk-list