File indexing completed on 2024-05-19 04:25:10

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     bool enableAutoModeForUnittests = false;
0025 };
0026 
0027 struct KisBarrierCallbackContainer
0028 {
0029     std::function<void()> callback;
0030 };
0031 
0032 Q_GLOBAL_STATIC(KisSynchronizedConnectionEventTypeRegistrar, s_instance)
0033 Q_GLOBAL_STATIC(KisBarrierCallbackContainer, s_barrier)
0034 
0035 
0036 /************************************************************************/
0037 /*            KisSynchronizedConnectionEvent                            */
0038 /************************************************************************/
0039 
0040 KisSynchronizedConnectionEvent::KisSynchronizedConnectionEvent(QObject *_destination)
0041     : QEvent(QEvent::Type(s_instance->eventType)),
0042       destination(_destination)
0043 {
0044 }
0045 
0046 KisSynchronizedConnectionEvent::KisSynchronizedConnectionEvent(const KisSynchronizedConnectionEvent &rhs)
0047     : QEvent(QEvent::Type(s_instance->eventType)),
0048       destination(rhs.destination)
0049 {
0050 }
0051 
0052 KisSynchronizedConnectionEvent::~KisSynchronizedConnectionEvent()
0053 {
0054 }
0055 
0056 /************************************************************************/
0057 /*            KisSynchronizedConnectionBase                             */
0058 /************************************************************************/
0059 
0060 int KisSynchronizedConnectionBase::eventType()
0061 {
0062     return s_instance->eventType;
0063 }
0064 
0065 void KisSynchronizedConnectionBase::registerSynchronizedEventBarrier(std::function<void ()> callback)
0066 {
0067     KIS_SAFE_ASSERT_RECOVER_NOOP(!s_barrier->callback);
0068     s_barrier->callback = callback;
0069 }
0070 
0071 void KisSynchronizedConnectionBase::setAutoModeForUnittestsEnabled(bool value)
0072 {
0073     s_instance->enableAutoModeForUnittests = value;
0074 }
0075 
0076 bool KisSynchronizedConnectionBase::isAutoModeForUnittestsEnabled()
0077 {
0078     return s_instance->enableAutoModeForUnittests;
0079 }
0080 
0081 bool KisSynchronizedConnectionBase::event(QEvent *event)
0082 {
0083     if (event->type() == s_instance->eventType) {
0084         KisSynchronizedConnectionEvent *typedEvent =
0085                 static_cast<KisSynchronizedConnectionEvent*>(event);
0086 
0087         KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(typedEvent->destination == this, false);
0088         deliverEventToReceiver();
0089         return true;
0090     }
0091 
0092     return QObject::event(event);
0093 }
0094 
0095 void KisSynchronizedConnectionBase::postEvent()
0096 {
0097     if (s_instance->enableAutoModeForUnittests && QThread::currentThread() == this->thread()) {
0098         /// TODO: check if we need s_barrier at all now!
0099 
0100         /// TODO: This assert triggers in unittests that don't have a fully-featured
0101         /// KisApplication object. Perhaps we should add a fake callback to KISTEST_MAIN
0102         /// KIS_SAFE_ASSERT_RECOVER_NOOP(s_barrier->callback);
0103 
0104         if (s_barrier->callback) {
0105             s_barrier->callback();
0106         }
0107 
0108         deliverEventToReceiver();
0109     } else {
0110         qApp->postEvent(this, new KisSynchronizedConnectionEvent(this));
0111     }
0112 }
0113