add a "reset all solo state" safeguard

This commit is contained in:
Robin Gareus 2015-10-06 20:05:38 +02:00
parent ce30132a89
commit e73fa8413e
4 changed files with 62 additions and 4 deletions

View File

@ -160,6 +160,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
void set_solo (bool yn, void *src);
bool soloed () const { return self_soloed () || soloed_by_others (); }
void clear_all_solo_state ();
bool soloed_by_others () const { return _soloed_by_others_upstream||_soloed_by_others_downstream; }
bool soloed_by_others_upstream () const { return _soloed_by_others_upstream; }

View File

@ -736,6 +736,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
static const SessionEvent::RTeventCallback rt_cleanup;
void set_solo (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
void clear_all_solo_state (boost::shared_ptr<RouteList>);
void set_just_one_solo (boost::shared_ptr<Route>, bool, SessionEvent::RTeventCallback after = rt_cleanup);
void set_mute (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
void set_listen (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
@ -1774,6 +1775,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
}
void rt_set_solo (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_clear_all_solo_state (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_set_just_one_solo (boost::shared_ptr<RouteList>, bool yn, bool /* ignored*/ );
void rt_set_mute (boost::shared_ptr<RouteList>, bool yn, bool group_override);
void rt_set_listen (boost::shared_ptr<RouteList>, bool yn, bool group_override);

View File

@ -815,6 +815,42 @@ Route::solo_safe() const
return _solo_safe;
}
void
Route::clear_all_solo_state ()
{
// ideally this function will never do anything, it only exists to forestall Murphy
bool emit_changed = false;
bool old_safe = _solo_safe;
#ifndef NDEBUG
// these are really debug messages, but of possible interest.
if (_self_solo) {
PBD::info << string_compose (_("Cleared Explicit solo: %1\n"), name());
}
if (_soloed_by_others_upstream || _soloed_by_others_downstream) {
PBD::info << string_compose (_("Cleared Implicit solo: %1 up:%2 down:%3\n"),
name(), _soloed_by_others_upstream, _soloed_by_others_downstream);
}
#endif
if (!_self_solo && (_soloed_by_others_upstream || _soloed_by_others_downstream)) {
// if self-soled, set_solo() will do signal emission
emit_changed = true;
}
_soloed_by_others_upstream = 0;
_soloed_by_others_downstream = 0;
_solo_safe = false; // allow set_solo() to do its job;
set_solo (false, this);
_solo_safe = old_safe;
if (emit_changed) {
set_mute_master_solo ();
solo_changed (false, this); /* EMIT SIGNAL */
}
}
void
Route::set_solo (bool yn, void *src)
{
@ -916,7 +952,7 @@ Route::mod_solo_by_others_upstream (int32_t delta)
}
set_mute_master_solo ();
solo_changed (false, this);
solo_changed (false, this); /* EMIT SIGNAL */
}
void
@ -938,7 +974,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 ();
solo_changed (false, this);
solo_changed (false, this); /* EMIT SIGNAL */
}
void
@ -968,7 +1004,7 @@ Route::mod_solo_isolated_by_upstream (bool yn, void* src)
if (solo_isolated() != old) {
/* solo isolated status changed */
_mute_master->set_solo_ignore (solo_isolated());
solo_isolated_changed (src);
solo_isolated_changed (src); /* EMIT SIGNAL */
}
}
@ -1024,7 +1060,7 @@ Route::set_solo_isolated (bool yn, void *src)
/* XXX should we back-propagate as well? (April 2010: myself and chris goddard think not) */
solo_isolated_changed (src);
solo_isolated_changed (src); /* EMIT SIGNAL */
}
bool

View File

@ -53,12 +53,31 @@ Session::rt_set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, b
set_dirty();
}
void
Session::clear_all_solo_state (boost::shared_ptr<RouteList> rl)
{
queue_event (get_rt_event (rl, false, rt_cleanup, false, &Session::rt_clear_all_solo_state));
}
void
Session::rt_clear_all_solo_state (boost::shared_ptr<RouteList> rl, bool /* yn */, bool /* group_override */)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if ((*i)->is_auditioner()) {
continue;
}
(*i)->clear_all_solo_state();
}
set_dirty();
}
void
Session::set_solo (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
{
queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_solo));
}
void
Session::rt_set_solo (boost::shared_ptr<RouteList> rl, bool yn, bool /* group_override */)
{