add Port::PostDisconnect signal to allow objects other than the one being directly disconnected to act when disconnection happens. This turns out to be much easier than using the JACK port connect/disconnect callback
git-svn-id: svn://localhost/ardour2/branches/3.0@11355 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
9b3aefec1b
commit
e3b2111109
|
@ -247,6 +247,7 @@ class IO : public SessionObject, public Latent
|
|||
std::string bundle_channel_name (uint32_t, uint32_t, DataType) const;
|
||||
|
||||
BufferSet _buffers;
|
||||
void disconnect_check (boost::shared_ptr<ARDOUR::Port>, boost::shared_ptr<ARDOUR::Port>);
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
|
|
@ -125,7 +125,7 @@ public:
|
|||
static void set_engine (AudioEngine *);
|
||||
|
||||
PBD::Signal1<void,bool> MonitorInputChanged;
|
||||
|
||||
static PBD::Signal2<void,boost::shared_ptr<Port>,boost::shared_ptr<Port> > PostDisconnect;
|
||||
|
||||
static void set_cycle_framecnt (pframes_t n) {
|
||||
_cycle_nframes = n;
|
||||
|
|
|
@ -69,6 +69,7 @@ IO::IO (Session& s, const string& name, Direction dir, DataType default_type)
|
|||
, _default_type (default_type)
|
||||
{
|
||||
_active = true;
|
||||
Port::PostDisconnect.connect_same_thread (*this, boost::bind (&IO::disconnect_check, this, _1, _2));
|
||||
pending_state_node = 0;
|
||||
setup_bundle ();
|
||||
}
|
||||
|
@ -80,6 +81,7 @@ IO::IO (Session& s, const XMLNode& node, DataType dt)
|
|||
{
|
||||
_active = true;
|
||||
pending_state_node = 0;
|
||||
Port::PostDisconnect.connect_same_thread (*this, boost::bind (&IO::disconnect_check, this, _1, _2));
|
||||
|
||||
set_state (node, Stateful::loading_state_version);
|
||||
setup_bundle ();
|
||||
|
@ -96,6 +98,31 @@ IO::~IO ()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
IO::disconnect_check (boost::shared_ptr<Port> a, boost::shared_ptr<Port> b)
|
||||
{
|
||||
/* this could be called from within our own ::disconnect() method(s)
|
||||
or from somewhere that operates directly on a port. so, we don't
|
||||
know for sure if we can take this lock or not. if we fail,
|
||||
we assume that its safely locked by our own ::disconnect().
|
||||
*/
|
||||
|
||||
Glib::Mutex::Lock tm (io_lock, Glib::TRY_LOCK);
|
||||
|
||||
if (tm.locked()) {
|
||||
/* we took the lock, so we cannot be here from inside
|
||||
* ::disconnect()
|
||||
*/
|
||||
if (_ports.contains (a) || _ports.contains (b)) {
|
||||
changed (IOChange (IOChange::ConnectionsChanged), this); /* EMIT SIGNAL */
|
||||
}
|
||||
} else {
|
||||
/* we didn't get the lock, so assume that we're inside
|
||||
* ::disconnect(), and it will call changed() appropriately.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IO::increment_port_buffer_offset (pframes_t offset)
|
||||
{
|
||||
|
|
|
@ -39,6 +39,8 @@ using namespace std;
|
|||
using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
PBD::Signal2<void,boost::shared_ptr<Port>, boost::shared_ptr<Port> > Port::PostDisconnect;
|
||||
|
||||
AudioEngine* Port::_engine = 0;
|
||||
bool Port::_connecting_blocked = false;
|
||||
pframes_t Port::_global_port_buffer_offset = 0;
|
||||
|
@ -94,6 +96,11 @@ Port::disconnect_all ()
|
|||
jack_port_disconnect (_engine->jack(), _jack_port);
|
||||
_connections.clear ();
|
||||
|
||||
/* a cheaper, less hacky way to do boost::shared_from_this() ...
|
||||
*/
|
||||
boost::shared_ptr<Port> pself = _engine->get_port_by_name (name());
|
||||
PostDisconnect (pself, boost::shared_ptr<Port>()); // emit signal
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -168,21 +175,34 @@ Port::connect (std::string const & other)
|
|||
int
|
||||
Port::disconnect (std::string const & other)
|
||||
{
|
||||
std::string const other_shrt = _engine->make_port_name_non_relative (other);
|
||||
std::string const this_shrt = _engine->make_port_name_non_relative (_name);
|
||||
std::string const other_fullname = _engine->make_port_name_non_relative (other);
|
||||
std::string const this_fullname = _engine->make_port_name_non_relative (_name);
|
||||
|
||||
int r = 0;
|
||||
|
||||
if (sends_output ()) {
|
||||
r = jack_disconnect (_engine->jack (), this_shrt.c_str (), other_shrt.c_str ());
|
||||
r = jack_disconnect (_engine->jack (), this_fullname.c_str (), other_fullname.c_str ());
|
||||
} else {
|
||||
r = jack_disconnect (_engine->jack (), other_shrt.c_str (), this_shrt.c_str ());
|
||||
r = jack_disconnect (_engine->jack (), other_fullname.c_str (), this_fullname.c_str ());
|
||||
}
|
||||
|
||||
if (r == 0) {
|
||||
_connections.erase (other);
|
||||
}
|
||||
|
||||
/* a cheaper, less hacky way to do boost::shared_from_this() ...
|
||||
*/
|
||||
boost::shared_ptr<Port> pself = _engine->get_port_by_name (name());
|
||||
boost::shared_ptr<Port> pother = _engine->get_port_by_name (other);
|
||||
|
||||
if (pself && pother) {
|
||||
/* Disconnecting from another Ardour port: need to allow
|
||||
a check on whether this may affect anything that we
|
||||
need to know about.
|
||||
*/
|
||||
PostDisconnect (pself, pother); // emit signal
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -2837,8 +2837,6 @@ Route::input_change_handler (IOChange change, void * /*src*/)
|
|||
io_changed (); /* EMIT SIGNAL */
|
||||
}
|
||||
|
||||
cerr << _name << ": input change, connected ? " << _input->connected() << endl;
|
||||
|
||||
if (!_input->connected() && _soloed_by_others_upstream) {
|
||||
if (need_to_queue_solo_change) {
|
||||
_session.cancel_solo_after_disconnect (shared_from_this(), true);
|
||||
|
@ -2860,8 +2858,6 @@ Route::output_change_handler (IOChange change, void * /*src*/)
|
|||
need_to_queue_solo_change = false;
|
||||
}
|
||||
|
||||
cerr << _name << ": output change, connected ? " << _output->connected() << endl;
|
||||
|
||||
if (!_output->connected() && _soloed_by_others_downstream) {
|
||||
if (need_to_queue_solo_change) {
|
||||
_session.cancel_solo_after_disconnect (shared_from_this(), false);
|
||||
|
@ -2874,7 +2870,6 @@ Route::output_change_handler (IOChange change, void * /*src*/)
|
|||
void
|
||||
Route::cancel_solo_after_disconnect (bool upstream)
|
||||
{
|
||||
cerr << _name << " CSAD upstream ? " << upstream << endl;
|
||||
if (upstream) {
|
||||
_soloed_by_others_upstream = 0;
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue
Block a user