correctly restore VCA-VCA slave/master relationships at session load time
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 4 Mar 2016 21:44:30 +0000 (16:44 -0500)
committerPaul Davis <paul@linuxaudiosystems.com>
Tue, 31 May 2016 19:30:39 +0000 (15:30 -0400)
libs/ardour/ardour/gain_control.h
libs/ardour/ardour/vca_manager.h
libs/ardour/gain_control.cc
libs/ardour/vca_manager.cc

index c44a76dd04bd0a4ad70f27afea16e77239fabc8f..2b472dc8e00887d3f46d8f3f20cd0849ae51e0b2 100644 (file)
@@ -91,12 +91,14 @@ class LIBARDOUR_API GainControl : public AutomationControl {
        typedef std::map<uint32_t,MasterRecord> Masters;
        Masters _masters;
        PBD::ScopedConnectionList masters_connections;
-       std::string _masters_state_string ();
+       std::string masters_string;
+       PBD::ScopedConnection vca_loaded_connection;
 
        gain_t get_value_locked () const;
        gain_t get_master_gain_locked () const;
        void master_going_away (boost::weak_ptr<VCA>);
        void recompute_masters_ratios (double val);
+       void vcas_loaded();
 
        void _set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
 };
index 4e5b54f438edaf1b046a948d21338987edc0f45b..c51336b55857553b786f93f0e8399aea57ff162d 100644 (file)
@@ -50,17 +50,21 @@ class VCAManager : public SessionHandleRef, public PBD::StatefulDestructible
 
        VCAList vcas() const;
 
+       PBD::Signal0<void>          VCAsLoaded;
        PBD::Signal1<void,VCAList&> VCAAdded;
        PBD::Signal1<void,VCAList&> VCARemoved;
 
        XMLNode& get_state();
        int set_state (XMLNode const&, int version);
 
+       bool vcas_loaded() const { return _vcas_loaded; }
+
        static std::string xml_node_name;
 
      private:
        mutable Glib::Threads::Mutex lock;
        VCAList _vcas;
+       bool _vcas_loaded;
 
        void clear ();
 };
index b9c381c406eda2acc272e350ac55e3d59e69a93f..3eff20b1f10bb378885cb6be3e2944a5457ced3f 100644 (file)
@@ -348,22 +348,41 @@ GainControl::set_state (XMLNode const& node, int version)
 
        XMLProperty const* prop = node.property (X_("masters"));
 
-       /* XXX Problem here if we allow VCA's to be slaved to other VCA's .. we
-        * have to load all VCAs first, then call ::set_state() so that
-        * vca_by_number() will succeed.
+       /* Problem here if we allow VCA's to be slaved to other VCA's .. we
+        * have to load all VCAs first, then set up slave/master relationships
+        * once we have them all.
         */
 
        if (prop) {
-               vector<string> masters;
-               split (prop->value(), masters, ',');
+               masters_string = prop->value ();
 
-               for (vector<string>::const_iterator m = masters.begin(); m != masters.end(); ++m) {
-                       boost::shared_ptr<VCA> vca = _session.vca_manager().vca_by_number (PBD::atoi (*m));
-                       if (vca) {
-                               add_master (vca);
-                       }
+               if (_session.vca_manager().vcas_loaded()) {
+                       vcas_loaded ();
+               } else {
+                       _session.vca_manager().VCAsLoaded.connect_same_thread (vca_loaded_connection, boost::bind (&GainControl::vcas_loaded, this));
                }
        }
 
        return 0;
 }
+
+void
+GainControl::vcas_loaded ()
+{
+       if (masters_string.empty()) {
+               return;
+       }
+
+       vector<string> masters;
+       split (masters_string, masters, ',');
+
+       for (vector<string>::const_iterator m = masters.begin(); m != masters.end(); ++m) {
+               boost::shared_ptr<VCA> vca = _session.vca_manager().vca_by_number (PBD::atoi (*m));
+               if (vca) {
+                       add_master (vca);
+               }
+       }
+
+       vca_loaded_connection.disconnect ();
+       masters_string.clear ();
+}
index 9a96dc8a38b389658742c8a87c6642b2d27aae83..71c3fe8029a31957fbf51531f461f5983145bb86 100644 (file)
@@ -33,6 +33,7 @@ string VCAManager::xml_node_name (X_("VCAManager"));
 
 VCAManager::VCAManager (Session& s)
        : SessionHandleRef (s)
+       , _vcas_loaded (false)
 {
 }
 
@@ -140,6 +141,8 @@ VCAManager::set_state (XMLNode const& node, int version)
        XMLNodeList const & children = node.children();
        VCAList vcal;
 
+       _vcas_loaded = false;
+
        for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
                if ((*i)->name() == VCA::xml_node_name) {
                        boost::shared_ptr<VCA> vca = boost::shared_ptr<VCA> (new VCA (_session, **i, version));
@@ -158,6 +161,9 @@ VCAManager::set_state (XMLNode const& node, int version)
                }
        }
 
+       _vcas_loaded = true;
+
+       VCAsLoaded (); /* EMIT SIGNAL */
        VCAAdded (vcal); /* EMIT SIGNAL */
 
        return 0;