From 879d64ea1f6863dc10cc3c9cb45583eaecc0556c Mon Sep 17 00:00:00 2001 From: Sampo Savolainen Date: Mon, 21 May 2007 19:13:42 +0000 Subject: [PATCH] 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 --- libs/ardour/ardour/route.h | 3 +- libs/ardour/route.cc | 125 +++++++++++++++++++++++++++++++------ 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()); @@ -1758,6 +1751,102 @@ Route::_set_state (const XMLNode& node, bool call_base) return 0; } +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 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 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 () { -- 2.30.2