From 5dc54c91c76b02f8de9c5af4641667882a27b254 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 20 Oct 2017 02:13:23 +0200 Subject: Prevent recursive VCA assignments The GUI so far only prevents direct connections VCA 1 > VCA 2 > VCA 1, but does not recurse VCA 1 > VCA 2 > VCA 3 > VCA 1 --- libs/ardour/ardour/slavable.h | 7 ++++++- libs/ardour/ardour/vca.h | 6 ++++-- libs/ardour/slavable.cc | 26 ++++++++++++++++++++++++++ libs/ardour/vca.cc | 11 +++++++++++ 4 files changed, 47 insertions(+), 3 deletions(-) (limited to 'libs/ardour') diff --git a/libs/ardour/ardour/slavable.h b/libs/ardour/ardour/slavable.h index 6e584b2128..91c96edb1e 100644 --- a/libs/ardour/ardour/slavable.h +++ b/libs/ardour/ardour/slavable.h @@ -51,7 +51,7 @@ public: XMLNode& get_state () const; int set_state (XMLNode const&, int); - void assign (boost::shared_ptr); + virtual void assign (boost::shared_ptr); void unassign (boost::shared_ptr); PBD::Signal2,bool> AssignmentChange; @@ -63,6 +63,11 @@ public: /* signal sent VCAManager once assignment is possible */ static PBD::Signal1 Assign; + std::vector > masters (VCAManager*) const; + + /** recursively test for master assignment to given VCA */ + bool assigned_to (VCAManager*, boost::shared_ptr) const; + protected: virtual SlavableControlList slavables () const = 0; diff --git a/libs/ardour/ardour/vca.h b/libs/ardour/ardour/vca.h index 49bb575e1d..f5f15d5e33 100644 --- a/libs/ardour/ardour/vca.h +++ b/libs/ardour/ardour/vca.h @@ -64,8 +64,10 @@ class LIBARDOUR_API VCA : public Stripable, /* Slavable API */ - bool slaved_to (boost::shared_ptr) const; - bool slaved () const; + void assign (boost::shared_ptr); + + bool slaved_to (boost::shared_ptr) const; + bool slaved () const; /* Soloable API */ diff --git a/libs/ardour/slavable.cc b/libs/ardour/slavable.cc index 7d8109eac6..155fd4f736 100644 --- a/libs/ardour/slavable.cc +++ b/libs/ardour/slavable.cc @@ -60,6 +60,32 @@ Slavable::get_state () const return *node; } +std::vector > +Slavable::masters (VCAManager* manager) const +{ + std::vector > rv; + Glib::Threads::RWLock::ReaderLock lm (master_lock); + for (std::set::const_iterator i = _masters.begin(); i != _masters.end(); ++i) { + rv.push_back (manager->vca_by_number (*i)); + } + return rv; +} + +bool +Slavable::assigned_to (VCAManager* manager, boost::shared_ptr mst) const +{ + if (mst.get () == this) { + return true; + } + std::vector > ml = mst->masters (manager); + for (std::vector >::const_iterator i = ml.begin (); i != ml.end(); ++i) { + if (assigned_to (manager, *i)) { + return true; + } + } + return false; +} + int Slavable::set_state (XMLNode const& node, int version) { diff --git a/libs/ardour/vca.cc b/libs/ardour/vca.cc index 7be103e9e4..b7b95d1271 100644 --- a/libs/ardour/vca.cc +++ b/libs/ardour/vca.cc @@ -208,6 +208,17 @@ VCA::slaved_to (boost::shared_ptr vca) const return _gain_control->slaved_to (vca->gain_control()); } +void +VCA::assign (boost::shared_ptr v) +{ + /* prevent recursive assignments */ + if (assigned_to (_session.vca_manager_ptr (), v)) { + warning << _("Master assignment inored to prevent recursion") << endmsg; + return; + } + Slavable::assign (v); +} + SlavableControlList VCA::slavables () const { -- cgit v1.2.3