|
Krita Source Code Documentation
|
#include <KisSynchronizedConnection.h>
Inheritance diagram for KisSynchronizedConnection< Args >:Public Types | |
| using | ArgsTuple = std::tuple<Args...> |
| using | CallbackFunction = std::function<void (Args...)> |
Public Member Functions | |
| template<typename Dptr , typename C , typename R , typename ... MemFnArgs> | |
| void | connectInputSignal (Dptr object, R(C::*memfn)(MemFnArgs...)) |
| template<typename Dptr , typename C , typename R , typename ... MemFnArgs> | |
| void | connectOutputSlot (Dptr object, R(C::*memfn)(MemFnArgs...)) |
| template<typename Dptr1 , typename C1 , typename R1 , typename ... MemFnArgs1, typename Dptr2 , typename C2 , typename R2 , typename ... MemFnArgs2> | |
| void | connectSync (Dptr1 object1, R1(C1::*memfn1)(MemFnArgs1...), Dptr2 object2, R2(C2::*memfn2)(MemFnArgs2...)) |
| bool | hasPendingSignals () const |
| KisSynchronizedConnection ()=default | |
| KisSynchronizedConnection (CallbackFunction callback) | |
| void | setCallback (CallbackFunction callback) |
| void | start (const Args &...argsTuple) |
Protected Member Functions | |
| void | deliverEventToReceiver () override |
Protected Member Functions inherited from KisSynchronizedConnectionBase | |
| bool | event (QEvent *event) override |
| void | postEvent () |
Private Member Functions | |
| template<typename Dptr , typename C , typename R , typename ... MemFnArgs, std::size_t ... Idx> | |
| CallbackFunction | bindToMemberFunction (Dptr object, R(C::*memfn)(MemFnArgs...), std::index_sequence< Idx... >) |
Private Attributes | |
| CallbackFunction | m_callback |
| QMutex | m_inputConnectionMutex |
| std::queue< ArgsTuple > | m_queue |
Additional Inherited Members | |
Static Public Member Functions inherited from KisSynchronizedConnectionBase | |
| static int | eventType () |
| static void | forceDeliverAllSynchronizedEvents () |
| static bool | isAutoModeForUnittestsEnabled () |
| static void | registerSynchronizedEventBarrier (std::function< void()> callback) |
| static void | setAutoModeForUnittestsEnabled (bool value) |
A "simple" class for ensuring a queued connection is never executed in a recursive event processing loop.
In several places in Krita we use queued signals for synchronizing image changes to the GUI. In such cases we use Qt::DirectConnection to fetch some data from the image, wrap that into the signal parameters and post at the events queue as a queued signal. Obviously, we expect this queued signal to be executed "after all the currently processed GUI actions are finished". But that is not always true in Qt...
In Qt the queued signal will be executed "as soon as execution path returns to the event loop". And it can also happen when a nested event loop started (by opening a QDialog) or QApplication::processEvent() is called. It means that the processing of a queued signal can start before the currently running GUI action is finished (because the current task has been recursively overridden by KisBusyWaitBroker.
KisSynchronizedConnection is workaround to this problem. Every connection made via KisSynchronizedConnection ensures that the target slot is executed without any recursion. The class tried to resemble new member-function-pointer-based API of QObject::connect.
In case the signal is emitted from the GUI thread, KisSynchronizedConnection behaves as Qt::AutoConnection, that is, delivers event right away, skipping the event loop.
Under the hood the class uses a custom event (KisSynchronizedConnectionEvent), which is recognized by KisApplication and postponed until the recursion state is over.
| Args... | the list of arguments that are passed through the signal |
Usage:
\code{.cpp}
class KisImage
{
// ...
Q_SIGNALS:
void sigRequestNodeReselection(KisNodeSP activeNode, const KisNodeList &selectedNodes);
};
KisSynchronizedConnection<KisNodeSP, KisNodeList> connection;
// if you want connect input and output separately
connection.connectInputSignal(image, &KisImage::sigRequestNodeReselection);
connection.connectOutputSlot(nodeManager, &KisNodeManager::slotImageRequestNodeReselection)
// if you want to connect them in one call (in QObject style)
connection.connectSync(image, &KisImage::sigRequestNodeReselection,
nodeManager, &KisNodeManager::slotImageRequestNodeReselection);
\endcode
Definition at line 131 of file KisSynchronizedConnection.h.
| using KisSynchronizedConnection< Args >::ArgsTuple = std::tuple<Args...> |
Definition at line 135 of file KisSynchronizedConnection.h.
| using KisSynchronizedConnection< Args >::CallbackFunction = std::function<void (Args...)> |
Definition at line 136 of file KisSynchronizedConnection.h.
|
default |
|
inline |
Definition at line 140 of file KisSynchronizedConnection.h.
|
inlineprivate |
we cannot use std::bind here, because it doesn't support indexed iteration over the argument placeholders
Definition at line 216 of file KisSynchronizedConnection.h.
|
inline |
Connect input signal to the connection
This part of the connection is based on Qt-signal mechanism, therefore object should be convertible into const QObject*.
Definition at line 170 of file KisSynchronizedConnection.h.
References C, and KisSynchronizedConnection< Args >::start().
|
inline |
Connect output slot to the connection
Since destination slot doesn't use Qt-signal machinery, the destination object shouldn't necessarily be a QObject. It should just be a member function with a compatible signature.
Definition at line 186 of file KisSynchronizedConnection.h.
References KisSynchronizedConnection< Args >::bindToMemberFunction(), KIS_SAFE_ASSERT_RECOVER_RETURN, and KisSynchronizedConnection< Args >::m_callback.
|
inline |
A convenience method for setting up input and output connections at the same time
Definition at line 201 of file KisSynchronizedConnection.h.
References KisSynchronizedConnection< Args >::connectInputSignal(), and KisSynchronizedConnection< Args >::connectOutputSlot().
|
inlineoverrideprotectedvirtual |
Implements KisSynchronizedConnectionBase.
Definition at line 225 of file KisSynchronizedConnection.h.
References KisSynchronizedConnection< Args >::m_callback, KisSynchronizedConnection< Args >::m_inputConnectionMutex, and KisSynchronizedConnection< Args >::m_queue.
|
inline |
Definition at line 208 of file KisSynchronizedConnection.h.
References KisSynchronizedConnection< Args >::m_inputConnectionMutex, and KisSynchronizedConnection< Args >::m_queue.
|
inline |
Sets an arbitrary callback as a destination slot in the connection. The callback should have a signature void (Args...)
Definition at line 159 of file KisSynchronizedConnection.h.
References KisSynchronizedConnection< Args >::m_callback.
|
inline |
Triggers the delivery of the signal to the destination slot manually
Definition at line 147 of file KisSynchronizedConnection.h.
References KisSynchronizedConnection< Args >::m_inputConnectionMutex, KisSynchronizedConnection< Args >::m_queue, and KisSynchronizedConnectionBase::postEvent().
|
private |
Definition at line 238 of file KisSynchronizedConnection.h.
|
mutableprivate |
Definition at line 240 of file KisSynchronizedConnection.h.
|
private |
Definition at line 239 of file KisSynchronizedConnection.h.