summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-11-28 15:58:38 +0100
committerDavid Robillard <d@drobilla.net>2020-11-28 17:39:10 +0100
commit0f8bd14d3487c35280c33bbfd133dd9e37c8f07e (patch)
tree701cac49a1e6e34025a8352e53845859566106b3
parenta872f8b07498c85f0f2eb8b55462ac9df9ce4677 (diff)
downloadpatchage-0f8bd14d3487c35280c33bbfd133dd9e37c8f07e.tar.gz
patchage-0f8bd14d3487c35280c33bbfd133dd9e37c8f07e.tar.bz2
patchage-0f8bd14d3487c35280c33bbfd133dd9e37c8f07e.zip
Index clients and ports by ID
-rw-r--r--src/AlsaDriver.cpp10
-rw-r--r--src/ClientID.hpp18
-rw-r--r--src/JackDbusDriver.cpp80
-rw-r--r--src/JackDbusDriver.hpp2
-rw-r--r--src/JackDriver.cpp38
-rw-r--r--src/PatchageCanvas.cpp58
-rw-r--r--src/PatchageCanvas.hpp11
-rw-r--r--src/PatchageEvent.cpp2
-rw-r--r--src/PatchageEvent.hpp4
-rw-r--r--src/PatchageModule.cpp4
-rw-r--r--src/PatchageModule.hpp4
-rw-r--r--src/PortID.hpp42
12 files changed, 162 insertions, 111 deletions
diff --git a/src/AlsaDriver.cpp b/src/AlsaDriver.cpp
index 3ef466d..702cc00 100644
--- a/src/AlsaDriver.cpp
+++ b/src/AlsaDriver.cpp
@@ -234,7 +234,7 @@ AlsaDriver::find_or_create_module(Patchage* patchage,
m = new PatchageModule(
patchage, client_name, type, ClientID::alsa(client_id));
m->load_location();
- _app->canvas()->add_module(client_name, m);
+ _app->canvas()->add_module(ClientID::alsa(client_id), m);
_modules.insert(std::make_pair(client_id, m));
}
return m;
@@ -292,10 +292,12 @@ AlsaDriver::create_port_view_internal(snd_seq_addr_t addr,
split = _app->conf()->get_module_split(client_name, !is_application);
}
+ const auto port_id = PortID::alsa(addr.client, addr.port, is_input);
+
if (!split) {
parent = find_or_create_module(
_app, addr.client, client_name, ModuleType::input_output);
- if (!parent->get_port(port_name)) {
+ if (!parent->get_port(port_id)) {
port = create_port(*parent, port_name, is_input, addr);
port->show();
}
@@ -307,7 +309,7 @@ AlsaDriver::create_port_view_internal(snd_seq_addr_t addr,
parent = find_or_create_module(
_app, addr.client, client_name, module_type);
- if (!parent->get_port(port_name)) {
+ if (!parent->get_port(port_id)) {
port = create_port(*parent, port_name, is_input, addr);
port->show();
}
@@ -318,7 +320,7 @@ AlsaDriver::create_port_view_internal(snd_seq_addr_t addr,
((!is_input) ? ModuleType::input : ModuleType::output);
parent = find_or_create_module(
_app, addr.client, client_name, flipped_module_type);
- if (!parent->get_port(port_name)) {
+ if (!parent->get_port(port_id)) {
port = create_port(*parent, port_name, !is_input, addr);
port->show();
}
diff --git a/src/ClientID.hpp b/src/ClientID.hpp
index 43b56ec..639cbbf 100644
--- a/src/ClientID.hpp
+++ b/src/ClientID.hpp
@@ -86,6 +86,24 @@ operator<<(std::ostream& os, const ClientID& id)
}
static inline bool
+operator==(const ClientID& lhs, const ClientID& rhs)
+{
+ if (lhs.type() != rhs.type()) {
+ return false;
+ }
+
+ switch (lhs.type()) {
+ case ClientID::Type::jack:
+ return lhs.jack_name() == rhs.jack_name();
+ case ClientID::Type::alsa:
+ return lhs.alsa_id() == rhs.alsa_id();
+ }
+
+ assert(false);
+ return false;
+}
+
+static inline bool
operator<(const ClientID& lhs, const ClientID& rhs)
{
if (lhs.type() != rhs.type()) {
diff --git a/src/JackDbusDriver.cpp b/src/JackDbusDriver.cpp
index 25ba144..211b6ae 100644
--- a/src/JackDbusDriver.cpp
+++ b/src/JackDbusDriver.cpp
@@ -28,6 +28,7 @@
PATCHAGE_DISABLE_FMT_WARNINGS
#include <fmt/core.h>
+#include <fmt/ostream.h>
PATCHAGE_RESTORE_WARNINGS
#include <dbus/dbus-glib-lowlevel.h>
@@ -598,22 +599,24 @@ JackDriver::is_attached() const
void
JackDriver::add_port(PatchageModule* module,
PortType type,
- PortID id,
+ const PortID& id,
const std::string& name,
bool is_input)
{
- if (module->get_port(name)) {
+ if (module->get_port(id)) {
return;
}
- new PatchagePort(*module,
- type,
- std::move(id),
- name,
- "", // TODO: pretty name
- is_input,
- _app->conf()->get_port_color(type),
- _app->show_human_names());
+ 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
@@ -663,8 +666,8 @@ JackDriver::remove_port(dbus_uint64_t /*client_id*/,
dbus_uint64_t /*port_id*/,
const char* port_name)
{
- PatchagePort* port =
- _app->canvas()->find_port_by_name(client_name, 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;
@@ -691,12 +694,13 @@ JackDriver::remove_port(dbus_uint64_t /*client_id*/,
PatchageModule*
JackDriver::find_or_create_module(ModuleType type, const std::string& name)
{
- PatchageModule* module = _app->canvas()->find_module(name, type);
+ const auto id = ClientID::jack(name);
+ PatchageModule* module = _app->canvas()->find_module(id, type);
if (!module) {
- module = new PatchageModule(_app, name, type, ClientID::jack(name));
+ module = new PatchageModule(_app, name, type, id);
module->load_location();
- _app->canvas()->add_module(name, module);
+ _app->canvas()->add_module(id, module);
}
return module;
@@ -713,23 +717,24 @@ JackDriver::connect_ports(dbus_uint64_t /*connection_id*/,
dbus_uint64_t /*port2_id*/,
const char* port2_name)
{
- PatchagePort* port1 =
- _app->canvas()->find_port_by_name(client1_name, port1_name);
- if (!port1) {
- error_msg(std::string{"Unable to connect unknown port '"} + port1_name +
- "' of client '" + client1_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* port2 =
- _app->canvas()->find_port_by_name(client2_name, port2_name);
- if (!port2) {
- error_msg(std::string{"Unable to connect unknown port '"} + port2_name +
- "' of client '" + client2_name + "'");
+ 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(port1, port2);
+ _app->canvas()->make_connection(tail, head);
}
void
@@ -743,23 +748,24 @@ JackDriver::disconnect_ports(dbus_uint64_t /*connection_id*/,
dbus_uint64_t /*port2_id*/,
const char* port2_name)
{
- PatchagePort* port1 =
- _app->canvas()->find_port_by_name(client1_name, port1_name);
- if (!port1) {
- error_msg(std::string{"Unable to disconnect unknown port '"} +
- port1_name + "' of client '" + client1_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* port2 =
- _app->canvas()->find_port_by_name(client2_name, port2_name);
- if (!port2) {
- error_msg(std::string{"Unable to disconnect unknown port '"} +
- port2_name + "' of client '" + client2_name + "'");
+ 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(port1, port2);
+ _app->canvas()->remove_edge_between(tail, head);
}
void
diff --git a/src/JackDbusDriver.hpp b/src/JackDbusDriver.hpp
index c28c1d5..a92e553 100644
--- a/src/JackDbusDriver.hpp
+++ b/src/JackDbusDriver.hpp
@@ -81,7 +81,7 @@ private:
void add_port(PatchageModule* module,
PortType type,
- PortID id,
+ const PortID& id,
const std::string& name,
bool is_input);
diff --git a/src/JackDriver.cpp b/src/JackDriver.cpp
index 0d8c2b9..36dfa47 100644
--- a/src/JackDriver.cpp
+++ b/src/JackDriver.cpp
@@ -137,6 +137,8 @@ JackDriver::create_port_view(Patchage* patchage, const PortID& id)
{
assert(id.type() == PortID::Type::jack);
+ const auto client_id = id.client();
+
jack_port_t* const jack_port =
jack_port_by_name(_client, id.jack_name().c_str());
if (!jack_port) {
@@ -161,15 +163,15 @@ JackDriver::create_port_view(Patchage* patchage, const PortID& id)
}
}
- PatchageModule* parent = _app->canvas()->find_module(module_name, type);
+ PatchageModule* parent = _app->canvas()->find_module(client_id, type);
if (!parent) {
parent = new PatchageModule(
patchage, module_name, type, ClientID::jack(module_name));
parent->load_location();
- patchage->canvas()->add_module(module_name, parent);
+ patchage->canvas()->add_module(client_id, parent);
}
- if (parent->get_port(port_name)) {
+ if (parent->get_port(id)) {
_log.error(fmt::format("[JACK] Module \"{}\" already has port \"{}\"",
module_name,
port_name));
@@ -315,16 +317,18 @@ JackDriver::refresh()
}
}
- PatchageModule* m = _app->canvas()->find_module(client1_name, type);
+ const auto port1_id = PortID::jack(ports[i]);
+ const auto client1_id = ClientID::jack(client1_name);
+
+ PatchageModule* m = _app->canvas()->find_module(client1_id, type);
if (!m) {
- m = new PatchageModule(
- _app, client1_name, type, ClientID::jack(client1_name));
+ m = new PatchageModule(_app, client1_name, type, client1_id);
m->load_location();
- _app->canvas()->add_module(client1_name, m);
+ _app->canvas()->add_module(client1_id, m);
}
- if (!m->get_port(jack_port_short_name(port))) {
+ if (!m->get_port(port1_id)) {
create_port(*m, port, PortID::jack(ports[i]));
}
}
@@ -344,8 +348,11 @@ JackDriver::refresh()
? ModuleType::input
: ModuleType::output;
+ const auto port1_id = PortID::jack(ports[i]);
+ const auto client1_id = ClientID::jack(client1_name);
+
PatchageModule* client1_module =
- _app->canvas()->find_module(client1_name, port1_type);
+ _app->canvas()->find_module(client1_id, port1_type);
if (connected_ports) {
for (int j = 0; connected_ports[j]; ++j) {
@@ -355,15 +362,18 @@ JackDriver::refresh()
port2_name = client2_name.substr(colon + 1);
client2_name = client2_name.substr(0, colon);
+ const auto port2_id = PortID::jack(connected_ports[j]);
+ const auto client2_id = ClientID::jack(client2_name);
+
const ModuleType port2_type = (port1_type == ModuleType::input)
? ModuleType::output
: ModuleType::input;
PatchageModule* client2_module =
- _app->canvas()->find_module(client2_name, port2_type);
+ _app->canvas()->find_module(client2_id, port2_type);
- Ganv::Port* port1 = client1_module->get_port(port1_name);
- Ganv::Port* port2 = client2_module->get_port(port2_name);
+ Ganv::Port* port1 = client1_module->get_port(port1_id);
+ Ganv::Port* port2 = client2_module->get_port(port2_id);
if (!port1 || !port2) {
continue;
@@ -474,9 +484,9 @@ JackDriver::jack_client_registration_cb(const char* name,
assert(me->_client);
if (registered) {
- me->_events.emplace(ClientCreationEvent{name});
+ me->_events.emplace(ClientCreationEvent{ClientID::jack(name)});
} else {
- me->_events.emplace(ClientDestructionEvent{name});
+ me->_events.emplace(ClientDestructionEvent{ClientID::jack(name)});
}
}
diff --git a/src/PatchageCanvas.cpp b/src/PatchageCanvas.cpp
index 167df2b..f31c2f9 100644
--- a/src/PatchageCanvas.cpp
+++ b/src/PatchageCanvas.cpp
@@ -40,23 +40,18 @@ PatchageCanvas::PatchageCanvas(Connector& connector, int width, int height)
}
PatchageModule*
-PatchageCanvas::find_module(const std::string& name, ModuleType type)
+PatchageCanvas::find_module(const ClientID& id, const ModuleType type)
{
- const ModuleIndex::const_iterator i = _module_index.find(name);
- if (i == _module_index.end()) {
- return nullptr;
- }
+ auto i = _module_index.find(id);
PatchageModule* io_module = nullptr;
- for (ModuleIndex::const_iterator j = i;
- j != _module_index.end() && j->first == name;
- ++j) {
- if (j->second->type() == type) {
- return j->second;
+ for (; i != _module_index.end() && i->first == id; ++i) {
+ if (i->second->type() == type) {
+ return i->second;
}
- if (j->second->type() == ModuleType::input_output) {
- io_module = j->second;
+ if (i->second->type() == ModuleType::input_output) {
+ io_module = i->second;
}
}
@@ -65,13 +60,13 @@ PatchageCanvas::find_module(const std::string& name, ModuleType type)
}
void
-PatchageCanvas::remove_module(const std::string& name)
+PatchageCanvas::remove_module(const ClientID& id)
{
- auto i = _module_index.find(name);
+ auto i = _module_index.find(id);
while (i != _module_index.end()) {
PatchageModule* mod = i->second;
_module_index.erase(i);
- i = _module_index.find(name);
+ i = _module_index.find(id);
delete mod;
}
}
@@ -161,27 +156,6 @@ PatchageCanvas::remove_ports(bool (*pred)(const PatchagePort*))
}
}
-PatchagePort*
-PatchageCanvas::find_port_by_name(const std::string& client_name,
- const std::string& port_name)
-{
- const ModuleIndex::const_iterator i = _module_index.find(client_name);
- if (i == _module_index.end()) {
- return nullptr;
- }
-
- for (ModuleIndex::const_iterator j = i;
- j != _module_index.end() && j->first == client_name;
- ++j) {
- PatchagePort* port = j->second->get_port(port_name);
- if (port) {
- return port;
- }
- }
-
- return nullptr;
-}
-
void
PatchageCanvas::on_connect(Ganv::Node* port1, Ganv::Node* port2)
{
@@ -213,18 +187,18 @@ PatchageCanvas::on_disconnect(Ganv::Node* port1, Ganv::Node* port2)
}
void
-PatchageCanvas::add_module(const std::string& name, PatchageModule* module)
+PatchageCanvas::add_module(const ClientID& id, PatchageModule* module)
{
- _module_index.insert(std::make_pair(name, module));
+ _module_index.emplace(id, module);
// Join partners, if applicable
PatchageModule* in_module = nullptr;
PatchageModule* out_module = nullptr;
if (module->type() == ModuleType::input) {
in_module = module;
- out_module = find_module(name, ModuleType::output);
+ out_module = find_module(id, ModuleType::output);
} else if (module->type() == ModuleType::output) {
- in_module = find_module(name, ModuleType::output);
+ in_module = find_module(id, ModuleType::output);
out_module = module;
}
@@ -264,8 +238,8 @@ void
PatchageCanvas::remove_module(PatchageModule* module)
{
// Remove module from cache
- for (auto i = _module_index.find(module->get_label());
- i != _module_index.end() && i->first == module->get_label();
+ for (auto i = _module_index.find(module->id());
+ i != _module_index.end() && i->first == module->id();
++i) {
if (i->second == module) {
_module_index.erase(i);
diff --git a/src/PatchageCanvas.hpp b/src/PatchageCanvas.hpp
index 349512b..7f68b9c 100644
--- a/src/PatchageCanvas.hpp
+++ b/src/PatchageCanvas.hpp
@@ -45,15 +45,12 @@ class PatchageCanvas : public Ganv::Canvas
public:
PatchageCanvas(Connector& connector, int width, int height);
- PatchageModule* find_module(const std::string& name, ModuleType type);
+ PatchageModule* find_module(const ClientID& id, ModuleType type);
PatchagePort* find_port(const PortID& id);
- void remove_module(const std::string& name);
+ void remove_module(const ClientID& id);
void remove_module(PatchageModule* module);
- PatchagePort* find_port_by_name(const std::string& client_name,
- const std::string& port_name);
-
void index_port(const PortID& id, PatchagePort* port)
{
_port_index.insert(std::make_pair(id, port));
@@ -61,7 +58,7 @@ public:
void remove_ports(bool (*pred)(const PatchagePort*));
- void add_module(const std::string& name, PatchageModule* module);
+ void add_module(const ClientID& id, PatchageModule* module);
bool make_connection(Ganv::Node* tail, Ganv::Node* head);
@@ -71,7 +68,7 @@ public:
private:
using PortIndex = std::map<const PortID, PatchagePort*>;
- using ModuleIndex = std::multimap<const std::string, PatchageModule*>;
+ using ModuleIndex = std::multimap<const ClientID, PatchageModule*>;
friend void disconnect_edge(GanvEdge*, void*);
diff --git a/src/PatchageEvent.cpp b/src/PatchageEvent.cpp
index 353bb16..0896b49 100644
--- a/src/PatchageEvent.cpp
+++ b/src/PatchageEvent.cpp
@@ -57,7 +57,7 @@ public:
void operator()(const ClientDestructionEvent& event)
{
- _patchage.canvas()->remove_module(event.name);
+ _patchage.canvas()->remove_module(event.id);
}
void operator()(const PortCreationEvent& event)
diff --git a/src/PatchageEvent.hpp b/src/PatchageEvent.hpp
index b4aa640..f2fa99d 100644
--- a/src/PatchageEvent.hpp
+++ b/src/PatchageEvent.hpp
@@ -32,12 +32,12 @@ struct NoopEvent
struct ClientCreationEvent
{
- std::string name;
+ ClientID id;
};
struct ClientDestructionEvent
{
- std::string name;
+ ClientID id;
};
struct PortCreationEvent
diff --git a/src/PatchageModule.cpp b/src/PatchageModule.cpp
index 574757f..63a268c 100644
--- a/src/PatchageModule.cpp
+++ b/src/PatchageModule.cpp
@@ -147,11 +147,11 @@ PatchageModule::menu_disconnect_all()
}
PatchagePort*
-PatchageModule::get_port(const std::string& name)
+PatchageModule::get_port(const PortID& id)
{
for (Ganv::Port* p : *this) {
auto* pport = dynamic_cast<PatchagePort*>(p);
- if (pport && pport->name() == name) {
+ if (pport && pport->id() == id) {
return pport;
}
}
diff --git a/src/PatchageModule.hpp b/src/PatchageModule.hpp
index e5abe43..6953124 100644
--- a/src/PatchageModule.hpp
+++ b/src/PatchageModule.hpp
@@ -30,6 +30,8 @@ PATCHAGE_RESTORE_WARNINGS
#include <string>
+struct PortID;
+
class Patchage;
class PatchagePort;
@@ -57,7 +59,7 @@ public:
bool show_menu(GdkEventButton* ev);
void update_menu();
- PatchagePort* get_port(const std::string& name);
+ PatchagePort* get_port(const PortID& id);
void load_location();
void menu_disconnect_all();
diff --git a/src/PortID.hpp b/src/PortID.hpp
index 4887a27..e399220 100644
--- a/src/PortID.hpp
+++ b/src/PortID.hpp
@@ -17,6 +17,7 @@
#ifndef PATCHAGE_PORTID_HPP
#define PATCHAGE_PORTID_HPP
+#include "ClientID.hpp"
#include "ClientType.hpp"
#include <cassert>
@@ -44,6 +45,13 @@ struct PortID
return PortID{Type::jack, std::move(name)};
}
+ /// Return an ID for a JACK port by separate client and port name
+ static PortID
+ jack(const std::string& client_name, const std::string& port_name)
+ {
+ return PortID{Type::jack, client_name + ":" + port_name};
+ }
+
/// Return an ID for an ALSA Sequencer port by ID
static PortID
alsa(const uint8_t client_id, const uint8_t port, const bool is_input)
@@ -51,6 +59,17 @@ struct PortID
return PortID{Type::alsa, client_id, port, is_input};
}
+ /// Return the ID of the client that hosts this port
+ ClientID client() const
+ {
+ switch (_type) {
+ case Type::jack:
+ return ClientID::jack(_jack_name.substr(0, _jack_name.find(':')));
+ case Type::alsa:
+ return ClientID::alsa(_alsa_client);
+ }
+ }
+
Type type() const { return _type; }
const std::string& jack_name() const { return _jack_name; }
uint8_t alsa_client() const { return _alsa_client; }
@@ -64,6 +83,8 @@ private:
{
assert(_type == Type::jack);
assert(_jack_name.find(':') != std::string::npos);
+ assert(_jack_name.find(':') > 0);
+ assert(_jack_name.find(':') < _jack_name.length() - 1);
}
PortID(const Type type,
@@ -102,6 +123,27 @@ operator<<(std::ostream& os, const PortID& id)
}
static inline bool
+operator==(const PortID& lhs, const PortID& rhs)
+{
+ if (lhs.type() != rhs.type()) {
+ return false;
+ }
+
+ switch (lhs.type()) {
+ case PortID::Type::jack:
+ return lhs.jack_name() == rhs.jack_name();
+ case PortID::Type::alsa:
+ return std::make_tuple(
+ lhs.alsa_client(), lhs.alsa_port(), lhs.alsa_is_input()) ==
+ std::make_tuple(
+ rhs.alsa_client(), rhs.alsa_port(), rhs.alsa_is_input());
+ }
+
+ assert(false);
+ return false;
+}
+
+static inline bool
operator<(const PortID& lhs, const PortID& rhs)
{
if (lhs.type() != rhs.type()) {