summaryrefslogtreecommitdiffstats
path: root/src
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 /src
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.
Diffstat (limited to 'src')
-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();