summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSampo Savolainen <v2@iki.fi>2007-05-21 19:13:42 +0000
committerSampo Savolainen <v2@iki.fi>2007-05-21 19:13:42 +0000
commit879d64ea1f6863dc10cc3c9cb45583eaecc0556c (patch)
tree07995452451645088f04b1b97006a6dfc125c604
parent2f1bcda13587b0485da9ebab2d23c0dc2780acb3 (diff)
Make the set_state() function respect redirects already present on the route. Still work to be done to resurrect set_state() for the post
only-for-constructor era. git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@1888 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--libs/ardour/ardour/route.h3
-rw-r--r--libs/ardour/route.cc125
2 files changed, 109 insertions, 19 deletions
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index 442c006e9b..9bdd2cbca5 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -314,7 +314,8 @@ class Route : public IO
uint32_t pans_required() const;
uint32_t n_process_buffers ();
- virtual int _set_state (const XMLNode&, bool call_base);
+ virtual int _set_state (const XMLNode&, bool call_base);
+ virtual void _set_redirect_states (const XMLNodeList&);
private:
void init ();
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 79894bdd33..ad3077d9a0 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -1674,34 +1674,27 @@ Route::_set_state (const XMLNode& node, bool call_base)
break;
}
}
+
+ XMLNodeList redirect_nodes;
for (niter = nlist.begin(); niter != nlist.end(); ++niter){
child = *niter;
- if (child->name() == X_("Send")) {
-
-
- if (!IO::ports_legal) {
+ if (child->name() == X_("Send") || child->name() == X_("Insert")) {
+ redirect_nodes.push_back(child);
+ }
- deferred_state->add_child_copy (*child);
+ }
- } else {
- add_redirect_from_xml (*child);
- }
+ _set_redirect_states(redirect_nodes);
- } else if (child->name() == X_("Insert")) {
-
- if (!IO::ports_legal) {
-
- deferred_state->add_child_copy (*child);
- } else {
-
- add_redirect_from_xml (*child);
- }
+ for (niter = nlist.begin(); niter != nlist.end(); ++niter){
+ child = *niter;
+ // All redirects (sends and inserts) have been applied already
- } else if (child->name() == X_("Automation")) {
+ if (child->name() == X_("Automation")) {
if ((prop = child->property (X_("path"))) != 0) {
load_automation (prop->value());
@@ -1759,6 +1752,102 @@ Route::_set_state (const XMLNode& node, bool call_base)
}
void
+Route::_set_redirect_states(const XMLNodeList &nlist)
+{
+ XMLNodeConstIterator niter;
+ char buf[64];
+
+ RedirectList::iterator i, o;
+
+ // Iterate through existing redirects, remove those which are not in the state list
+ for (i = _redirects.begin(); i != _redirects.end(); ) {
+ RedirectList::iterator tmp = i;
+ ++tmp;
+
+ bool redirectInStateList = false;
+
+ (*i)->id().print (buf, sizeof (buf));
+
+
+ for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+
+ if (strncmp(buf,(*niter)->child(X_("Redirect"))->child(X_("IO"))->property(X_("id"))->value().c_str(), sizeof(buf)) == 0) {
+ redirectInStateList = true;
+ break;
+ }
+ }
+
+ if (!redirectInStateList) {
+ remove_redirect ( *i, this);
+ }
+
+
+ i = tmp;
+ }
+
+
+ // Iterate through state list and make sure all redirects are on the track and in the correct order,
+ // set the state of existing redirects according to the new state on the same go
+ i = _redirects.begin();
+ for (niter = nlist.begin(); niter != nlist.end(); ++niter, ++i) {
+
+ // Check whether the next redirect in the list
+ o = i;
+
+ while (o != _redirects.end()) {
+ (*o)->id().print (buf, sizeof (buf));
+ if ( strncmp(buf, (*niter)->child(X_("Redirect"))->child(X_("IO"))->property(X_("id"))->value().c_str(), sizeof(buf)) == 0)
+ break;
+ ++o;
+ }
+
+ if (o == _redirects.end()) {
+ // If the redirect (*niter) is not on the route, we need to create it
+ // and move it to the correct location
+
+ RedirectList::iterator prev_last = _redirects.end();
+ --prev_last; // We need this to check whether adding succeeded
+
+ add_redirect_from_xml (**niter);
+
+ RedirectList::iterator last = _redirects.end();
+ --last;
+
+ if (prev_last == last) {
+ cerr << "Could not fully restore state as some redirects were not possible to create" << endl;
+ continue;
+
+ }
+
+ boost::shared_ptr<Redirect> tmp = (*last);
+ // remove the redirect from the wrong location
+ _redirects.erase(last);
+ // insert the new redirect at the current location
+ _redirects.insert(i, tmp);
+
+ --i; // move pointer to the newly inserted redirect
+ continue;
+ }
+
+ // We found the redirect (*niter) on the route, first we must make sure the redirect
+ // is at the location provided in the XML state
+ if (i != o) {
+ boost::shared_ptr<Redirect> tmp = (*o);
+ // remove the old copy
+ _redirects.erase(o);
+ // insert the redirect at the correct location
+ _redirects.insert(i, tmp);
+
+ --i; // move pointer so it points to the right redirect
+ }
+
+ (*i)->set_state( (**niter) );
+ }
+
+ redirects_changed(this);
+}
+
+void
Route::curve_reallocate ()
{
// _gain_automation_curve.finish_resize ();