summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-11-28 22:23:54 +0100
committerDavid Robillard <d@drobilla.net>2020-11-28 22:49:10 +0100
commit924775a79c07a4f5798fcefddb523b189e473080 (patch)
tree6a201df93b109d10cb5c5cab018ee89448c00e00
parent5128bfab7ddb9504abf17375e910e5bc94af291e (diff)
downloadpatchage-924775a79c07a4f5798fcefddb523b189e473080.tar.gz
patchage-924775a79c07a4f5798fcefddb523b189e473080.tar.bz2
patchage-924775a79c07a4f5798fcefddb523b189e473080.zip
Abstract out sending of events
This removes the details of how events are handled from drivers, so the owner can set them up to do anything. For example, a driver could be run in the GUI thread and have its events simply dispatched immediately, but here everything is enqueued to the same queue which is drained later for simplicity.
-rw-r--r--src/AlsaDriver.cpp34
-rw-r--r--src/AlsaDriver.hpp10
-rw-r--r--src/Driver.hpp10
-rw-r--r--src/JackDbusDriver.cpp25
-rw-r--r--src/JackDbusDriver.hpp8
-rw-r--r--src/JackDriver.cpp29
-rw-r--r--src/JackDriver.hpp9
-rw-r--r--src/Patchage.cpp42
-rw-r--r--src/Patchage.hpp9
9 files changed, 74 insertions, 102 deletions
diff --git a/src/AlsaDriver.cpp b/src/AlsaDriver.cpp
index 6e1cebb..a417469 100644
--- a/src/AlsaDriver.cpp
+++ b/src/AlsaDriver.cpp
@@ -23,7 +23,6 @@
#include "PortInfo.hpp"
#include "PortType.hpp"
#include "SignalDirection.hpp"
-#include "handle_event.hpp"
PATCHAGE_DISABLE_FMT_WARNINGS
#include <fmt/core.h>
@@ -84,8 +83,9 @@ port_info(const snd_seq_port_info_t* const pinfo)
} // namespace
-AlsaDriver::AlsaDriver(ILog& log)
- : _log(log)
+AlsaDriver::AlsaDriver(ILog& log, EventSink emit_event)
+ : Driver{std::move(emit_event)}
+ , _log(log)
, _seq(nullptr)
, _refresh_thread{}
{}
@@ -425,19 +425,17 @@ AlsaDriver::_refresh_main()
while (snd_seq_event_input(_seq, &ev) > 0) {
assert(ev);
- std::lock_guard<std::mutex> lock{_events_mutex};
-
switch (ev->type) {
case SND_SEQ_EVENT_CLIENT_START:
snd_seq_get_any_client_info(_seq, ev->data.addr.client, cinfo);
- _events.emplace(ClientCreationEvent{
+ _emit_event(ClientCreationEvent{
ClientID::alsa(ev->data.addr.client),
client_info(cinfo),
});
break;
case SND_SEQ_EVENT_CLIENT_EXIT:
- _events.emplace(ClientDestructionEvent{
+ _emit_event(ClientDestructionEvent{
ClientID::alsa(ev->data.addr.client),
});
break;
@@ -452,7 +450,7 @@ AlsaDriver::_refresh_main()
caps = snd_seq_port_info_get_capability(pinfo);
if (!ignore(ev->data.addr)) {
- _events.emplace(PortCreationEvent{
+ _emit_event(PortCreationEvent{
addr_to_id(ev->data.addr, (caps & SND_SEQ_PORT_CAP_READ)),
port_info(pinfo),
});
@@ -463,9 +461,9 @@ AlsaDriver::_refresh_main()
if (!ignore(ev->data.addr, false)) {
// Note: getting caps at this point does not work
// Delete both inputs and outputs (to handle duplex ports)
- _events.emplace(
+ _emit_event(
PortDestructionEvent{addr_to_id(ev->data.addr, true)});
- _events.emplace(
+ _emit_event(
PortDestructionEvent{addr_to_id(ev->data.addr, false)});
}
break;
@@ -476,7 +474,7 @@ AlsaDriver::_refresh_main()
case SND_SEQ_EVENT_PORT_SUBSCRIBED:
if (!ignore(ev->data.connect.sender) &&
!ignore(ev->data.connect.dest)) {
- _events.emplace(
+ _emit_event(
ConnectionEvent{addr_to_id(ev->data.connect.sender, false),
addr_to_id(ev->data.connect.dest, true)});
}
@@ -485,7 +483,7 @@ AlsaDriver::_refresh_main()
case SND_SEQ_EVENT_PORT_UNSUBSCRIBED:
if (!ignore(ev->data.connect.sender) &&
!ignore(ev->data.connect.dest)) {
- _events.emplace(DisconnectionEvent{
+ _emit_event(DisconnectionEvent{
addr_to_id(ev->data.connect.sender, false),
addr_to_id(ev->data.connect.dest, true)});
}
@@ -497,15 +495,3 @@ AlsaDriver::_refresh_main()
}
}
}
-
-void
-AlsaDriver::process_events(Patchage* app)
-{
- std::lock_guard<std::mutex> lock{_events_mutex};
-
- while (!_events.empty()) {
- PatchageEvent& ev = _events.front();
- handle_event(*app, ev);
- _events.pop();
- }
-}
diff --git a/src/AlsaDriver.hpp b/src/AlsaDriver.hpp
index 15a5086..2f4b1e3 100644
--- a/src/AlsaDriver.hpp
+++ b/src/AlsaDriver.hpp
@@ -23,19 +23,16 @@
#include <pthread.h>
#include <map>
-#include <mutex>
-#include <queue>
#include <set>
#include <string>
class ILog;
-class Patchage;
/// Driver for ALSA Sequencer ports
class AlsaDriver : public Driver
{
public:
- explicit AlsaDriver(ILog& log);
+ explicit AlsaDriver(ILog& log, EventSink emit_event);
AlsaDriver(const AlsaDriver&) = delete;
AlsaDriver& operator=(const AlsaDriver&) = delete;
@@ -57,8 +54,6 @@ public:
void print_addr(snd_seq_addr_t addr);
- void process_events(Patchage* app) override;
-
private:
bool create_refresh_port();
static void* refresh_main(void* me);
@@ -68,9 +63,6 @@ private:
snd_seq_t* _seq;
pthread_t _refresh_thread;
- std::mutex _events_mutex;
- std::queue<PatchageEvent> _events;
-
struct SeqAddrComparator
{
bool operator()(const snd_seq_addr_t& a, const snd_seq_addr_t& b) const
diff --git a/src/Driver.hpp b/src/Driver.hpp
index d40f7b5..d85e5bc 100644
--- a/src/Driver.hpp
+++ b/src/Driver.hpp
@@ -22,6 +22,7 @@
#include <sigc++/sigc++.h>
#include <functional>
+#include <utility>
class Patchage;
@@ -31,7 +32,9 @@ class Driver
public:
using EventSink = std::function<void(const PatchageEvent&)>;
- Driver() = default;
+ explicit Driver(EventSink emit_event)
+ : _emit_event{std::move(emit_event)}
+ {}
Driver(const Driver&) = delete;
Driver& operator=(const Driver&) = delete;
@@ -41,8 +44,6 @@ public:
virtual ~Driver() = default;
- virtual void process_events(Patchage* app) = 0;
-
virtual void attach(bool launch_daemon) = 0;
virtual void detach() = 0;
virtual bool is_attached() const = 0;
@@ -54,6 +55,9 @@ public:
sigc::signal<void> signal_attached;
sigc::signal<void> signal_detached;
+
+protected:
+ EventSink _emit_event;
};
#endif // PATCHAGE_DRIVER_HPP
diff --git a/src/JackDbusDriver.cpp b/src/JackDbusDriver.cpp
index 85dfae3..4d780a7 100644
--- a/src/JackDbusDriver.cpp
+++ b/src/JackDbusDriver.cpp
@@ -20,11 +20,11 @@
#include "patchage_config.h"
#include "Driver.hpp"
+#include "ILog.hpp"
#include "PatchageEvent.hpp"
#include "PortNames.hpp"
#include "PortType.hpp"
#include "SignalDirection.hpp"
-#include "handle_event.hpp"
#include "warnings.hpp"
PATCHAGE_DISABLE_FMT_WARNINGS
@@ -55,8 +55,9 @@ PATCHAGE_RESTORE_WARNINGS
#define JACKDBUS_PORT_TYPE_AUDIO 0
#define JACKDBUS_PORT_TYPE_MIDI 1
-JackDriver::JackDriver(ILog& log)
- : _log(log)
+JackDriver::JackDriver(ILog& log, EventSink emit_event)
+ : Driver{std::move(emit_event)}
+ , _log(log)
, _dbus_error()
, _dbus_connection(nullptr)
, _max_dsp_load(0.0f)
@@ -210,7 +211,7 @@ JackDriver::dbus_message_hook(DBusConnection* /*connection*/,
me->signal_attached.emit();
}
- me->_events.emplace(
+ me->_emit_event(
PortCreationEvent{PortID::jack(client_name, port_name),
me->port_info(port_name, port_type, port_flags)});
@@ -245,7 +246,7 @@ JackDriver::dbus_message_hook(DBusConnection* /*connection*/,
me->signal_attached.emit();
}
- me->_events.emplace(
+ me->_emit_event(
PortDestructionEvent{PortID::jack(client_name, port_name)});
return DBUS_HANDLER_RESULT_HANDLED;
@@ -289,7 +290,7 @@ JackDriver::dbus_message_hook(DBusConnection* /*connection*/,
me->signal_attached.emit();
}
- me->_events.emplace(
+ me->_emit_event(
ConnectionEvent{PortID::jack(client_name, port_name),
PortID::jack(client2_name, port2_name)});
@@ -334,7 +335,7 @@ JackDriver::dbus_message_hook(DBusConnection* /*connection*/,
me->signal_attached.emit();
}
- me->_events.emplace(
+ me->_emit_event(
DisconnectionEvent{PortID::jack(client_name, port_name),
PortID::jack(client2_name, port2_name)});
@@ -980,13 +981,3 @@ 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();
- }
-}
diff --git a/src/JackDbusDriver.hpp b/src/JackDbusDriver.hpp
index db77658..a40af72 100644
--- a/src/JackDbusDriver.hpp
+++ b/src/JackDbusDriver.hpp
@@ -19,14 +19,12 @@
#define PATCHAGE_JACKDBUSDRIVER_HPP
#include "Driver.hpp"
-#include "Patchage.hpp"
#include <dbus/dbus.h>
#include <glibmm/thread.h>
#include <jack/jack.h>
#include <jack/statistics.h>
-#include <queue>
#include <string>
class ILog;
@@ -34,7 +32,7 @@ class ILog;
class JackDriver : public Driver
{
public:
- explicit JackDriver(ILog& log);
+ explicit JackDriver(ILog& log, EventSink emit_event);
JackDriver(const JackDriver&) = delete;
JackDriver& operator=(const JackDriver&) = delete;
@@ -64,8 +62,6 @@ public:
jack_nframes_t buffer_size();
bool set_buffer_size(jack_nframes_t size);
- void process_events(Patchage* app) override;
-
private:
PortType patchage_port_type(dbus_uint32_t dbus_port_type) const;
@@ -104,8 +100,6 @@ private:
DBusConnection* _dbus_connection;
float _max_dsp_load;
- std::queue<PatchageEvent> _events;
-
bool _server_responding;
bool _server_started;
diff --git a/src/JackDriver.cpp b/src/JackDriver.cpp
index cfcc541..9046c5d 100644
--- a/src/JackDriver.cpp
+++ b/src/JackDriver.cpp
@@ -24,7 +24,6 @@
#include "PortNames.hpp"
#include "PortType.hpp"
#include "SignalDirection.hpp"
-#include "handle_event.hpp"
#include "patchage_config.h"
#ifdef HAVE_JACK_METADATA
@@ -44,9 +43,11 @@ PATCHAGE_RESTORE_WARNINGS
#include <set>
#include <string>
#include <unordered_set>
+#include <utility>
-JackDriver::JackDriver(ILog& log)
- : _log(log)
+JackDriver::JackDriver(ILog& log, EventSink emit_event)
+ : Driver{std::move(emit_event)}
+ , _log(log)
, _client(nullptr)
, _last_pos{}
, _buffer_size(0)
@@ -345,9 +346,9 @@ JackDriver::jack_client_registration_cb(const char* name,
assert(me->_client);
if (registered) {
- me->_events.emplace(ClientCreationEvent{ClientID::jack(name), {name}});
+ me->_emit_event(ClientCreationEvent{ClientID::jack(name), {name}});
} else {
- me->_events.emplace(ClientDestructionEvent{ClientID::jack(name)});
+ me->_emit_event(ClientDestructionEvent{ClientID::jack(name)});
}
}
@@ -364,9 +365,9 @@ JackDriver::jack_port_registration_cb(jack_port_id_t port_id,
const auto id = PortID::jack(name);
if (registered) {
- me->_events.emplace(PortCreationEvent{id, me->get_port_info(port)});
+ me->_emit_event(PortCreationEvent{id, me->get_port_info(port)});
} else {
- me->_events.emplace(PortDestructionEvent{id});
+ me->_emit_event(PortDestructionEvent{id});
}
}
@@ -385,10 +386,10 @@ JackDriver::jack_port_connect_cb(jack_port_id_t src,
const char* const dst_name = jack_port_name(dst_port);
if (connect) {
- me->_events.emplace(
+ me->_emit_event(
ConnectionEvent{PortID::jack(src_name), PortID::jack(dst_name)});
} else {
- me->_events.emplace(
+ me->_emit_event(
DisconnectionEvent{PortID::jack(src_name), PortID::jack(dst_name)});
}
}
@@ -486,13 +487,3 @@ JackDriver::set_buffer_size(jack_nframes_t size)
_buffer_size = size;
return true;
}
-
-void
-JackDriver::process_events(Patchage* app)
-{
- while (!_events.empty()) {
- PatchageEvent& ev = _events.front();
- handle_event(*app, ev);
- _events.pop();
- }
-}
diff --git a/src/JackDriver.hpp b/src/JackDriver.hpp
index 1e680a0..6c9c05e 100644
--- a/src/JackDriver.hpp
+++ b/src/JackDriver.hpp
@@ -19,24 +19,21 @@
#include "ClientInfo.hpp"
#include "Driver.hpp"
-#include "PatchageEvent.hpp"
#include "PortInfo.hpp"
#include <glibmm/thread.h>
#include <jack/jack.h>
#include <mutex>
-#include <queue>
#include <string>
class ILog;
-class Patchage;
/// Driver for JACK audio and midi ports
class JackDriver : public Driver
{
public:
- explicit JackDriver(ILog& log);
+ explicit JackDriver(ILog& log, EventSink emit_event);
JackDriver(const JackDriver&) = delete;
JackDriver& operator=(const JackDriver&) = delete;
@@ -73,8 +70,6 @@ public:
jack_nframes_t buffer_size();
bool set_buffer_size(jack_nframes_t size);
- void process_events(Patchage* app) override;
-
private:
ClientInfo get_client_info(const char* name);
PortInfo get_port_info(const jack_port_t* port);
@@ -101,8 +96,6 @@ private:
ILog& _log;
jack_client_t* _client;
- std::queue<PatchageEvent> _events;
-
std::mutex _shutdown_mutex;
jack_position_t _last_pos;
diff --git a/src/Patchage.cpp b/src/Patchage.cpp
index e0b5dc7..5147c44 100644
--- a/src/Patchage.cpp
+++ b/src/Patchage.cpp
@@ -344,7 +344,9 @@ Patchage::Patchage(int argc, char** argv)
#endif
#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS)
- _jack_driver = new JackDriver(_log);
+ _jack_driver = new JackDriver(
+ _log, [this](const PatchageEvent& event) { on_driver_event(event); });
+
_connector.add_driver(PortID::Type::jack, _jack_driver);
_jack_driver->signal_detached.connect(
@@ -357,7 +359,9 @@ Patchage::Patchage(int argc, char** argv)
#endif
#ifdef HAVE_ALSA
- _alsa_driver = new AlsaDriver(_log);
+ _alsa_driver = new AlsaDriver(
+ _log, [this](const PatchageEvent& event) { on_driver_event(event); });
+
_connector.add_driver(PortID::Type::alsa, _alsa_driver);
#endif
@@ -443,19 +447,8 @@ Patchage::idle_callback()
_attach = false;
}
- // Process any JACK events
-#if defined(PATCHAGE_LIBJACK) || defined(HAVE_JACK_DBUS)
- if (_jack_driver) {
- _jack_driver->process_events(this);
- }
-#endif
-
- // Process any ALSA events
-#ifdef HAVE_ALSA
- if (_alsa_driver) {
- _alsa_driver->process_events(this);
- }
-#endif
+ // Process any events from drivers
+ process_events();
// Do a full refresh
if (_refresh) {
@@ -615,6 +608,25 @@ Patchage::update_state()
_canvas->for_each_node(load_module_location, nullptr);
}
+void
+Patchage::on_driver_event(const PatchageEvent& event)
+{
+ std::lock_guard<std::mutex> lock{_events_mutex};
+
+ _driver_events.emplace(event);
+}
+
+void
+Patchage::process_events()
+{
+ std::lock_guard<std::mutex> lock{_events_mutex};
+
+ while (!_driver_events.empty()) {
+ handle_event(*this, _driver_events.front());
+ _driver_events.pop();
+ }
+}
+
/** Update the sensitivity status of menus to reflect the present.
*
* (eg. disable "Connect to Jack" when Patchage is already connected to Jack)
diff --git a/src/Patchage.hpp b/src/Patchage.hpp
index daae7c7..b358f34 100644
--- a/src/Patchage.hpp
+++ b/src/Patchage.hpp
@@ -42,11 +42,14 @@
#include "ILog.hpp"
#include "Legend.hpp"
#include "Metadata.hpp"
+#include "PatchageEvent.hpp"
#include "TextViewLog.hpp"
#include "Widget.hpp"
#include "patchage_config.h"
#include <memory>
+#include <mutex>
+#include <queue>
#include <set>
#include <string>
@@ -116,6 +119,9 @@ protected:
Gtk::TreeModelColumn<Glib::ustring> label;
};
+ void on_driver_event(const PatchageEvent& event);
+ void process_events();
+
void connect_widgets();
void on_arrange();
@@ -154,6 +160,9 @@ protected:
Glib::RefPtr<Gtk::Builder> _xml;
+ std::mutex _events_mutex;
+ std::queue<PatchageEvent> _driver_events;
+
#ifdef HAVE_ALSA
AlsaDriver* _alsa_driver;
void menu_alsa_connect();