diff options
Diffstat (limited to 'src/JackDbusDriver.cpp')
-rw-r--r-- | src/JackDbusDriver.cpp | 319 |
1 files changed, 68 insertions, 251 deletions
diff --git a/src/JackDbusDriver.cpp b/src/JackDbusDriver.cpp index 81d6224..85dfae3 100644 --- a/src/JackDbusDriver.cpp +++ b/src/JackDbusDriver.cpp @@ -20,14 +20,12 @@ #include "patchage_config.h" #include "Driver.hpp" -#include "Patchage.hpp" -#include "PatchageCanvas.hpp" #include "PatchageEvent.hpp" -#include "PatchageModule.hpp" -#include "PatchagePort.hpp" #include "PortNames.hpp" #include "PortType.hpp" #include "SignalDirection.hpp" +#include "handle_event.hpp" +#include "warnings.hpp" PATCHAGE_DISABLE_FMT_WARNINGS #include <fmt/core.h> @@ -57,19 +55,8 @@ PATCHAGE_RESTORE_WARNINGS #define JACKDBUS_PORT_TYPE_AUDIO 0 #define JACKDBUS_PORT_TYPE_MIDI 1 -namespace { - -std::string -full_name(const std::string& client_name, const std::string& port_name) -{ - return client_name + ":" + port_name; -} - -} // namespace - -JackDriver::JackDriver(Patchage* app, ILog& log) - : _app(app) - , _log(log) +JackDriver::JackDriver(ILog& log) + : _log(log) , _dbus_error() , _dbus_connection(nullptr) , _max_dsp_load(0.0f) @@ -91,19 +78,6 @@ JackDriver::~JackDriver() } } -static bool -is_jack_port(const PatchagePort* port) -{ - return port->type() == PortType::jack_audio || - port->type() == PortType::jack_midi; -} - -void -JackDriver::destroy_all() -{ - _app->canvas()->remove_ports(is_jack_port); -} - void JackDriver::update_attached() { @@ -236,8 +210,9 @@ JackDriver::dbus_message_hook(DBusConnection* /*connection*/, me->signal_attached.emit(); } - me->add_port( - client_id, client_name, port_id, port_name, port_flags, port_type); + me->_events.emplace( + PortCreationEvent{PortID::jack(client_name, port_name), + me->port_info(port_name, port_type, port_flags)}); return DBUS_HANDLER_RESULT_HANDLED; } @@ -270,7 +245,8 @@ JackDriver::dbus_message_hook(DBusConnection* /*connection*/, me->signal_attached.emit(); } - me->remove_port(client_id, client_name, port_id, port_name); + me->_events.emplace( + PortDestructionEvent{PortID::jack(client_name, port_name)}); return DBUS_HANDLER_RESULT_HANDLED; } @@ -313,15 +289,9 @@ JackDriver::dbus_message_hook(DBusConnection* /*connection*/, me->signal_attached.emit(); } - me->connect_ports(connection_id, - client_id, - client_name, - port_id, - port_name, - client2_id, - client2_name, - port2_id, - port2_name); + me->_events.emplace( + ConnectionEvent{PortID::jack(client_name, port_name), + PortID::jack(client2_name, port2_name)}); return DBUS_HANDLER_RESULT_HANDLED; } @@ -364,15 +334,9 @@ JackDriver::dbus_message_hook(DBusConnection* /*connection*/, me->signal_attached.emit(); } - me->disconnect_ports(connection_id, - client_id, - client_name, - port_id, - port_name, - client2_id, - client2_name, - port2_id, - port2_name); + me->_events.emplace( + DisconnectionEvent{PortID::jack(client_name, port_name), + PortID::jack(client2_name, port2_name)}); return DBUS_HANDLER_RESULT_HANDLED; } @@ -488,15 +452,11 @@ JackDriver::stop_server() "StopServer", &reply_ptr, DBUS_TYPE_INVALID)) { - return; + error_msg("Error stopping JACK server"); } dbus_message_unref(reply_ptr); - - if (!_server_started) { - _server_started = false; - signal_detached.emit(); - } + signal_detached.emit(); } void @@ -563,179 +523,7 @@ JackDriver::is_attached() const } void -JackDriver::add_port(PatchageModule* module, - PortType type, - const PortID& id, - const std::string& name, - bool is_input) -{ - if (module->get_port(id)) { - return; - } - - auto* port = new PatchagePort(*module, - type, - id, - name, - "", // TODO: pretty name - is_input, - _app->conf()->get_port_color(type), - _app->show_human_names()); - - _app->canvas()->index_port(id, port); -} - -void -JackDriver::add_port(dbus_uint64_t /*client_id*/, - const char* client_name, - dbus_uint64_t /*port_id*/, - const char* port_name, - dbus_uint32_t port_flags, - dbus_uint32_t port_type) -{ - PortType local_port_type; - - switch (port_type) { - case JACKDBUS_PORT_TYPE_AUDIO: - local_port_type = PortType::jack_audio; - break; - case JACKDBUS_PORT_TYPE_MIDI: - local_port_type = PortType::jack_midi; - break; - default: - error_msg("Unknown JACK D-Bus port type"); - return; - } - - SignalDirection type = SignalDirection::duplex; - if (_app->conf()->get_module_split( - client_name, port_flags & JACKDBUS_PORT_FLAG_TERMINAL)) { - if (port_flags & JACKDBUS_PORT_FLAG_INPUT) { - type = SignalDirection::input; - } else { - type = SignalDirection::output; - } - } - - PatchageModule* module = find_or_create_module(type, client_name); - - add_port(module, - local_port_type, - PortID::jack(full_name(client_name, port_name)), - port_name, - port_flags & JACKDBUS_PORT_FLAG_INPUT); -} - -void -JackDriver::remove_port(dbus_uint64_t /*client_id*/, - const char* client_name, - dbus_uint64_t /*port_id*/, - const char* port_name) -{ - const auto port_id = PortID::jack(client_name, port_name); - PatchagePort* const port = _app->canvas()->find_port(port_id); - if (!port) { - error_msg("Unable to remove unknown port"); - return; - } - - auto* module = dynamic_cast<PatchageModule*>(port->get_module()); - - delete port; - - // No empty modules (for now) - if (module->num_ports() == 0) { - delete module; - } - - if (_app->canvas()->empty()) { - if (_server_started) { - signal_detached.emit(); - } - - _server_started = false; - } -} - -PatchageModule* -JackDriver::find_or_create_module(SignalDirection type, const std::string& name) -{ - const auto id = ClientID::jack(name); - PatchageModule* module = _app->canvas()->find_module(id, type); - - if (!module) { - module = new PatchageModule(_app, name, type, id); - module->load_location(); - _app->canvas()->add_module(id, module); - } - - return module; -} - -void -JackDriver::connect_ports(dbus_uint64_t /*connection_id*/, - dbus_uint64_t /*client1_id*/, - const char* client1_name, - dbus_uint64_t /*port1_id*/, - const char* port1_name, - dbus_uint64_t /*client2_id*/, - const char* client2_name, - dbus_uint64_t /*port2_id*/, - const char* port2_name) -{ - const auto tail_id = PortID::jack(client1_name, port1_name); - const auto head_id = PortID::jack(client2_name, port2_name); - - PatchagePort* const tail = _app->canvas()->find_port(tail_id); - if (!tail) { - error_msg( - fmt::format("Unable to connect unknown port \"{}\"", tail_id)); - return; - } - - PatchagePort* const head = _app->canvas()->find_port(head_id); - if (!head) { - error_msg( - fmt::format("Unable to connect unknown port \"{}\"", head_id)); - return; - } - - _app->canvas()->make_connection(tail, head); -} - -void -JackDriver::disconnect_ports(dbus_uint64_t /*connection_id*/, - dbus_uint64_t /*client1_id*/, - const char* client1_name, - dbus_uint64_t /*port1_id*/, - const char* port1_name, - dbus_uint64_t /*client2_id*/, - const char* client2_name, - dbus_uint64_t /*port2_id*/, - const char* port2_name) -{ - const auto tail_id = PortID::jack(client1_name, port1_name); - const auto head_id = PortID::jack(client2_name, port2_name); - - PatchagePort* const tail = _app->canvas()->find_port(tail_id); - if (!tail) { - error_msg( - fmt::format("Unable to disconnect unknown port \"{}\"", tail_id)); - return; - } - - PatchagePort* const head = _app->canvas()->find_port(head_id); - if (!head) { - error_msg( - fmt::format("Unable to disconnect unknown port \"{}\"", head_id)); - return; - } - - _app->canvas()->remove_edge_between(tail, head); -} - -void -JackDriver::refresh() +JackDriver::refresh(const EventSink& sink) { DBusMessage* reply_ptr = nullptr; DBusMessageIter iter = {}; @@ -784,10 +572,9 @@ JackDriver::refresh() dbus_message_iter_get_basic(&iter, &version); dbus_message_iter_next(&iter); - destroy_all(); - _graph_version = version; + // Emit all clients and ports for (dbus_message_iter_recurse(&iter, &clients_array_iter); dbus_message_iter_get_arg_type(&clients_array_iter) != DBUS_TYPE_INVALID; @@ -800,6 +587,9 @@ JackDriver::refresh() dbus_message_iter_get_basic(&client_struct_iter, &client_name); dbus_message_iter_next(&client_struct_iter); + // TODO: Pretty name? + sink({ClientCreationEvent{ClientID::jack(client_name), {client_name}}}); + for (dbus_message_iter_recurse(&client_struct_iter, &ports_array_iter); dbus_message_iter_get_arg_type(&ports_array_iter) != DBUS_TYPE_INVALID; @@ -818,12 +608,9 @@ JackDriver::refresh() dbus_message_iter_get_basic(&port_struct_iter, &port_type); dbus_message_iter_next(&port_struct_iter); - add_port(client_id, - client_name, - port_id, - port_name, - port_flags, - port_type); + sink({PortCreationEvent{ + PortID::jack(client_name, port_name), + port_info(port_name, port_type, port_flags)}}); } dbus_message_iter_next(&client_struct_iter); @@ -831,6 +618,7 @@ JackDriver::refresh() dbus_message_iter_next(&iter); + // Emit all connections for (dbus_message_iter_recurse(&iter, &connections_array_iter); dbus_message_iter_get_arg_type(&connections_array_iter) != DBUS_TYPE_INVALID; @@ -865,15 +653,8 @@ JackDriver::refresh() dbus_message_iter_get_basic(&connection_struct_iter, &connection_id); dbus_message_iter_next(&connection_struct_iter); - connect_ports(connection_id, - client_id, - client_name, - port_id, - port_name, - client2_id, - client2_name, - port2_id, - port2_name); + sink({ConnectionEvent{PortID::jack(client_name, port_name), + PortID::jack(client2_name, port2_name)}}); } } @@ -1155,11 +936,37 @@ JackDriver::reset_max_dsp_load() _max_dsp_load = 0.0; } -PatchagePort* -JackDriver::create_port_view(Patchage*, const PortID&) +PortType +JackDriver::patchage_port_type(const dbus_uint32_t dbus_port_type) const +{ + switch (dbus_port_type) { + case JACKDBUS_PORT_TYPE_AUDIO: + return PortType::jack_audio; + case JACKDBUS_PORT_TYPE_MIDI: + return PortType::jack_midi; + default: + break; + } + + error_msg(fmt::format("Unknown JACK D-Bus port type {}", dbus_port_type)); + return PortType::jack_audio; +} + +PortInfo +JackDriver::port_info(const std::string& port_name, + const dbus_uint32_t port_type, + const dbus_uint32_t port_flags) const { - assert(false); // we dont use events at all - return nullptr; + const SignalDirection direction = + ((port_flags & JACKDBUS_PORT_FLAG_INPUT) ? SignalDirection::input + : SignalDirection::output); + + // TODO: Metadata? + return {port_name, + patchage_port_type(port_type), + direction, + {}, + bool(port_flags & JACKDBUS_PORT_FLAG_TERMINAL)}; } void @@ -1173,3 +980,13 @@ JackDriver::info_msg(const std::string& msg) const { _log.info(std::string{"[JACK] "} + msg); } + +void +JackDriver::process_events(Patchage* app) +{ + while (!_events.empty()) { + PatchageEvent& ev = _events.front(); + handle_event(*app, ev); + _events.pop(); + } +} |