Krita Source Code Documentation
Loading...
Searching...
No Matches
KisSynchronizedConnection.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2021 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#ifndef KISSYNCHRONIZEDCONNECTION_H
8#define KISSYNCHRONIZEDCONNECTION_H
9
10#include <kritaglobal_export.h>
11
12#include <QObject>
13#include <QEvent>
14
15#include <KisMpl.h>
16#include <QMutex>
17#include <QMutexLocker>
18#include <QPointer>
19#include <boost/bind/bind.hpp>
20#include <functional>
21#include <kis_assert.h>
22#include <queue>
23
30struct KRITAGLOBAL_EXPORT KisSynchronizedConnectionEvent : public QEvent
31{
32 KisSynchronizedConnectionEvent(QObject *_destination);
35
37};
38
48class KRITAGLOBAL_EXPORT KisSynchronizedConnectionBase : public QObject
49{
50public:
51 static int eventType();
52 static void registerSynchronizedEventBarrier(std::function<void()> callback);
53
61 static void setAutoModeForUnittestsEnabled(bool value);
62 static bool isAutoModeForUnittestsEnabled();
63
64 static void forceDeliverAllSynchronizedEvents();
65
66protected:
67 bool event(QEvent *event) override;
68
69protected:
70 virtual void deliverEventToReceiver() = 0;
71 void postEvent();
72};
73
130template <typename... Args>
132{
133public:
134public:
135 using ArgsTuple = std::tuple<Args...>;
136 using CallbackFunction = std::function<void (Args...)>;
137
138public:
141 : m_callback(callback)
142 {}
143
147 void start(const Args &...argsTuple) {
148 {
149 QMutexLocker l(&m_inputConnectionMutex);
150 m_queue.emplace(std::make_tuple(argsTuple...));
151 }
152 this->postEvent();
153 }
154
160 m_callback = callback;
161 }
162
169 template <typename Dptr, typename C, typename R, typename ...MemFnArgs>
170 void connectInputSignal(Dptr object, R (C::* memfn)(MemFnArgs...)) {
171 static_assert (std::is_convertible<Dptr, const C*>::value, "Source object should be convertible into the base of the member pointer");
172 static_assert (std::is_convertible<Dptr, const QObject*>::value, "Source object should be convertible into QObject");
173
174 QObject::connect(static_cast<const C*>(object), memfn,
175 this, &KisSynchronizedConnection::start, Qt::DirectConnection);
176 }
177
185 template <typename Dptr, typename C, typename R, typename ...MemFnArgs>
186 void connectOutputSlot(Dptr object, R (C::* memfn)(MemFnArgs...)) {
187 static_assert (std::is_convertible<Dptr, C*>::value, "Destination object should be convertible into the base of the member pointer");
189
190 m_callback = bindToMemberFunction(object, memfn,
192 std::tuple_size<ArgsTuple>::value>());
193 }
194
199 template <typename Dptr1, typename C1, typename R1, typename ...MemFnArgs1,
200 typename Dptr2, typename C2, typename R2, typename ...MemFnArgs2>
201 void connectSync(Dptr1 object1, R1 (C1::* memfn1)(MemFnArgs1...),
202 Dptr2 object2, R2 (C2::* memfn2)(MemFnArgs2...)) {
203
204 connectInputSignal(object1, memfn1);
205 connectOutputSlot(object2, memfn2);
206 }
207
208 bool hasPendingSignals() const {
209 QMutexLocker l(&m_inputConnectionMutex);
210 return !m_queue.empty();
211 }
212
213private:
214
215 template <typename Dptr, typename C, typename R, typename ...MemFnArgs, std::size_t ...Idx>
216 CallbackFunction bindToMemberFunction(Dptr object, R (C::* memfn)(MemFnArgs...), std::index_sequence<Idx...>) {
217
220
221 return boost::bind(memfn, object, boost::arg<Idx>()...);
222 }
223
224protected:
225 void deliverEventToReceiver() override {
226 ArgsTuple args;
227
228 {
229 QMutexLocker l(&m_inputConnectionMutex);
230 args = m_queue.front();
231 m_queue.pop();
232 }
233
234 std::apply(m_callback, args);
235 }
236
237private:
239 std::queue<ArgsTuple> m_queue;
241};
242
243#endif // KISSYNCHRONIZEDCONNECTION_H
float value(const T *src, size_t ch)
Eigen::Matrix< double, 4, 2 > R
#define C(i, j)
A base class for KisSynchronizedConnection.
virtual void deliverEventToReceiver()=0
void start(const Args &...argsTuple)
KisSynchronizedConnection()=default
KisSynchronizedConnection(CallbackFunction callback)
void setCallback(CallbackFunction callback)
void connectSync(Dptr1 object1, R1(C1::*memfn1)(MemFnArgs1...), Dptr2 object2, R2(C2::*memfn2)(MemFnArgs2...))
void connectInputSignal(Dptr object, R(C::*memfn)(MemFnArgs...))
std::function< void(Args...)> CallbackFunction
void connectOutputSlot(Dptr object, R(C::*memfn)(MemFnArgs...))
CallbackFunction bindToMemberFunction(Dptr object, R(C::*memfn)(MemFnArgs...), std::index_sequence< Idx... >)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
typedef void(QOPENGLF_APIENTRYP PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer)
typename detail::make_index_sequence_from_1_impl< Num >::type make_index_sequence_from_1
Definition KisMpl.h:44
Event type used for synchronizing connection in KisSynchronizedConnection.