diff options
author | Carl Hetherington <carl@carlh.net> | 2010-08-26 01:44:11 +0000 |
---|---|---|
committer | Carl Hetherington <carl@carlh.net> | 2010-08-26 01:44:11 +0000 |
commit | c243a02c998f585295f2179657673e2cf0fa4428 (patch) | |
tree | 1a18ca901b5f7fb1270938e2fb62f7e2636400ef /libs/pbd/pbd | |
parent | df2fd9491904aba95e08e1e26552be609530ee83 (diff) |
Fix crossfade undo using the stateful diff system. Fixes #3257.
git-svn-id: svn://localhost/ardour2/branches/3.0@7694 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/pbd/pbd')
-rw-r--r-- | libs/pbd/pbd/command.h | 4 | ||||
-rw-r--r-- | libs/pbd/pbd/property_basics.h | 2 | ||||
-rw-r--r-- | libs/pbd/pbd/sequence_property.h | 31 | ||||
-rw-r--r-- | libs/pbd/pbd/stateful.h | 2 | ||||
-rw-r--r-- | libs/pbd/pbd/stateful_diff_command.h | 2 |
5 files changed, 30 insertions, 11 deletions
diff --git a/libs/pbd/pbd/command.h b/libs/pbd/pbd/command.h index c6c3c8d3fd..db4d2bbd81 100644 --- a/libs/pbd/pbd/command.h +++ b/libs/pbd/pbd/command.h @@ -43,6 +43,10 @@ public: virtual XMLNode &get_state(); virtual int set_state(const XMLNode&, int /*version*/) { /* noop */ return 0; } + virtual bool empty () const { + return false; + } + protected: Command() {} Command(const std::string& name) : _name(name) {} diff --git a/libs/pbd/pbd/property_basics.h b/libs/pbd/pbd/property_basics.h index cfae36df20..145e84abfc 100644 --- a/libs/pbd/pbd/property_basics.h +++ b/libs/pbd/pbd/property_basics.h @@ -103,7 +103,7 @@ public: virtual void get_changes_as_properties (PropertyList& changes, Command *) const = 0; /** Collect StatefulDiffCommands for changes to anything that we own */ - virtual void rdiff (std::vector<StatefulDiffCommand*> &) const {} + virtual void rdiff (std::vector<Command*> &) const {} /** Look in an XML node written by get_changes_as_xml and, if XML from this property * is found, create a property with the changes from the XML. diff --git a/libs/pbd/pbd/sequence_property.h b/libs/pbd/pbd/sequence_property.h index 5b37d7a0fc..4b494d4a8d 100644 --- a/libs/pbd/pbd/sequence_property.h +++ b/libs/pbd/pbd/sequence_property.h @@ -31,6 +31,7 @@ #include "pbd/id.h" #include "pbd/property_basics.h" #include "pbd/property_list.h" +#include "pbd/stateful_diff_command.h" namespace PBD { @@ -80,8 +81,6 @@ class SequenceProperty : public PropertyBase SequenceProperty (PropertyID id, const boost::function<void(const ChangeRecord&)>& update) : PropertyBase (id), _update_callback (update) {} - virtual typename Container::value_type lookup_id (const PBD::ID&) const = 0; - void invert () { _changes.removed.swap (_changes.added); } @@ -97,18 +96,25 @@ class SequenceProperty : public PropertyBase for (typename ChangeContainer::iterator i = _changes.added.begin(); i != _changes.added.end(); ++i) { XMLNode* add_node = new XMLNode ("Add"); child->add_child_nocopy (*add_node); - add_node->add_property ("id", (*i)->id().to_s()); + get_content_as_xml (*i, *add_node); } } if (!_changes.removed.empty()) { for (typename ChangeContainer::iterator i = _changes.removed.begin(); i != _changes.removed.end(); ++i) { XMLNode* remove_node = new XMLNode ("Remove"); child->add_child_nocopy (*remove_node); - remove_node->add_property ("id", (*i)->id().to_s()); + get_content_as_xml (*i, *remove_node); } } } + /** Get a representation of one of our items as XML. The representation must be sufficient to + * restore the item's state later; an ID is ok if someone else is storing the item state, + * otherwise it needs to be the full state. The supplied node is an <Add> or <Remove> + * which this method can either add properties or children to. + */ + virtual void get_content_as_xml (typename ChangeContainer::value_type, XMLNode &) const = 0; + bool set_value (XMLNode const &) { /* XXX: not used, but probably should be */ assert (false); @@ -191,11 +197,10 @@ class SequenceProperty : public PropertyBase XMLNodeList const & grandchildren = (*i)->children (); for (XMLNodeList::const_iterator j = grandchildren.begin(); j != grandchildren.end(); ++j) { - XMLProperty const * prop = (*j)->property ("id"); - assert (prop); - PBD::ID id (prop->value ()); - typename Container::value_type v = lookup_id (id); + + typename Container::value_type v = get_content_from_xml (**j); assert (v); + if ((*j)->name() == "Add") { p->_changes.added.insert (v); } else if ((*j)->name() == "Remove") { @@ -206,13 +211,16 @@ class SequenceProperty : public PropertyBase return p; } + /** Given an <Add> or <Remove> node as passed into get_content_to_xml, obtain an item */ + virtual typename Container::value_type get_content_from_xml (XMLNode const & node) const = 0; + void clear_owned_changes () { for (typename Container::iterator i = begin(); i != end(); ++i) { (*i)->clear_changes (); } } - void rdiff (std::vector<StatefulDiffCommand*>& cmds) const { + void rdiff (std::vector<Command*>& cmds) const { for (typename Container::const_iterator i = begin(); i != end(); ++i) { if ((*i)->changed ()) { StatefulDiffCommand* sdc = new StatefulDiffCommand (*i); @@ -255,6 +263,11 @@ class SequenceProperty : public PropertyBase return _val.erase (f, l); } + void remove (const typename Container::value_type& v) { + _changes.remove (v); + _val.remove (v); + } + void push_back (const typename Container::value_type& v) { _changes.add (v); _val.push_back (v); diff --git a/libs/pbd/pbd/stateful.h b/libs/pbd/pbd/stateful.h index 5c1f079bc6..735ffbdc4a 100644 --- a/libs/pbd/pbd/stateful.h +++ b/libs/pbd/pbd/stateful.h @@ -70,7 +70,7 @@ class Stateful { void clear_changes (); virtual void clear_owned_changes (); PropertyList* get_changes_as_properties (Command *) const; - virtual void rdiff (std::vector<StatefulDiffCommand*> &) const; + virtual void rdiff (std::vector<Command*> &) const; bool changed() const; /* create a property list from an XMLNode diff --git a/libs/pbd/pbd/stateful_diff_command.h b/libs/pbd/pbd/stateful_diff_command.h index 2d5c234d76..2a213d7a17 100644 --- a/libs/pbd/pbd/stateful_diff_command.h +++ b/libs/pbd/pbd/stateful_diff_command.h @@ -45,6 +45,8 @@ public: XMLNode& get_state (); + bool empty () const; + private: boost::weak_ptr<Stateful> _object; ///< the object in question PBD::PropertyList* _changes; ///< property changes to execute this command |