Prefer vfork() over system() when opening an URI
[ardour.git] / libs / pbd / pbd / stateful.h
index ab09b7aa84d79b1efd8981cbc17af7f3b3f78dd5..fe2df931479429c6f7ab57347bfddf4146834fe2 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2000-2010 Paul Davis 
+    Copyright (C) 2000-2010 Paul Davis
 
     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
@@ -52,8 +52,8 @@ class LIBPBD_API Stateful {
 
        virtual bool apply_changes (PropertyBase const &);
        PropertyChange apply_changes (PropertyList const &);
-       
-        const OwnedPropertyList& properties() const { return *_properties; }
+
+       const OwnedPropertyList& properties() const { return *_properties; }
 
        void add_property (PropertyBase& s);
 
@@ -70,20 +70,29 @@ class LIBPBD_API Stateful {
        void set_id (const std::string&);
        void reset_id ();
 
-        /* history management */
+       /* 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 ();
        virtual void clear_owned_changes ();
-        PropertyList* get_changes_as_properties (Command *) const;
+       PropertyList* get_changes_as_properties (Command *) const;
        virtual void rdiff (std::vector<Command*> &) const;
-        bool changed() const;
+       bool changed() const;
 
-        /* create a property list from an XMLNode
-         */
-        virtual PropertyList* property_factory (const XMLNode&) const;
+       /* create a property list from an XMLNode */
+       virtual PropertyList* property_factory (const XMLNode&) const;
 
-       /* How stateful's notify of changes to their properties
-        */
+       /* How stateful's notify of changes to their properties */
        PBD::Signal1<void,const PropertyChange&> PropertyChanged;
 
        static int current_state_version;
@@ -92,8 +101,8 @@ class LIBPBD_API Stateful {
        virtual void suspend_property_changes ();
        virtual void resume_property_changes ();
 
-        bool property_changes_suspended() const { return g_atomic_int_get (const_cast<gint*>(&_stateful_frozen)) > 0; }
-        
+       bool property_changes_suspended() const { return g_atomic_int_get (const_cast<gint*>(&_stateful_frozen)) > 0; }
+
   protected:
 
        void add_instant_xml (XMLNode&, const std::string& directory_path);
@@ -101,9 +110,9 @@ class LIBPBD_API Stateful {
        void add_properties (XMLNode &);
 
        PropertyChange set_values (XMLNode const &);
-       
+
        /* derived classes can implement this to do cross-checking
-          of property values after either a PropertyList or XML 
+          of property values after either a PropertyList or XML
           driven property change.
        */
        virtual void post_set (const PropertyChange&) { };
@@ -111,23 +120,28 @@ class LIBPBD_API Stateful {
        XMLNode *_extra_xml;
        XMLNode *_instant_xml;
        PBD::PropertyChange     _pending_changed;
-        Glib::Threads::Mutex _lock;
+       Glib::Threads::Mutex _lock;
 
        std::string _xml_node_name; ///< name of node to use for this object in XML
        OwnedPropertyList* _properties;
 
-        virtual void send_change (const PropertyChange&);
-        /** derived classes can implement this in order to process a property change
-            within thaw() just before send_change() is called.
-        */
-        virtual void mid_thaw (const PropertyChange&) { }
+       virtual void send_change (const PropertyChange&);
+       /** derived classes can implement this in order to process a property change
+           within thaw() just before send_change() is called.
+       */
+       virtual void mid_thaw (const PropertyChange&) { }
+
+       bool regenerate_xml_or_string_ids () const;
 
   private:
+       friend struct ForceIDRegeneration;
+       static Glib::Threads::Private<bool> _regenerate_xml_or_string_ids;
        PBD::ID  _id;
-        gint     _stateful_frozen;
+       gint     _stateful_frozen;
+
+       static void set_regenerate_xml_and_string_ids_in_this_thread (bool yn);
 };
 
 } // namespace PBD
 
 #endif /* __pbd_stateful_h__ */
-