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
This commit is contained in:
Sampo Savolainen 2007-05-21 19:13:42 +00:00
parent 2f1bcda135
commit 879d64ea1f
2 changed files with 111 additions and 21 deletions

View file

@ -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 ();

View file

@ -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 (child->name() == X_("Send") || child->name() == X_("Insert")) {
redirect_nodes.push_back(child);
}
}
_set_redirect_states(redirect_nodes);
if (!IO::ports_legal) {
for (niter = nlist.begin(); niter != nlist.end(); ++niter){
child = *niter;
// All redirects (sends and inserts) have been applied already
deferred_state->add_child_copy (*child);
} else {
add_redirect_from_xml (*child);
}
} else if (child->name() == X_("Insert")) {
if (!IO::ports_legal) {
deferred_state->add_child_copy (*child);
} else {
add_redirect_from_xml (*child);
}
} 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<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 ()
{