summaryrefslogtreecommitdiffstats
path: root/src/control/controlproxy.h
diff options
context:
space:
mode:
authorBe <be@mixxx.org>2019-01-05 16:06:29 -0600
committerBe <be@mixxx.org>2019-01-06 00:24:59 -0600
commit2ab7121f08fe12b628848720bb432af43aca0175 (patch)
treeafc0d8c9a6cdfd5a352241229a94e38fe82cbe50 /src/control/controlproxy.h
parentf161b34ae71be5c24496c193bcbd8d296c60997e (diff)
remove need for lambdas with connectValueChange(Request)
and remove old SLOT syntax for ControlProxy::connectValueChangeRequest. That was easier than getting it to play nice with the templating required for the new functor syntax.
Diffstat (limited to 'src/control/controlproxy.h')
-rw-r--r--src/control/controlproxy.h77
1 files changed, 66 insertions, 11 deletions
diff --git a/src/control/controlproxy.h b/src/control/controlproxy.h
index a619cd0af6..4c72cce95a 100644
--- a/src/control/controlproxy.h
+++ b/src/control/controlproxy.h
@@ -30,17 +30,72 @@ class ControlProxy : public QObject {
return m_key;
}
- bool connectValueChanged(const QObject* receiver,
- std::function<void(double)> method, Qt::ConnectionType type = Qt::AutoConnection);
- // for legacy SLOT syntax from Qt < 5. TODO: replace all uses with Qt 5 functor syntax
- bool connectValueChanged(const QObject* receiver,
- const char* method, Qt::ConnectionType type = Qt::AutoConnection);
-
- bool connectValueChanged(
- std::function<void(double)> method, Qt::ConnectionType type = Qt::AutoConnection);
- // for legacy SLOT syntax from Qt < 5. TODO: replace all uses with Qt 5 functor syntax
- bool connectValueChanged(
- const char* method, Qt::ConnectionType type = Qt::AutoConnection);
+ template <typename Receiver, typename Slot>
+ bool connectValueChanged(Receiver receiver,
+ Slot func, Qt::ConnectionType requestedConnectionType = Qt::AutoConnection) {
+ if (!m_pControl) {
+ return false;
+ }
+
+ // We connect to the
+ // ControlObjectPrivate only once and in a way that
+ // the requested ConnectionType is working as desired.
+ // We try to avoid direct connections if not requested
+ // since you cannot safely delete an object with a pending
+ // direct connection. This fixes bug Bug #1406124
+ // requested: Auto -> COP = Auto / SCO = Auto
+ // requested: Direct -> COP = Direct / SCO = Direct
+ // requested: Queued -> COP = Queued / SCO = Auto
+ // requested: BlockingQueued -> Assert(false)
+
+ auto copSlot = &ControlProxy::slotValueChangedAuto;
+ Qt::ConnectionType copConnection;
+ Qt::ConnectionType scoConnection;
+ switch(requestedConnectionType) {
+ case Qt::AutoConnection:
+ copConnection = Qt::AutoConnection;
+ scoConnection = Qt::AutoConnection;
+ break;
+ case Qt::DirectConnection:
+ copSlot = &ControlProxy::slotValueChangedDirect;
+ copConnection = Qt::DirectConnection;
+ scoConnection = Qt::DirectConnection;
+ break;
+ case Qt::QueuedConnection:
+ copSlot = &ControlProxy::slotValueChangedQueued;
+ copConnection = Qt::QueuedConnection;
+ scoConnection = Qt::AutoConnection;
+ break;
+ case Qt::BlockingQueuedConnection:
+ // We must not block the signal source by a blocking connection
+ DEBUG_ASSERT(false);
+ return false;
+ default:
+ DEBUG_ASSERT(false);
+ return false;
+ }
+
+ if (!connect(this, &ControlProxy::valueChanged, receiver, func, scoConnection)) {
+ return false;
+ }
+
+ // Connect to ControlObjectPrivate only if required. Do not allow
+ // duplicate connections.
+
+ // use only explicit direct connection if requested
+ // the caller must not delete this until the all signals are
+ // processed to avoid segfaults
+ connect(m_pControl.data(), &ControlDoublePrivate::valueChanged,
+ this, copSlot,
+ static_cast<Qt::ConnectionType>(copConnection | Qt::UniqueConnection));
+ return true;
+ }
+ // TODO: get the compiler to accept parent() for the receiver
+ //template <typename Slot>
+ //bool connectValueChanged(Slot func, Qt::ConnectionType type = Qt::AutoConnection) {
+ // DEBUG_ASSERT(parent() != nullptr);
+ // return connectValueChanged(parent(), func, type);
+ //}
// Called from update();
virtual void emitValueChanged() {