File indexing completed on 2024-05-12 15:57:03
0001 /* 0002 * SPDX-FileCopyrightText: 2021 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "KisSynchronizedConnection.h" 0008 0009 #include <QThread> 0010 #include <QCoreApplication> 0011 #include <kis_assert.h> 0012 0013 /** 0014 * @brief The KisSynchronizedConnectionEventTypeRegistrar is a simple 0015 * class to register QEvent type in the Qt's system 0016 */ 0017 struct KisSynchronizedConnectionEventTypeRegistrar 0018 { 0019 KisSynchronizedConnectionEventTypeRegistrar() { 0020 eventType = QEvent::registerEventType(QEvent::User + 1000); 0021 } 0022 0023 int eventType = -1; 0024 }; 0025 0026 struct KisBarrierCallbackContainer 0027 { 0028 std::function<void()> callback; 0029 }; 0030 0031 Q_GLOBAL_STATIC(KisSynchronizedConnectionEventTypeRegistrar, s_instance) 0032 Q_GLOBAL_STATIC(KisBarrierCallbackContainer, s_barrier) 0033 0034 0035 /************************************************************************/ 0036 /* KisSynchronizedConnectionEvent */ 0037 /************************************************************************/ 0038 0039 KisSynchronizedConnectionEvent::KisSynchronizedConnectionEvent(QObject *_destination) 0040 : QEvent(QEvent::Type(s_instance->eventType)), 0041 destination(_destination) 0042 { 0043 } 0044 0045 KisSynchronizedConnectionEvent::KisSynchronizedConnectionEvent(const KisSynchronizedConnectionEvent &rhs) 0046 : QEvent(QEvent::Type(s_instance->eventType)), 0047 destination(rhs.destination) 0048 { 0049 } 0050 0051 KisSynchronizedConnectionEvent::~KisSynchronizedConnectionEvent() 0052 { 0053 } 0054 0055 /************************************************************************/ 0056 /* KisSynchronizedConnectionBase */ 0057 /************************************************************************/ 0058 0059 int KisSynchronizedConnectionBase::eventType() 0060 { 0061 return s_instance->eventType; 0062 } 0063 0064 void KisSynchronizedConnectionBase::registerSynchronizedEventBarrier(std::function<void ()> callback) 0065 { 0066 KIS_SAFE_ASSERT_RECOVER_NOOP(!s_barrier->callback); 0067 s_barrier->callback = callback; 0068 } 0069 0070 bool KisSynchronizedConnectionBase::event(QEvent *event) 0071 { 0072 if (event->type() == s_instance->eventType) { 0073 KisSynchronizedConnectionEvent *typedEvent = 0074 static_cast<KisSynchronizedConnectionEvent*>(event); 0075 0076 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(typedEvent->destination == this, false); 0077 deliverEventToReceiver(); 0078 return true; 0079 } 0080 0081 return QObject::event(event); 0082 } 0083 0084 void KisSynchronizedConnectionBase::postEvent() 0085 { 0086 if (QThread::currentThread() == this->thread()) { 0087 /// TODO: This assert triggers in unittests that don't have a fully-featured 0088 /// KisApplication object. Perhaps we should add a fake callback to KISTEST_MAIN 0089 /// KIS_SAFE_ASSERT_RECOVER_NOOP(s_barrier->callback); 0090 0091 if (s_barrier->callback) { 0092 s_barrier->callback(); 0093 } 0094 0095 deliverEventToReceiver(); 0096 } else { 0097 qApp->postEvent(this, new KisSynchronizedConnectionEvent(this)); 0098 } 0099 } 0100