Remove Input-meter special-case
[ardour.git] / libs / ardour / slavable.cc
index 5cb8e8ddce1e84e14d5ab5ef721267163deb815f..7d8109eac62ee1e3f454d79df7369f7aa3207592 100644 (file)
@@ -30,7 +30,7 @@
 #include "ardour/vca.h"
 #include "ardour/vca_manager.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace PBD;
 using namespace ARDOUR;
@@ -53,7 +53,7 @@ Slavable::get_state () const
        Glib::Threads::RWLock::ReaderLock lm (master_lock);
        for (std::set<uint32_t>::const_iterator i = _masters.begin(); i != _masters.end(); ++i) {
                child = new XMLNode (X_("Master"));
-               child->add_property (X_("number"), to_string (*i, std::dec));
+               child->set_property (X_("number"), *i);
                node->add_child_nocopy (*child);
        }
 
@@ -72,9 +72,8 @@ Slavable::set_state (XMLNode const& node, int version)
 
        for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
                if ((*i)->name() == X_("Master")) {
-                       XMLProperty const* prop = (*i)->property (X_("number"));
-                       if (prop) {
-                               uint32_t n = atoi (prop->value());
+                       uint32_t n;
+                       if ((*i)->get_property (X_("number"), n)) {
                                _masters.insert (n);
                        }
                }
@@ -83,7 +82,6 @@ Slavable::set_state (XMLNode const& node, int version)
        return 0;
 }
 
-
 int
 Slavable::do_assign (VCAManager* manager)
 {
@@ -104,8 +102,16 @@ Slavable::do_assign (VCAManager* manager)
 
        /* now that we've released the lock, we can do the assignments */
 
-       for (std::vector<boost::shared_ptr<VCA> >::iterator v = vcas.begin(); v != vcas.end(); ++v) {
-               assign (*v);
+       if (!vcas.empty()) {
+
+               for (std::vector<boost::shared_ptr<VCA> >::iterator v = vcas.begin(); v != vcas.end(); ++v) {
+                       assign (*v);
+               }
+
+               SlavableControlList scl = slavables ();
+               for (SlavableControlList::iterator i = scl.begin(); i != scl.end(); ++i) {
+                               (*i)->use_saved_master_ratios ();
+               }
        }
 
        assign_connection.disconnect ();
@@ -117,19 +123,23 @@ void
 Slavable::assign (boost::shared_ptr<VCA> v)
 {
        assert (v);
-       Glib::Threads::RWLock::WriterLock lm (master_lock);
-       if (assign_controls (v) == 0) {
-               _masters.insert (v->number());
-       }
+       {
+               Glib::Threads::RWLock::WriterLock lm (master_lock);
+               if (assign_controls (v)) {
+                       _masters.insert (v->number());
+               }
 
-       /* Do NOT use ::unassign() because it will store a
-        * boost::shared_ptr<VCA> in the functor, leaving a dangling ref to the
-        * VCA.
-        */
+               /* Do NOT use ::unassign() because it will store a
+                * boost::shared_ptr<VCA> in the functor, leaving a dangling ref to the
+                * VCA.
+                */
 
 
-       v->Drop.connect_same_thread (unassign_connections, boost::bind (&Slavable::weak_unassign, this, boost::weak_ptr<VCA>(v)));
-       v->DropReferences.connect_same_thread (unassign_connections, boost::bind (&Slavable::weak_unassign, this, boost::weak_ptr<VCA>(v)));
+               v->Drop.connect_same_thread (unassign_connections, boost::bind (&Slavable::weak_unassign, this, boost::weak_ptr<VCA>(v)));
+               v->DropReferences.connect_same_thread (unassign_connections, boost::bind (&Slavable::weak_unassign, this, boost::weak_ptr<VCA>(v)));
+       }
+
+       AssignmentChange (v, true);
 }
 
 void
@@ -144,67 +154,62 @@ Slavable::weak_unassign (boost::weak_ptr<VCA> v)
 void
 Slavable::unassign (boost::shared_ptr<VCA> v)
 {
-       Glib::Threads::RWLock::WriterLock lm (master_lock);
-       (void) unassign_controls (v);
-       if (v) {
-               _masters.erase (v->number());
-       } else {
-               _masters.clear ();
+       {
+               Glib::Threads::RWLock::WriterLock lm (master_lock);
+
+               unassign_controls (v);
+               if (v) {
+                       _masters.erase (v->number());
+               } else {
+                       _masters.clear ();
+               }
        }
+       AssignmentChange (v, false);
 }
 
-/* Gain, solo & mute are currently the only controls that are
- * automatically slaved to the master's own equivalent controls.
- */
-
-static AutomationType auto_slave_types[] = {
-       GainAutomation,
-       SoloAutomation,
-       MuteAutomation,
-       NullAutomation
-};
-
-int
+bool
 Slavable::assign_controls (boost::shared_ptr<VCA> vca)
 {
-       boost::shared_ptr<SlavableAutomationControl> slave;
-       boost::shared_ptr<AutomationControl> master;
-
-       for (uint32_t n = 0; auto_slave_types[n] != NullAutomation; ++n) {
-
-               slave = boost::dynamic_pointer_cast<SlavableAutomationControl> (automation_control (auto_slave_types[n]));
-               master = vca->automation_control (auto_slave_types[n]);
-
-               if (slave && master) {
-                       slave->add_master (master);
-               }
+       bool rv = false;
+       SlavableControlList scl = slavables ();
+       for (SlavableControlList::iterator i = scl.begin(); i != scl.end(); ++i) {
+               rv |= assign_control (vca, *i);
        }
-
-       return 0;
+       return rv;
 }
 
-int
+void
 Slavable::unassign_controls (boost::shared_ptr<VCA> vca)
 {
-       boost::shared_ptr<SlavableAutomationControl> slave;
-       boost::shared_ptr<AutomationControl> master;
-
-       for (uint32_t n = 0; auto_slave_types[n] != NullAutomation; ++n) {
+       SlavableControlList scl = slavables ();
+       for (SlavableControlList::iterator i = scl.begin(); i != scl.end(); ++i) {
+               unassign_control (vca, *i);
+       }
+}
 
-               slave = boost::dynamic_pointer_cast<SlavableAutomationControl> (automation_control (auto_slave_types[n]));
+bool
+Slavable::assign_control (boost::shared_ptr<VCA> vca, boost::shared_ptr<SlavableAutomationControl> slave)
+{
+       boost::shared_ptr<AutomationControl> master;
+       master = vca->automation_control (slave->parameter());
+       if (!master) {
+               return false;
+       }
+       slave->add_master (master);
+       return true;
+}
 
-               if (!vca) {
-                       /* unassign from all */
-                       if (slave) {
-                               slave->clear_masters ();
-                       }
-               } else {
-                       master = vca->automation_control (auto_slave_types[n]);
-                       if (slave && master) {
-                               slave->remove_master (master);
-                       }
+void
+Slavable::unassign_control (boost::shared_ptr<VCA> vca, boost::shared_ptr<SlavableAutomationControl> slave)
+{
+       if (!vca) {
+               /* unassign from all */
+               slave->clear_masters ();
+       } else {
+               boost::shared_ptr<AutomationControl> master;
+               master = vca->automation_control (slave->parameter());
+               if (master) {
+                       slave->remove_master (master);
                }
        }
-
-       return 0;
 }