X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fslavable.cc;h=7d8109eac62ee1e3f454d79df7369f7aa3207592;hb=9775c5c9f1b81340f3177ede038f02faed71c887;hp=4a759f5fef41a20abd567a74d314e731cf16ec3b;hpb=f485cfa324717f57b9f820f43f1b53307b96a8b9;p=ardour.git diff --git a/libs/ardour/slavable.cc b/libs/ardour/slavable.cc index 4a759f5fef..7d8109eac6 100644 --- a/libs/ardour/slavable.cc +++ b/libs/ardour/slavable.cc @@ -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::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); } } @@ -103,8 +102,16 @@ Slavable::do_assign (VCAManager* manager) /* now that we've released the lock, we can do the assignments */ - for (std::vector >::iterator v = vcas.begin(); v != vcas.end(); ++v) { - assign (*v); + if (!vcas.empty()) { + + for (std::vector >::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 (); @@ -115,72 +122,94 @@ Slavable::do_assign (VCAManager* manager) void Slavable::assign (boost::shared_ptr v) { - Glib::Threads::RWLock::WriterLock lm (master_lock); - if (assign_controls (v) == 0) { - _masters.insert (v->number()); + assert (v); + { + 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 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(v))); + v->DropReferences.connect_same_thread (unassign_connections, boost::bind (&Slavable::weak_unassign, this, boost::weak_ptr(v))); } + + AssignmentChange (v, true); } void -Slavable::unassign (boost::shared_ptr v) +Slavable::weak_unassign (boost::weak_ptr v) { - Glib::Threads::RWLock::WriterLock lm (master_lock); - (void) unassign_controls (v); - _masters.erase (v->number()); + boost::shared_ptr sv (v.lock()); + if (sv) { + unassign (sv); + } } -int -Slavable::assign_controls (boost::shared_ptr vca) +void +Slavable::unassign (boost::shared_ptr v) { - boost::shared_ptr slave; - boost::shared_ptr master; - AutomationType types[] = { - GainAutomation, - SoloAutomation, - MuteAutomation, - RecEnableAutomation, - MonitoringAutomation, - NullAutomation - }; - - for (uint32_t n = 0; types[n] != NullAutomation; ++n) { - - slave = boost::dynamic_pointer_cast (automation_control (types[n])); - master = vca->automation_control (types[n]); - - if (slave && master) { - slave->add_master (master); + { + Glib::Threads::RWLock::WriterLock lm (master_lock); + + unassign_controls (v); + if (v) { + _masters.erase (v->number()); + } else { + _masters.clear (); } } + AssignmentChange (v, false); +} - return 0; +bool +Slavable::assign_controls (boost::shared_ptr vca) +{ + bool rv = false; + SlavableControlList scl = slavables (); + for (SlavableControlList::iterator i = scl.begin(); i != scl.end(); ++i) { + rv |= assign_control (vca, *i); + } + return rv; } -int +void Slavable::unassign_controls (boost::shared_ptr vca) { - boost::shared_ptr slave; + SlavableControlList scl = slavables (); + for (SlavableControlList::iterator i = scl.begin(); i != scl.end(); ++i) { + unassign_control (vca, *i); + } +} + +bool +Slavable::assign_control (boost::shared_ptr vca, boost::shared_ptr slave) +{ boost::shared_ptr master; - AutomationType types[] = { - GainAutomation, - SoloAutomation, - MuteAutomation, - RecEnableAutomation, - MonitoringAutomation, - NullAutomation - }; - - for (uint32_t n = 0; types[n] != NullAutomation; ++n) { - - slave = boost::dynamic_pointer_cast (automation_control (types[n])); - if (!vca) { - /* unassign from all */ - slave->clear_masters (); - } else { + master = vca->automation_control (slave->parameter()); + if (!master) { + return false; + } + slave->add_master (master); + return true; +} + +void +Slavable::unassign_control (boost::shared_ptr vca, boost::shared_ptr slave) +{ + if (!vca) { + /* unassign from all */ + slave->clear_masters (); + } else { + boost::shared_ptr master; + master = vca->automation_control (slave->parameter()); + if (master) { slave->remove_master (master); } } - - return 0; } -