From acfa04d7009bd9842983c718dc055493315f1ca2 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 4 Feb 2021 06:19:37 +0100 Subject: [PATCH] Update Ctrl-surface MIDI port list when ports change This is a better variant of bbb6851468090905, directly using the GUI context without indirection. --- libs/surfaces/cc121/gui.cc | 4 +++- libs/surfaces/cc121/gui.h | 2 +- libs/surfaces/faderport/faderport.cc | 5 ++--- libs/surfaces/faderport/faderport.h | 2 +- libs/surfaces/faderport/gui.cc | 4 +++- libs/surfaces/faderport/gui.h | 2 +- libs/surfaces/faderport8/faderport8.cc | 1 - libs/surfaces/faderport8/gui.cc | 4 +++- libs/surfaces/faderport8/gui.h | 2 +- .../surfaces/generic_midi/generic_midi_control_protocol.cc | 3 +-- libs/surfaces/generic_midi/generic_midi_control_protocol.h | 2 +- libs/surfaces/generic_midi/gmcp_gui.cc | 7 ++++--- libs/surfaces/launch_control_xl/gui.cc | 5 +++-- libs/surfaces/launch_control_xl/gui.h | 2 +- libs/surfaces/launch_control_xl/launch_control_xl.cc | 6 ++---- libs/surfaces/launch_control_xl/launch_control_xl.h | 3 +-- libs/surfaces/mackie/gui.cc | 6 +++++- libs/surfaces/mackie/gui.h | 2 +- libs/surfaces/push2/gui.cc | 5 +++-- libs/surfaces/push2/gui.h | 3 +-- libs/surfaces/push2/push2.cc | 3 --- libs/surfaces/us2400/gui.cc | 4 +++- libs/surfaces/us2400/gui.h | 2 +- 23 files changed, 42 insertions(+), 37 deletions(-) diff --git a/libs/surfaces/cc121/gui.cc b/libs/surfaces/cc121/gui.cc index 4d68ed8d97..fb6fbca31f 100644 --- a/libs/surfaces/cc121/gui.cc +++ b/libs/surfaces/cc121/gui.cc @@ -288,7 +288,9 @@ CC121GUI::CC121GUI (CC121& p) /* catch future changes to connection state */ - fp.ConnectionChange.connect (connection_change_connection, invalidator (*this), boost::bind (&CC121GUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (_port_connections, invalidator (*this), boost::bind (&CC121GUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortPrettyNameChanged.connect (_port_connections, invalidator (*this), boost::bind (&CC121GUI::connection_handler, this), gui_context()); + fp.ConnectionChange.connect (_port_connections, invalidator (*this), boost::bind (&CC121GUI::connection_handler, this), gui_context()); } CC121GUI::~CC121GUI () diff --git a/libs/surfaces/cc121/gui.h b/libs/surfaces/cc121/gui.h index 6ba9f1a801..c4eb5be7e2 100644 --- a/libs/surfaces/cc121/gui.h +++ b/libs/surfaces/cc121/gui.h @@ -72,7 +72,7 @@ private: Gtk::ComboBox allbypass_combo; void update_port_combos (); - PBD::ScopedConnection connection_change_connection; + PBD::ScopedConnectionList _port_connections; void connection_handler (); struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord { diff --git a/libs/surfaces/faderport/faderport.cc b/libs/surfaces/faderport/faderport.cc index 76e7c948dc..6a7b8fa237 100644 --- a/libs/surfaces/faderport/faderport.cc +++ b/libs/surfaces/faderport/faderport.cc @@ -109,8 +109,7 @@ FaderPort::FaderPort (Session& s) ); /* Catch port connections and disconnections */ - ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::connection_handler, this, _1, _2, _3, _4, _5), this); - ARDOUR::AudioEngine::instance()->PortPrettyNameChanged.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::ConnectionChange, this), this); /* notify GUI */ + ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (_port_connection, MISSING_INVALIDATOR, boost::bind (&FaderPort::connection_handler, this, _1, _2, _3, _4, _5), this); buttons.insert (std::make_pair (Mute, Button (*this, _("Mute"), Mute, 21))); buttons.insert (std::make_pair (Solo, Button (*this, _("Solo"), Solo, 22))); @@ -630,7 +629,7 @@ FaderPort::close () stop_midi_handling (); session_connections.drop_connections (); - port_connections.drop_connections (); + _port_connection.disconnect (); blink_connection.disconnect (); selection_connection.disconnect (); stripable_connections.drop_connections (); diff --git a/libs/surfaces/faderport/faderport.h b/libs/surfaces/faderport/faderport.h index 87b0954704..e6ef738a4f 100644 --- a/libs/surfaces/faderport/faderport.h +++ b/libs/surfaces/faderport/faderport.h @@ -183,7 +183,7 @@ class FaderPort : public ARDOUR::ControlProtocol, public AbstractUI, std::string name1, boost::weak_ptr, std::string name2, bool yn); - PBD::ScopedConnectionList port_connections; + PBD::ScopedConnection _port_connection; enum ConnectionState { InputConnected = 0x1, diff --git a/libs/surfaces/faderport/gui.cc b/libs/surfaces/faderport/gui.cc index 2676ea01c6..34a82aff98 100644 --- a/libs/surfaces/faderport/gui.cc +++ b/libs/surfaces/faderport/gui.cc @@ -272,7 +272,9 @@ FPGUI::FPGUI (FaderPort& p) /* catch future changes to connection state */ - fp.ConnectionChange.connect (connection_change_connection, invalidator (*this), boost::bind (&FPGUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (_port_connections, invalidator (*this), boost::bind (&FPGUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortPrettyNameChanged.connect (_port_connections, invalidator (*this), boost::bind (&FPGUI::connection_handler, this), gui_context()); + fp.ConnectionChange.connect (_port_connections, invalidator (*this), boost::bind (&FPGUI::connection_handler, this), gui_context()); } FPGUI::~FPGUI () diff --git a/libs/surfaces/faderport/gui.h b/libs/surfaces/faderport/gui.h index 6a27b2085e..8b6dcbff01 100644 --- a/libs/surfaces/faderport/gui.h +++ b/libs/surfaces/faderport/gui.h @@ -69,7 +69,7 @@ private: Gtk::ComboBox foot_combo[3]; void update_port_combos (); - PBD::ScopedConnection connection_change_connection; + PBD::ScopedConnectionList _port_connections; void connection_handler (); struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord { diff --git a/libs/surfaces/faderport8/faderport8.cc b/libs/surfaces/faderport8/faderport8.cc index fce7179632..53e7d3b64e 100644 --- a/libs/surfaces/faderport8/faderport8.cc +++ b/libs/surfaces/faderport8/faderport8.cc @@ -172,7 +172,6 @@ FaderPort8::FaderPort8 (Session& s) ); ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::connection_handler, this, _2, _4), this); - ARDOUR::AudioEngine::instance()->PortPrettyNameChanged.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::ConnectionChange, this), this); /* notify GUI */ ARDOUR::AudioEngine::instance()->Stopped.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::engine_reset, this), this); ARDOUR::Port::PortDrop.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort8::engine_reset, this), this); diff --git a/libs/surfaces/faderport8/gui.cc b/libs/surfaces/faderport8/gui.cc index 6fa7071492..b81ee85593 100644 --- a/libs/surfaces/faderport8/gui.cc +++ b/libs/surfaces/faderport8/gui.cc @@ -215,7 +215,9 @@ FP8GUI::FP8GUI (FaderPort8& p) update_port_combos (); /* catch future changes to connection state */ - fp.ConnectionChange.connect (connection_change_connection, invalidator (*this), boost::bind (&FP8GUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (_port_connections, invalidator (*this), boost::bind (&FP8GUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortPrettyNameChanged.connect (_port_connections, invalidator (*this), boost::bind (&FP8GUI::connection_handler, this), gui_context()); + fp.ConnectionChange.connect (_port_connections, invalidator (*this), boost::bind (&FP8GUI::connection_handler, this), gui_context()); } FP8GUI::~FP8GUI () diff --git a/libs/surfaces/faderport8/gui.h b/libs/surfaces/faderport8/gui.h index 82ddea6d41..a6622cbe63 100644 --- a/libs/surfaces/faderport8/gui.h +++ b/libs/surfaces/faderport8/gui.h @@ -61,7 +61,7 @@ private: void update_port_combos (); void connection_handler (); - PBD::ScopedConnection connection_change_connection; + PBD::ScopedConnectionList _port_connections; struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord { MidiPortColumns() { diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc index 74665eb899..b0a33dfe79 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.cc +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.cc @@ -137,10 +137,9 @@ GenericMidiControlProtocol::GenericMidiControlProtocol (Session& s) PresentationInfo::Change.connect (*this, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::reset_controllables, this), this); /* Catch port connections and disconnections (cross-thread) */ - ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connections, MISSING_INVALIDATOR, + ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (_port_connection, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::connection_handler, this, _1, _2, _3, _4, _5), this); - ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&GenericMidiControlProtocol::ConnectionChange, this), this); /* notify GUI */ reload_maps (); } diff --git a/libs/surfaces/generic_midi/generic_midi_control_protocol.h b/libs/surfaces/generic_midi/generic_midi_control_protocol.h index 366d9f3e69..fbabc9234a 100644 --- a/libs/surfaces/generic_midi/generic_midi_control_protocol.h +++ b/libs/surfaces/generic_midi/generic_midi_control_protocol.h @@ -183,7 +183,7 @@ private: int connection_state; bool connection_handler (boost::weak_ptr, std::string name1, boost::weak_ptr, std::string name2, bool yn); - PBD::ScopedConnectionList port_connections; + PBD::ScopedConnection _port_connection; std::string _current_binding; uint32_t _bank_size; diff --git a/libs/surfaces/generic_midi/gmcp_gui.cc b/libs/surfaces/generic_midi/gmcp_gui.cc index 24aacb99b9..dbaa57ad7e 100644 --- a/libs/surfaces/generic_midi/gmcp_gui.cc +++ b/libs/surfaces/generic_midi/gmcp_gui.cc @@ -72,7 +72,7 @@ private: void toggle_feedback_enable (); void update_port_combos (); - PBD::ScopedConnection connection_change_connection; + PBD::ScopedConnectionList _port_connections; void connection_handler (); struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord { @@ -247,8 +247,9 @@ GMCPGUI::GMCPGUI (GenericMidiControlProtocol& p) update_port_combos (); /* catch future changes to connection state */ - - cp.ConnectionChange.connect (connection_change_connection, invalidator (*this), boost::bind (&GMCPGUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (_port_connections, invalidator (*this), boost::bind (&GMCPGUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortPrettyNameChanged.connect (_port_connections, invalidator (*this), boost::bind (&GMCPGUI::connection_handler, this), gui_context()); + cp.ConnectionChange.connect (_port_connections, invalidator (*this), boost::bind (&GMCPGUI::connection_handler, this), gui_context()); } GMCPGUI::~GMCPGUI () diff --git a/libs/surfaces/launch_control_xl/gui.cc b/libs/surfaces/launch_control_xl/gui.cc index 331f941619..70a1bd745d 100644 --- a/libs/surfaces/launch_control_xl/gui.cc +++ b/libs/surfaces/launch_control_xl/gui.cc @@ -162,8 +162,9 @@ LCXLGUI::LCXLGUI (LaunchControlXL& p) /* catch future changes to connection state */ - ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (port_reg_connection, invalidator (*this), boost::bind (&LCXLGUI::connection_handler, this), gui_context()); - lcxl.ConnectionChange.connect (connection_change_connection, invalidator (*this), boost::bind (&LCXLGUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (_port_connections, invalidator (*this), boost::bind (&LCXLGUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortPrettyNameChanged.connect (_port_connections, invalidator (*this), boost::bind (&LCXLGUI::connection_handler, this), gui_context()); + lcxl.ConnectionChange.connect (_port_connections, invalidator (*this), boost::bind (&LCXLGUI::connection_handler, this), gui_context()); } LCXLGUI::~LCXLGUI () diff --git a/libs/surfaces/launch_control_xl/gui.h b/libs/surfaces/launch_control_xl/gui.h index 581fdbd2cd..b4054a741f 100644 --- a/libs/surfaces/launch_control_xl/gui.h +++ b/libs/surfaces/launch_control_xl/gui.h @@ -67,7 +67,7 @@ private: void update_port_combos (); PBD::ScopedConnection connection_change_connection; void connection_handler (); - PBD::ScopedConnection port_reg_connection; + PBD::ScopedConnectionList _port_connections; struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord { MidiPortColumns() { diff --git a/libs/surfaces/launch_control_xl/launch_control_xl.cc b/libs/surfaces/launch_control_xl/launch_control_xl.cc index 325dcab6bd..d22edc2319 100644 --- a/libs/surfaces/launch_control_xl/launch_control_xl.cc +++ b/libs/surfaces/launch_control_xl/launch_control_xl.cc @@ -103,8 +103,7 @@ LaunchControlXL::LaunchControlXL (ARDOUR::Session& s) ports_acquire (); /* Catch port connections and disconnections */ - ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&LaunchControlXL::connection_handler, this, _1, _2, _3, _4, _5), this); - ARDOUR::AudioEngine::instance()->PortPrettyNameChanged.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&LaunchControlXL::ConnectionChange, this), this); /* notify GUI */ + ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR, boost::bind (&LaunchControlXL::connection_handler, this, _1, _2, _3, _4, _5), this); session->RouteAdded.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&LaunchControlXL::stripables_added, this), lcxl); session->vca_manager().VCAAdded.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&LaunchControlXL::stripables_added, this), lcxl); @@ -115,8 +114,7 @@ LaunchControlXL::~LaunchControlXL () DEBUG_TRACE (DEBUG::LaunchControlXL, "Launch Control XL control surface object being destroyed\n"); /* do this before stopping the event loop, so that we don't get any notifications */ - port_reg_connection.disconnect (); - port_connections.drop_connections (); + port_connection.disconnect (); session_connections.drop_connections (); stripable_connections.drop_connections (); diff --git a/libs/surfaces/launch_control_xl/launch_control_xl.h b/libs/surfaces/launch_control_xl/launch_control_xl.h index fcae638d9d..4147260524 100644 --- a/libs/surfaces/launch_control_xl/launch_control_xl.h +++ b/libs/surfaces/launch_control_xl/launch_control_xl.h @@ -631,7 +631,6 @@ private: boost::shared_ptr master; - PBD::ScopedConnection port_reg_connection; void port_registration_handler(); enum ConnectionState { InputConnected = 0x1, OutputConnected = 0x2 }; @@ -640,7 +639,7 @@ private: bool connection_handler(boost::weak_ptr, std::string name1, boost::weak_ptr, std::string name2, bool yn); - PBD::ScopedConnectionList port_connections; + PBD::ScopedConnection port_connection; void connected(); /* GUI */ diff --git a/libs/surfaces/mackie/gui.cc b/libs/surfaces/mackie/gui.cc index 8f734a3539..166744f51d 100644 --- a/libs/surfaces/mackie/gui.cc +++ b/libs/surfaces/mackie/gui.cc @@ -129,7 +129,11 @@ MackieControlProtocolGUI::MackieControlProtocolGUI (MackieControlProtocol& p) _surface_combo.signal_changed().connect (sigc::mem_fun (*this, &MackieControlProtocolGUI::surface_combo_changed)); _cp.DeviceChanged.connect (device_change_connection, invalidator (*this), boost::bind (&MackieControlProtocolGUI::device_changed, this), gui_context()); - _cp.ConnectionChange.connect (connection_change_connection, invalidator (*this), boost::bind (&MackieControlProtocolGUI::connection_handler, this), gui_context()); + + /* catch future changes to connection state */ + ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (_port_connections, invalidator (*this), boost::bind (&MackieControlProtocolGUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortPrettyNameChanged.connect (_port_connections, invalidator (*this), boost::bind (&MackieControlProtocolGUI::connection_handler, this), gui_context()); + _cp.ConnectionChange.connect (_port_connections, invalidator (*this), boost::bind (&MackieControlProtocolGUI::connection_handler, this), gui_context()); ipmidi_base_port_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &MackieControlProtocolGUI::ipmidi_spinner_changed)); diff --git a/libs/surfaces/mackie/gui.h b/libs/surfaces/mackie/gui.h index 390a4bbfe5..9e599a5399 100644 --- a/libs/surfaces/mackie/gui.h +++ b/libs/surfaces/mackie/gui.h @@ -140,7 +140,7 @@ class MackieControlProtocolGUI : public Gtk::Notebook Gtk::ComboBox* output_combo, boost::shared_ptr surface); - PBD::ScopedConnection connection_change_connection; + PBD::ScopedConnectionList _port_connections; void connection_handler (); Glib::RefPtr build_midi_port_list (std::vector const & ports, bool for_input); diff --git a/libs/surfaces/push2/gui.cc b/libs/surfaces/push2/gui.cc index 920697c7f7..1a31882a03 100644 --- a/libs/surfaces/push2/gui.cc +++ b/libs/surfaces/push2/gui.cc @@ -144,8 +144,9 @@ P2GUI::P2GUI (Push2& p) /* catch future changes to connection state */ - ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (port_reg_connection, invalidator (*this), boost::bind (&P2GUI::connection_handler, this), gui_context()); - p2.ConnectionChange.connect (connection_change_connection, invalidator (*this), boost::bind (&P2GUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (_port_connections, invalidator (*this), boost::bind (&P2GUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortPrettyNameChanged.connect (_port_connections, invalidator (*this), boost::bind (&P2GUI::connection_handler, this), gui_context()); + p2.ConnectionChange.connect (_port_connections, invalidator (*this), boost::bind (&P2GUI::connection_handler, this), gui_context()); } P2GUI::~P2GUI () diff --git a/libs/surfaces/push2/gui.h b/libs/surfaces/push2/gui.h index 9b56e441f7..5e703f2334 100644 --- a/libs/surfaces/push2/gui.h +++ b/libs/surfaces/push2/gui.h @@ -59,9 +59,8 @@ private: Gtk::Image image; void update_port_combos (); - PBD::ScopedConnection connection_change_connection; void connection_handler (); - PBD::ScopedConnection port_reg_connection; + PBD::ScopedConnectionList _port_connections; struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord { MidiPortColumns() { diff --git a/libs/surfaces/push2/push2.cc b/libs/surfaces/push2/push2.cc index 1c1536780d..12fd1d7e31 100644 --- a/libs/surfaces/push2/push2.cc +++ b/libs/surfaces/push2/push2.cc @@ -130,9 +130,6 @@ Push2::Push2 (ARDOUR::Session& s) /* Catch port connections and disconnections */ ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&Push2::connection_handler, this, _1, _2, _3, _4, _5), this); - /* Catch name changes, notify GUI */ - ARDOUR::AudioEngine::instance()->PortPrettyNameChanged.connect (port_connections, MISSING_INVALIDATOR, boost::bind (&Push2::ConnectionChange, this), this); - /* Push 2 ports might already be there */ port_registration_handler (); } diff --git a/libs/surfaces/us2400/gui.cc b/libs/surfaces/us2400/gui.cc index 16eec80cec..e0bf05f447 100644 --- a/libs/surfaces/us2400/gui.cc +++ b/libs/surfaces/us2400/gui.cc @@ -107,7 +107,9 @@ US2400ProtocolGUI::US2400ProtocolGUI (US2400Protocol& p) table.set_homogeneous (false); _cp.DeviceChanged.connect (device_change_connection, invalidator (*this), boost::bind (&US2400ProtocolGUI::device_changed, this), gui_context()); - _cp.ConnectionChange.connect (connection_change_connection, invalidator (*this), boost::bind (&US2400ProtocolGUI::connection_handler, this), gui_context()); + _cp.ConnectionChange.connect (_port_connections, invalidator (*this), boost::bind (&US2400ProtocolGUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortRegisteredOrUnregistered.connect (_port_connections, invalidator (*this), boost::bind (&US2400ProtocolGUI::connection_handler, this), gui_context()); + ARDOUR::AudioEngine::instance()->PortPrettyNameChanged.connect (_port_connections, invalidator (*this), boost::bind (&US2400ProtocolGUI::connection_handler, this), gui_context()); /* device-dependent part */ diff --git a/libs/surfaces/us2400/gui.h b/libs/surfaces/us2400/gui.h index a6baad6b8b..252090d41a 100644 --- a/libs/surfaces/us2400/gui.h +++ b/libs/surfaces/us2400/gui.h @@ -123,7 +123,7 @@ class US2400ProtocolGUI : public Gtk::Notebook Gtk::ComboBox* output_combo, boost::shared_ptr surface); - PBD::ScopedConnection connection_change_connection; + PBD::ScopedConnectionList _port_connections; void connection_handler (); Glib::RefPtr build_midi_port_list (std::vector const & ports, bool for_input);