summaryrefslogtreecommitdiff
path: root/libs/pbd/undo.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2008-12-12 14:43:24 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2008-12-12 14:43:24 +0000
commitbc89fe0147c04b67141936d109c00dfd4d69cc4b (patch)
tree544ff450c40fe1f43853a8420228a26f27f1eafb /libs/pbd/undo.cc
parent30daaebaa2d90d6b0e8673143ccc3cacd7bd1753 (diff)
most of the 2.X->3.0 commit (up to rev 4299) except for gtk2_ardour/editor_canvas.cc; builds and runs and does a few specific things but expect it to be buggy for a while yet
git-svn-id: svn://localhost/ardour2/branches/3.0@4313 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/pbd/undo.cc')
-rw-r--r--libs/pbd/undo.cc67
1 files changed, 57 insertions, 10 deletions
diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc
index f04b4d9431..5365a98146 100644
--- a/libs/pbd/undo.cc
+++ b/libs/pbd/undo.cc
@@ -18,14 +18,12 @@
$Id$
*/
-#include <iostream>
#include <string>
#include <sstream>
#include <time.h>
#include <pbd/undo.h>
#include <pbd/xml++.h>
-#include <pbd/shiva.h>
#include <sigc++/bind.h>
@@ -79,8 +77,10 @@ UndoTransaction::operator= (const UndoTransaction& rhs)
void
UndoTransaction::add_command (Command *const action)
{
- /* catch death */
- new PBD::ProxyShiva<Command,UndoTransaction> (*action, *this, &command_death);
+ /* catch death of command (e.g. caused by death of object to
+ which it refers.
+ */
+ shivas.push_back (new PBD::ProxyShiva<Command,UndoTransaction> (*action, *this, &command_death));
actions.push_back (action);
}
@@ -90,6 +90,21 @@ UndoTransaction::remove_command (Command* const action)
actions.remove (action);
}
+void
+UndoTransaction::about_to_explicitly_delete ()
+{
+ /* someone is going to call our destructor and its not Shiva,
+ the god of destruction and chaos. This happens when an UndoHistory
+ is pruning itself. we must remove Shivas to avoid the god
+ striking us down a second time, unnecessarily and illegally.
+ */
+
+ for (list<PBD::ProxyShiva<Command,UndoTransaction>*>::iterator i = shivas.begin(); i != shivas.end(); ++i) {
+ delete *i;
+ }
+ shivas.clear ();
+}
+
bool
UndoTransaction::empty () const
{
@@ -154,27 +169,59 @@ UndoHistory::UndoHistory ()
}
void
-UndoHistory::set_depth (int32_t d)
+UndoHistory::set_depth (uint32_t d)
{
+ UndoTransaction* ut;
+ uint32_t current_depth = UndoList.size();
+
_depth = d;
- while (_depth > 0 && UndoList.size() > (uint32_t) _depth) {
- UndoList.pop_front ();
+ if (d > current_depth) {
+ /* not even transactions to meet request */
+ return;
+ }
+
+ if (_depth > 0) {
+
+ uint32_t cnt = current_depth - d;
+
+ while (cnt--) {
+ ut = UndoList.front();
+ UndoList.pop_front ();
+ ut->about_to_explicitly_delete ();
+ delete ut;
+ }
}
}
void
UndoHistory::add (UndoTransaction* const ut)
{
+ uint32_t current_depth = UndoList.size();
+
ut->GoingAway.connect (bind (mem_fun (*this, &UndoHistory::remove), ut));
- while (_depth > 0 && UndoList.size() > (uint32_t) _depth) {
- UndoList.pop_front ();
+ /* if the current undo history is larger than or equal to the currently
+ requested depth, then pop off at least 1 element to make space
+ at the back for new one.
+ */
+
+ if ((_depth > 0) && current_depth && (current_depth >= _depth)) {
+
+ uint32_t cnt = 1 + (current_depth - _depth);
+
+ while (cnt--) {
+ UndoTransaction* ut;
+ ut = UndoList.front ();
+ UndoList.pop_front ();
+ ut->about_to_explicitly_delete ();
+ delete ut;
+ }
}
UndoList.push_back (ut);
- /* we are now owners of the transaction */
+ /* we are now owners of the transaction and must delete it when finished with it */
Changed (); /* EMIT SIGNAL */
}