diff --git a/libs/pbd/pbd/stateful.h b/libs/pbd/pbd/stateful.h index 8a86e47285..0207cfcf0c 100644 --- a/libs/pbd/pbd/stateful.h +++ b/libs/pbd/pbd/stateful.h @@ -70,6 +70,17 @@ class LIBPBD_API Stateful { void set_id (const std::string&); void reset_id (); + /* RAII structure to manage thread-local ID regeneration. + */ + struct ForceIDRegeneration { + ForceIDRegeneration () { + set_regenerate_xml_and_string_ids_in_this_thread (true); + } + ~ForceIDRegeneration () { + set_regenerate_xml_and_string_ids_in_this_thread (false); + } + }; + /* history management */ void clear_changes (); @@ -121,11 +132,14 @@ class LIBPBD_API Stateful { virtual void mid_thaw (const PropertyChange&) { } private: + friend struct ForceIDRegeneration; + static Glib::Threads::Private regenerate_xml_or_string_ids; PBD::ID _id; gint _stateful_frozen; + + static void set_regenerate_xml_and_string_ids_in_this_thread (bool yn); }; } // namespace PBD #endif /* __pbd_stateful_h__ */ - diff --git a/libs/pbd/stateful.cc b/libs/pbd/stateful.cc index 2cc40ff6a9..628594891b 100644 --- a/libs/pbd/stateful.cc +++ b/libs/pbd/stateful.cc @@ -44,6 +44,10 @@ namespace PBD { int Stateful::current_state_version = 0; int Stateful::loading_state_version = 0; +static void do_not_delete (void*) { } + +Glib::Threads::Private Stateful::regenerate_xml_or_string_ids (do_not_delete); + Stateful::Stateful () : _extra_xml (0) , _instant_xml (0) @@ -382,6 +386,11 @@ Stateful::set_id (const XMLNode& node) { const XMLProperty* prop; + if (regenerate_xml_or_string_ids.get()) { + reset_id (); + return true; + } + if ((prop = node.property ("id")) != 0) { _id = prop->value (); return true; @@ -399,7 +408,17 @@ Stateful::reset_id () void Stateful::set_id (const string& str) { - _id = str; + if (regenerate_xml_or_string_ids.get()) { + reset_id (); + } else { + _id = str; + } +} + +void +Stateful::set_regenerate_xml_and_string_ids_in_this_thread (bool yn) +{ + regenerate_xml_or_string_ids.set (&yn); } } // namespace PBD