diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc index fc961b2820..98ae6e76ea 100644 --- a/libs/ardour/location.cc +++ b/libs/ardour/location.cc @@ -29,6 +29,7 @@ #include "pbd/stl_delete.h" #include "pbd/xml++.h" #include "pbd/enumwriter.h" +#include "pbd/statefulidpredicates.h" #include "ardour/location.h" #include "ardour/midi_scene_change.h" @@ -610,6 +611,8 @@ Location::set_state (const XMLNode& node, int version) } if (!set_id (node)) { + // Old versions did not write ids for locations: make a new one. + reset_id(); warning << _("XML node for Location has no ID information") << endmsg; } @@ -1056,21 +1059,20 @@ Locations::set_state (const XMLNode& node, int version) try { + Location* loc = 0; XMLProperty const * prop_id = (*niter)->property ("id"); - assert (prop_id); - PBD::ID id (prop_id->value ()); + if (prop_id) { + LocationList::const_iterator i = std::find_if( + locations.begin(), locations.end(), + PBD::StatefulIdEquals(prop_id->value())); - LocationList::const_iterator i = locations.begin(); - while (i != locations.end () && (*i)->id() != id) { - ++i; + if (i != locations.end()) { + /* we can re-use an old Location object */ + loc = *i; + loc->set_state (**niter, version); + } } - - Location* loc; - if (i != locations.end()) { - /* we can re-use an old Location object */ - loc = *i; - loc->set_state (**niter, version); - } else { + if (!loc) { loc = new Location (_session, **niter); } diff --git a/libs/pbd/pbd/statefulidpredicates.h b/libs/pbd/pbd/statefulidpredicates.h new file mode 100644 index 0000000000..d1c1497562 --- /dev/null +++ b/libs/pbd/pbd/statefulidpredicates.h @@ -0,0 +1,59 @@ +/* + Copyright (C) 2015 Paul Davis + Author: Sakari Bergen + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __pbd_statefulidpredicate_h__ +#define __pbd_statefulidpredicate_h__ + +#include "pbd/libpbd_visibility.h" +#include "pbd/id.h" +#include "pbd/stateful.h" + +namespace PBD { + +struct LIBPBD_TEMPLATE_MEMBER_API StatefulIdEquals +{ + StatefulIdEquals(ID const & id) + : id(id) + {} + + template + bool operator() (StatefulPtr p) + { + return p && compare(*p); + } + + bool operator() (Stateful const & s) + { + return compare(s); + } + +private: + + bool compare(Stateful const & s) + { + return s.id() == id; + } + + ID const & id; +}; + +} // namespace PBD + +#endif // __pbd_statefulidpredicate_h__