Remove all IO code that handled deferred connections

When loading a session, we now just set up port state, which will
populate the Port::_connections member, and then once all ports have
been created, use PortManager::reconnect_ports() to get everything connected.
This commit is contained in:
Paul Davis 2021-11-03 15:06:16 -06:00
parent f3481df9d4
commit 016206e18a
4 changed files with 74 additions and 194 deletions

View File

@ -183,24 +183,11 @@ public:
*/
PBD::Signal1<bool, ChanCount, BoolCombiner> PortCountChanging;
static int disable_connecting ();
static int enable_connecting ();
static PBD::Signal1<void, ChanCount> PortCountChanged; // emitted when the number of ports changes
static std::string name_from_state (const XMLNode&);
static void set_name_in_state (XMLNode&, const std::string&);
/* we have to defer/order port connection. this is how we do it.
*/
static PBD::Signal0<int> ConnectingLegal;
static bool connecting_legal;
XMLNode *pending_state_node;
int pending_state_node_version;
bool pending_state_node_in;
/* three utility functions - this just seems to be simplest place to put them */
void collect_input (BufferSet& bufs, pframes_t nframes, ChanCount offset);
@ -222,9 +209,6 @@ private:
mutable Glib::Threads::Mutex io_lock;
PortSet _ports;
int connecting_became_legal ();
PBD::ScopedConnection connection_legal_c;
void reestablish_port_subscriptions ();
PBD::ScopedConnectionList _port_connections;
@ -242,12 +226,11 @@ private:
int ensure_ports (ChanCount, bool clear, void *src);
void bundle_changed (Bundle::Change);
int set_port_state_2X (const XMLNode& node, int version, bool in);
int get_port_counts (const XMLNode& node, int version, ChanCount& n, boost::shared_ptr<Bundle>& c);
int get_port_counts_2X (const XMLNode& node, int version, ChanCount& n, boost::shared_ptr<Bundle>& c);
int create_ports (const XMLNode&, int version);
int make_connections (const XMLNode&, int, bool);
int make_connections_2X (const XMLNode &, int, bool);
boost::shared_ptr<Bundle> find_possible_bundle (const std::string &desired_name);

View File

@ -63,8 +63,6 @@ using namespace ARDOUR;
using namespace PBD;
const string IO::state_node_name = "IO";
bool IO::connecting_legal = false;
PBD::Signal0<int> IO::ConnectingLegal;
PBD::Signal1<void,ChanCount> IO::PortCountChanged;
/** @param default_type The type of port that will be created by ensure_io
@ -77,7 +75,6 @@ IO::IO (Session& s, const string& name, Direction dir, DataType default_type, bo
, _sendish (sendish)
{
_active = true;
pending_state_node = 0;
setup_bundle ();
}
@ -88,7 +85,6 @@ IO::IO (Session& s, const XMLNode& node, DataType dt, bool sendish)
, _sendish (sendish)
{
_active = true;
pending_state_node = 0;
set_state (node, Stateful::loading_state_version);
setup_bundle ();
@ -105,7 +101,6 @@ IO::~IO ()
for (PortSet::iterator i = _ports.begin(); i != _ports.end(); ++i) {
_session.engine().unregister_port (*i);
}
delete pending_state_node; pending_state_node = 0;
}
void
@ -614,6 +609,7 @@ IO::set_state (const XMLNode& node, int version)
if (create_ports (node, version)) {
return -1;
}
if (_sendish && _direction == Output) {
/* ignore <Port name="..."> from XML for sends, but use the names
* ::ensure_ports_locked() creates port using ::build_legal_port_name()
@ -631,23 +627,37 @@ IO::set_state (const XMLNode& node, int version)
}
// after create_ports, updates names
if (node.get_property ("pretty-name", name)) {
set_pretty_name (name);
}
if (connecting_legal) {
/* now set port state (this will *not* connect them, but will store
the names of connected ports).
*/
if (make_connections (node, version, false)) {
return -1;
if (version < 3000) {
return set_port_state_2X (node, version, false);
}
XMLProperty const * prop;
for (XMLNodeConstIterator i = node.children().begin(); i != node.children().end(); ++i) {
if ((*i)->name() == "Port") {
prop = (*i)->property (X_("name"));
if (!prop) {
continue;
}
boost::shared_ptr<Port> p = port_by_name (prop->value());
if (p) {
p->set_state (**i, version);
}
}
} else {
delete pending_state_node;
pending_state_node = new XMLNode (node);
pending_state_node_version = version;
pending_state_node_in = false;
ConnectingLegal.connect_same_thread (connection_legal_c, boost::bind (&IO::connecting_became_legal, this));
}
return 0;
@ -685,41 +695,13 @@ IO::set_state_2X (const XMLNode& node, int version, bool in)
return -1;
}
if (connecting_legal) {
if (make_connections_2X (node, version, in)) {
return -1;
}
} else {
delete pending_state_node;
pending_state_node = new XMLNode (node);
pending_state_node_version = version;
pending_state_node_in = in;
ConnectingLegal.connect_same_thread (connection_legal_c, boost::bind (&IO::connecting_became_legal, this));
if (set_port_state_2X (node, version, in)) {
return -1;
}
return 0;
}
int
IO::connecting_became_legal ()
{
int ret = 0;
assert (pending_state_node);
connection_legal_c.disconnect ();
ret = make_connections (*pending_state_node, pending_state_node_version, pending_state_node_in);
delete pending_state_node;
pending_state_node = 0;
return ret;
}
boost::shared_ptr<Bundle>
IO::find_possible_bundle (const string &desired_name)
{
@ -915,103 +897,7 @@ IO::create_ports (const XMLNode& node, int version)
}
int
IO::make_connections (const XMLNode& node, int version, bool in)
{
if (version < 3000) {
return make_connections_2X (node, version, in);
}
XMLProperty const * prop;
for (XMLNodeConstIterator i = node.children().begin(); i != node.children().end(); ++i) {
if ((*i)->name() == "Bundle") {
XMLProperty const * prop = (*i)->property ("name");
if (prop) {
boost::shared_ptr<Bundle> b = find_possible_bundle (prop->value());
if (b) {
connect_ports_to_bundle (b, true, this);
}
}
return 0;
}
if ((*i)->name() == "Port") {
prop = (*i)->property (X_("name"));
if (!prop) {
continue;
}
boost::shared_ptr<Port> p = port_by_name (prop->value());
if (p) {
for (XMLNodeConstIterator c = (*i)->children().begin(); c != (*i)->children().end(); ++c) {
XMLNode* cnode = (*c);
if (cnode->name() != X_("Connection")) {
continue;
}
if ((prop = cnode->property (X_("other"))) == 0) {
continue;
}
if (prop) {
connect (p, prop->value(), this);
}
}
}
}
}
return 0;
}
void
IO::prepare_for_reset (XMLNode& node, const std::string& name)
{
/* reset name */
node.set_property ("name", name);
/* now find connections and reset the name of the port
in one so that when we re-use it it will match
the name of the thing we're applying it to.
*/
XMLProperty * prop;
XMLNodeList children = node.children();
for (XMLNodeIterator i = children.begin(); i != children.end(); ++i) {
if ((*i)->name() == "Port") {
prop = (*i)->property (X_("name"));
if (prop) {
string new_name;
string old = prop->value();
string::size_type slash = old.find ('/');
if (slash != string::npos) {
/* port name is of form: <IO-name>/<port-name> */
new_name = name;
new_name += old.substr (old.find ('/'));
prop->set_value (new_name);
}
}
}
}
}
int
IO::make_connections_2X (const XMLNode& node, int /*version*/, bool in)
IO::set_port_state_2X (const XMLNode& node, int /*version*/, bool in)
{
XMLProperty const * prop;
@ -1106,6 +992,46 @@ IO::make_connections_2X (const XMLNode& node, int /*version*/, bool in)
return 0;
}
void
IO::prepare_for_reset (XMLNode& node, const std::string& name)
{
/* reset name */
node.set_property ("name", name);
/* now find connections and reset the name of the port
in one so that when we re-use it it will match
the name of the thing we're applying it to.
*/
XMLProperty * prop;
XMLNodeList children = node.children();
for (XMLNodeIterator i = children.begin(); i != children.end(); ++i) {
if ((*i)->name() == "Port") {
prop = (*i)->property (X_("name"));
if (prop) {
string new_name;
string old = prop->value();
string::size_type slash = old.find ('/');
if (slash != string::npos) {
/* port name is of form: <IO-name>/<port-name> */
new_name = name;
new_name += old.substr (old.find ('/'));
prop->set_value (new_name);
}
}
}
}
}
int
IO::set_ports (const string& str)
{
@ -1425,23 +1351,6 @@ IO::disconnect_ports_from_bundle (boost::shared_ptr<Bundle> c, void* src)
return 0;
}
int
IO::disable_connecting ()
{
connecting_legal = false;
return 0;
}
int
IO::enable_connecting ()
{
Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock());
connecting_legal = true;
boost::optional<int> r = ConnectingLegal ();
return r.value_or (0);
}
void
IO::bundle_changed (Bundle::Change /*c*/)
{

View File

@ -1331,12 +1331,7 @@ Session::hookup_io ()
delete _bundle_xml_node;
}
/* Tell all IO objects to connect themselves together */
IO::enable_connecting ();
/* Now tell all "floating" ports to connect to whatever
they should be connected to.
/* Get everything connected
*/
AudioEngine::instance()->reconnect_ports ();
@ -2871,7 +2866,6 @@ Session::new_route_from_template (uint32_t how_many, PresentationInfo::order_t i
values by Stateful.
*/
Stateful::ForceIDRegeneration force_ids;
IO::disable_connecting ();
/* New v6 templates do have a version in the Route-Template,
* we assume that all older, unversioned templates are
@ -3100,7 +3094,6 @@ Session::new_route_from_template (uint32_t how_many, PresentationInfo::order_t i
}
catch (...) {
IO::enable_connecting ();
throw;
}
@ -3112,8 +3105,6 @@ Session::new_route_from_template (uint32_t how_many, PresentationInfo::order_t i
add_routes (ret, true, true, insert_at);
}
IO::enable_connecting ();
if (!ret.empty()) {
/* set/unset monitor-send */
Glib::Threads::Mutex::Lock lm (_engine.process_lock());
@ -3184,7 +3175,7 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
* we will resort when done.
*/
if (!_monitor_out && IO::connecting_legal) {
if (!_monitor_out && !loading()) {
resort_routes_using (r);
}
}
@ -3279,7 +3270,7 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
ensure_stripable_sort_order ();
}
if (_monitor_out && IO::connecting_legal) {
if (_monitor_out && !loading()) {
Glib::Threads::Mutex::Lock lm (_engine.process_lock());
for (RouteList::iterator x = new_routes.begin(); x != new_routes.end(); ++x) {
@ -7087,7 +7078,7 @@ Session::auto_connect (const AutoConnectRequest& ar)
if (!route) { return; }
if (!IO::connecting_legal) {
if (loading()) {
return;
}

View File

@ -214,7 +214,6 @@ Session::pre_engine_init (string fullpath)
/* stop IO objects from doing stuff until we're ready for them */
Delivery::disable_panners ();
IO::disable_connecting ();
}
int
@ -1628,8 +1627,6 @@ Session::set_state (const XMLNode& node, int version)
_midi_ports->set_midi_port_states (child->children());
}
IO::disable_connecting ();
Stateful::save_extra_xml (node);
if (((child = find_named_node (node, "Options")) != 0)) { /* old style */