change API of Controllable::Changed signal to include (from_self, GroupControlDisposition)

This allows the signal to convey more information, which may be required by some handlers of a control's Changed signal
This commit is contained in:
Paul Davis 2016-03-11 10:34:51 -05:00
parent 36784ee94f
commit 5531c83496
12 changed files with 110 additions and 64 deletions

View File

@ -54,11 +54,11 @@ public:
/* Controllable API */
void set_value (double v, PBD::Controllable::GroupControlDisposition group_override) {
void set_value (double v, PBD::Controllable::GroupControlDisposition gcd) {
T newval = (T) v;
if (newval != _value) {
_value = std::max (_lower, std::min (_upper, newval));
Changed(); /* EMIT SIGNAL */
Changed (true, gcd); /* EMIT SIGNAL */
}
}
@ -84,7 +84,7 @@ public:
MPControl& operator=(const T& v) {
if (v != _value) {
_value = std::max (_lower, std::min (_upper, v));
Changed (); /* EMIT SIGNAL */
Changed (true, PBD::Controllable::UseGroup); /* EMIT SIGNAL */
}
return *this;
}

View File

@ -40,7 +40,7 @@ class LIBARDOUR_API ProxyControllable : public PBD::Controllable {
, _getter (getter)
{}
void set_value (double v, PBD::Controllable::GroupControlDisposition /*group_override*/) { if (_setter (v)) { Changed(); /* EMIT SIGNAL */ } }
void set_value (double v, PBD::Controllable::GroupControlDisposition gcd) { if (_setter (v)) { Changed (true, gcd); /* EMIT SIGNAL */ } }
double get_value () const { return _getter (); }
double internal_to_user (double i) const { return accurate_coefficient_to_dB (i);}

View File

@ -526,7 +526,6 @@ public:
/* Pretend to change value, but do not affect actual route mute. */
void set_superficial_value(bool muted);
private:
boost::weak_ptr<Route> _route;
void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);

View File

@ -67,7 +67,6 @@
#include "ardour/rc_configuration.h"
#include "ardour/session_configuration.h"
#include "ardour/session_event.h"
#include "ardour/session_solo_notifications.h"
#include "ardour/interpolation.h"
#include "ardour/plugin.h"
#include "ardour/route.h"
@ -166,7 +165,7 @@ private:
};
/** Ardour Session */
class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager, public SessionSoloNotifications<Session>
class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionList, public SessionEventManager
{
public:
enum RecordState {
@ -1684,13 +1683,12 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
void reassign_track_numbers ();
uint32_t _track_number_decimals;
/* solo/mute/notifications (see SessionSoloNotifications object) */
/* solo/mute/notifications */
friend class SessionSoloNotifications;
void _route_listen_changed (PBD::Controllable::GroupControlDisposition, boost::shared_ptr<Route>);
void _route_mute_changed ();
void _route_solo_changed (bool self_solo_change, PBD::Controllable::GroupControlDisposition group_override, boost::shared_ptr<Route>);
void _route_solo_isolated_changed (boost::shared_ptr<Route>);
void route_listen_changed (PBD::Controllable::GroupControlDisposition, boost::weak_ptr<Route>);
void route_mute_changed ();
void route_solo_changed (bool self_solo_change, PBD::Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route>);
void route_solo_isolated_changed (boost::weak_ptr<Route>);
void update_route_solo_state (boost::shared_ptr<RouteList> r = boost::shared_ptr<RouteList>());

View File

@ -113,20 +113,22 @@ AutomationControl::get_value() const
* @param value `user' value
*/
void
AutomationControl::set_value (double value, PBD::Controllable::GroupControlDisposition /* group_override */)
AutomationControl::set_value (double value, PBD::Controllable::GroupControlDisposition gcd)
{
bool to_list = _list && ((AutomationList*)_list.get())->automation_write();
Control::set_double (value, _session.transport_frame(), to_list);
Changed(); /* EMIT SIGNAL */
cerr << "AC was set to " << value << endl;
Changed (true, gcd);
}
void
AutomationControl::set_list (boost::shared_ptr<Evoral::ControlList> list)
{
Control::set_list (list);
Changed(); /* EMIT SIGNAL */
Changed (true, Controllable::NoGroup);
}
void
@ -268,6 +270,7 @@ void
AutomationControl::add_master (boost::shared_ptr<AutomationControl> m)
{
double current_value;
double new_value;
std::pair<Masters::iterator,bool> res;
{
@ -291,15 +294,28 @@ AutomationControl::add_master (boost::shared_ptr<AutomationControl> m)
/* Store the connection inside the MasterRecord, so that when we destroy it, the connection is destroyed
and we no longer hear about changes to the AutomationControl.
Note that we fix the "from_self" argument that will
be given to our own Changed signal to "false",
because the change came from the master.
*/
m->Changed.connect_same_thread (res.first->second.connection, boost::bind (&PBD::Signal0<void>::operator(), &Changed));
m->Changed.connect_same_thread (res.first->second.connection, boost::bind (&PBD::Signal2<void,bool,Controllable::GroupControlDisposition>::operator(), &Changed, false, _2));
}
new_value = get_value_locked ();
}
if (res.second) {
MasterStatusChange (); /* EMIT SIGNAL */
}
if (new_value != current_value) {
/* effective value changed by master */
Changed (false, Controllable::NoGroup);
}
}
void
@ -315,6 +331,7 @@ void
AutomationControl::remove_master (boost::shared_ptr<AutomationControl> m)
{
double current_value;
double new_value;
Masters::size_type erased = 0;
{
@ -324,29 +341,43 @@ AutomationControl::remove_master (boost::shared_ptr<AutomationControl> m)
if (erased) {
recompute_masters_ratios (current_value);
}
new_value = get_value_locked ();
}
if (erased) {
MasterStatusChange (); /* EMIT SIGNAL */
}
if (new_value != current_value) {
Changed (false, Controllable::NoGroup);
}
}
void
AutomationControl::clear_masters ()
{
double current_value;
double new_value;
bool had_masters = false;
{
Glib::Threads::RWLock::WriterLock lm (master_lock);
current_value = get_value_locked ();
if (!_masters.empty()) {
had_masters = true;
}
_masters.clear ();
new_value = get_value_locked ();
}
if (had_masters) {
MasterStatusChange (); /* EMIT SIGNAL */
}
if (new_value != current_value) {
Changed (false, Controllable::NoGroup);
}
}
bool

View File

@ -37,11 +37,11 @@ using namespace std;
/* specialize for bool because of set_value() semantics */
namespace ARDOUR {
template<> void MPControl<bool>::set_value (double v, PBD::Controllable::GroupControlDisposition /*group_override*/) {
template<> void MPControl<bool>::set_value (double v, PBD::Controllable::GroupControlDisposition gcd) {
bool newval = fabs (v) >= 0.5;
if (newval != _value) {
_value = newval;
Changed(); /* EMIT SIGNAL */
Changed (true, gcd); /* EMIT SIGNAL */
}
}
}

View File

@ -416,9 +416,9 @@ Route::inc_gain (gain_t factor)
}
void
Route::set_gain (gain_t val, Controllable::GroupControlDisposition group_override)
Route::set_gain (gain_t val, Controllable::GroupControlDisposition gcd)
{
if (use_group (group_override, &RouteGroup::is_gain)) {
if (use_group (gcd, &RouteGroup::is_gain)) {
if (_route_group->is_relative()) {
@ -442,13 +442,13 @@ Route::set_gain (gain_t val, Controllable::GroupControlDisposition group_overrid
if (factor > 0.0f) {
factor = _route_group->get_max_factor(factor);
if (factor == 0.0f) {
_amp->gain_control()->Changed(); /* EMIT SIGNAL */
_amp->gain_control()->Changed (true, gcd); /* EMIT SIGNAL */
return;
}
} else {
factor = _route_group->get_min_factor(factor);
if (factor == 0.0f) {
_amp->gain_control()->Changed(); /* EMIT SIGNAL */
_amp->gain_control()->Changed (true, gcd); /* EMIT SIGNAL */
return;
}
}
@ -830,8 +830,8 @@ Route::set_listen (bool yn, Controllable::GroupControlDisposition group_override
}
_mute_master->set_soloed_by_others (false);
_session.listen_changed (group_override, shared_from_this());
_solo_control->Changed(); /* EMIT SIGNAL */
/* first argument won't matter because solo <=> listen right now */
_solo_control->Changed (false, group_override); /* EMIT SIGNAL */
}
}
}
@ -847,11 +847,11 @@ Route::listening_via_monitor () const
}
void
Route::set_solo_safe (bool yn, Controllable::GroupControlDisposition /* group_override */)
Route::set_solo_safe (bool yn, Controllable::GroupControlDisposition gcd)
{
if (_solo_safe != yn) {
_solo_safe = yn;
_solo_safe_control->Changed(); /* EMIT SIGNAL */
_solo_safe_control->Changed (true, gcd); /* EMIT SIGNAL */
}
}
@ -893,8 +893,7 @@ Route::clear_all_solo_state ()
if (emit_changed) {
set_mute_master_solo ();
_session.solo_changed (false, Controllable::UseGroup, shared_from_this());
_solo_control->Changed (); /* EMIT SIGNAL */
_solo_control->Changed (false, Controllable::UseGroup); /* EMIT SIGNAL */
}
}
@ -921,8 +920,7 @@ Route::set_solo (bool yn, Controllable::GroupControlDisposition group_override)
if (self_soloed() != yn) {
set_self_solo (yn);
_session.solo_changed (true, group_override, shared_from_this());
_solo_control->Changed (); /* EMIT SIGNAL */
_solo_control->Changed (true, group_override); /* EMIT SIGNAL */
}
assert (Config->get_solo_control_is_listen_control() || !_monitor_send || !_monitor_send->active());
@ -999,8 +997,7 @@ Route::mod_solo_by_others_upstream (int32_t delta)
}
set_mute_master_solo ();
_session.solo_changed (false, Controllable::UseGroup, shared_from_this());
_solo_control->Changed (); /* EMIT SIGNAL */
_solo_control->Changed (false, Controllable::UseGroup); /* EMIT SIGNAL */
}
void
@ -1022,8 +1019,7 @@ Route::mod_solo_by_others_downstream (int32_t delta)
DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 SbD delta %2 = %3\n", name(), delta, _soloed_by_others_downstream));
set_mute_master_solo ();
_session.solo_changed (false, Controllable::UseGroup, shared_from_this());
_solo_control->Changed (); /* EMIT SIGNAL */
_solo_control->Changed (false, Controllable::UseGroup); /* EMIT SIGNAL */
}
void
@ -1053,8 +1049,7 @@ Route::mod_solo_isolated_by_upstream (bool yn)
if (solo_isolated() != old) {
/* solo isolated status changed */
_mute_master->set_solo_ignore (solo_isolated());
_session.solo_isolated_changed (shared_from_this());
_solo_isolate_control->Changed(); /* EMIT SIGNAL */
_solo_isolate_control->Changed (false, Controllable::NoGroup); /* EMIT SIGNAL */
}
}
@ -1110,8 +1105,7 @@ Route::set_solo_isolated (bool yn, Controllable::GroupControlDisposition group_o
/* XXX should we back-propagate as well? (April 2010: myself and chris goddard think not) */
_session.solo_isolated_changed (shared_from_this());
_solo_isolate_control->Changed(); /* EMIT SIGNAL */
_solo_isolate_control->Changed (true, group_override); /* EMIT SIGNAL */
}
bool
@ -1127,8 +1121,7 @@ Route::set_mute_points (MuteMaster::MutePoint mp)
mute_points_changed (); /* EMIT SIGNAL */
if (_mute_master->muted_by_self()) {
_session.mute_changed ();
_mute_control->Changed (); /* EMIT SIGNAL */
_mute_control->Changed (true, Controllable::UseGroup); /* EMIT SIGNAL */
}
}
@ -1147,8 +1140,7 @@ Route::set_mute (bool yn, Controllable::GroupControlDisposition group_override)
*/
act_on_mute ();
/* tell everyone else */
_session.mute_changed ();
_mute_control->Changed (); /* EMIT SIGNAL */
_mute_control->Changed (true, Controllable::NoGroup); /* EMIT SIGNAL */
}
}
@ -4647,7 +4639,7 @@ Route::set_phase_invert (uint32_t c, bool yn)
{
if (_phase_invert[c] != yn) {
_phase_invert[c] = yn;
_phase_control->Changed(); /* EMIT SIGNAL */
_phase_control->Changed (true, Controllable::NoGroup); /* EMIT SIGNAL */
_session.set_dirty ();
}
}
@ -4657,7 +4649,7 @@ Route::set_phase_invert (boost::dynamic_bitset<> p)
{
if (_phase_invert != p) {
_phase_invert = p;
_phase_control->Changed (); /* EMIT SIGNAL */
_phase_control->Changed (true, Controllable::NoGroup); /* EMIT SIGNAL */
_session.set_dirty ();
}
}

View File

@ -158,9 +158,13 @@ Route::SoloControllable::set_value_unchecked (double val)
double
Route::SoloControllable::get_value () const
{
std::cerr << "RSC get value\n";
if (slaved()) {
std::cerr << "slaved solo control, get master value ... ";
Glib::Threads::RWLock::ReaderLock lm (master_lock);
return get_masters_value_locked () ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
double v = get_masters_value_locked () ? GAIN_COEFF_UNITY : GAIN_COEFF_ZERO;
std::cerr << v << std::endl;
}
if (_list && ((AutomationList*)_list.get())->automation_playback()) {
@ -385,4 +389,3 @@ Route::SoloSafeControllable::get_value () const
return r->solo_safe() ? 1.0 : 0.0;
}

View File

@ -3411,12 +3411,10 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
boost::weak_ptr<Route> wpr (*x);
boost::shared_ptr<Route> r (*x);
/* we don't connect to control Changed signals for
* solo/mute/listen. The Route calls back to use, via
* the SessionSoloNotifications API, passing us more
* information than would be available from a control Changed signal.
*/
r->solo_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
r->solo_isolate_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, wpr));
r->mute_control()->Changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this));
r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
@ -3694,14 +3692,20 @@ Session::remove_route (boost::shared_ptr<Route> route)
}
void
Session::_route_mute_changed ()
Session::route_mute_changed ()
{
set_dirty ();
}
void
Session::_route_listen_changed (Controllable::GroupControlDisposition group_override, boost::shared_ptr<Route> route)
Session::route_listen_changed (Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
{
boost::shared_ptr<Route> route (wpr.lock());
if (!route) {
return;
}
if (route->listening_via_monitor ()) {
if (Config->get_exclusive_solo()) {
@ -3745,8 +3749,14 @@ Session::_route_listen_changed (Controllable::GroupControlDisposition group_over
}
void
Session::_route_solo_isolated_changed (boost::shared_ptr<Route> route)
Session::route_solo_isolated_changed (boost::weak_ptr<Route> wpr)
{
boost::shared_ptr<Route> route (wpr.lock());
if (!route) {
return;
}
bool send_changed = false;
if (route->solo_isolated()) {
@ -3767,10 +3777,23 @@ Session::_route_solo_isolated_changed (boost::shared_ptr<Route> route)
}
void
Session::_route_solo_changed (bool self_solo_change, Controllable::GroupControlDisposition group_override, boost::shared_ptr<Route> route)
Session::route_solo_changed (bool self_solo_change, Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
{
cerr << "route solo change (self ? " << self_solo_change << endl;
DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
boost::shared_ptr<Route> route (wpr.lock());
if (!route) {
return;
}
if (Config->get_solo_control_is_listen_control()) {
route_listen_changed (group_override, wpr);
return;
}
if (!self_solo_change) {
// session doesn't care about changes to soloed-by-others
return;
@ -3924,7 +3947,7 @@ Session::_route_solo_changed (bool self_solo_change, Controllable::GroupControlD
for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
(*i)->act_on_mute ();
(*i)->mute_control()->Changed (); /* EMIT SIGNAL */
(*i)->mute_control()->Changed (false, Controllable::NoGroup);
}
SoloChanged (); /* EMIT SIGNAL */

View File

@ -3875,7 +3875,7 @@ Session::config_changed (std::string p, bool ours)
} else if (p == "solo-control-is-listen-control") {
solo_control_mode_changed ();
} else if (p == "solo-mute-gain") {
_solo_cut_control->Changed();
_solo_cut_control->Changed (true, Controllable::NoGroup);
} else if (p == "timecode-offset" || p == "timecode-offset-negative") {
last_timecode_valid = false;
} else if (p == "playback-buffer-seconds") {

View File

@ -291,7 +291,7 @@ Track::prep_record_enabled (bool yn, Controllable::GroupControlDisposition group
}
void
Track::set_record_enabled (bool yn, Controllable::GroupControlDisposition group_override)
Track::set_record_enabled (bool yn, Controllable::GroupControlDisposition gcd)
{
if (_diskstream->record_safe ()) {
return;
@ -305,14 +305,14 @@ Track::set_record_enabled (bool yn, Controllable::GroupControlDisposition group_
return;
}
if (use_group (group_override, &RouteGroup::is_recenable)) {
if (use_group (gcd, &RouteGroup::is_recenable)) {
_route_group->apply (&Track::set_record_enabled, yn, Controllable::NoGroup);
return;
}
_diskstream->set_record_enabled (yn);
_rec_enable_control->Changed ();
_rec_enable_control->Changed (true, gcd);
}
bool
@ -1151,7 +1151,7 @@ Track::set_monitoring (MonitorChoice mc, Controllable::GroupControlDisposition g
}
MonitoringChanged (); /* EMIT SIGNAL */
_monitoring_control->Changed (); /* EMIT SIGNAL */
_monitoring_control->Changed (true, gcd);
}
}

View File

@ -126,7 +126,7 @@ class LIBPBD_API Controllable : public PBD::StatefulDestructible {
static PBD::Signal1<void,Controllable*> Destroyed;
PBD::Signal0<void> Changed;
PBD::Signal2<void,bool,PBD::Controllable::GroupControlDisposition> Changed;
int set_state (const XMLNode&, int version);
XMLNode& get_state ();