diff options
author | Be <be@mixxx.org> | 2019-01-05 16:06:29 -0600 |
---|---|---|
committer | Be <be@mixxx.org> | 2019-01-06 00:24:59 -0600 |
commit | 2ab7121f08fe12b628848720bb432af43aca0175 (patch) | |
tree | afc0d8c9a6cdfd5a352241229a94e38fe82cbe50 /src/control/controlproxy.h | |
parent | f161b34ae71be5c24496c193bcbd8d296c60997e (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.h | 77 |
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() { |