#include "ardour/vca.h"
#include "ardour/vca_manager.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
using namespace PBD;
using namespace ARDOUR;
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);
}
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);
}
}
/* 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 ();
void
Slavable::assign (boost::shared_ptr<VCA> 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<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)));
}
+
+ AssignmentChange (v, true);
}
void
-Slavable::unassign (boost::shared_ptr<VCA> v)
+Slavable::weak_unassign (boost::weak_ptr<VCA> v)
{
- Glib::Threads::RWLock::WriterLock lm (master_lock);
- (void) unassign_controls (v);
- if (v) {
- _masters.erase (v->number());
- } else {
- _masters.clear ();
+ boost::shared_ptr<VCA> sv (v.lock());
+ if (sv) {
+ unassign (sv);
}
}
-int
-Slavable::assign_controls (boost::shared_ptr<VCA> vca)
+void
+Slavable::unassign (boost::shared_ptr<VCA> v)
{
- boost::shared_ptr<SlavableAutomationControl> slave;
- boost::shared_ptr<AutomationControl> master;
- AutomationType types[] = {
- GainAutomation,
- SoloAutomation,
- MuteAutomation,
- RecEnableAutomation,
- MonitoringAutomation,
- NullAutomation
- };
-
- for (uint32_t n = 0; types[n] != NullAutomation; ++n) {
-
- slave = boost::dynamic_pointer_cast<SlavableAutomationControl> (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> 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> vca)
{
- boost::shared_ptr<SlavableAutomationControl> 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> vca, boost::shared_ptr<SlavableAutomationControl> slave)
+{
boost::shared_ptr<AutomationControl> master;
- AutomationType types[] = {
- GainAutomation,
- SoloAutomation,
- MuteAutomation,
- RecEnableAutomation,
- MonitoringAutomation,
- NullAutomation
- };
-
- for (uint32_t n = 0; types[n] != NullAutomation; ++n) {
-
- slave = boost::dynamic_pointer_cast<SlavableAutomationControl> (automation_control (types[n]));
-
- if (!vca) {
- /* unassign from all */
- if (slave) {
- slave->clear_masters ();
- }
- } else {
- master = vca->automation_control (types[n]);
- if (slave && master) {
- slave->remove_master (master);
- }
- }
+ master = vca->automation_control (slave->parameter());
+ if (!master) {
+ return false;
}
+ slave->add_master (master);
+ return true;
+}
- return 0;
+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);
+ }
+ }
}