10 #include <type_traits> 12 #include <QCoreApplication> 15 #include <QMetaObject> 18 #include <QReadLocker> 19 #include <QReadWriteLock> 20 #include <QSharedPointer> 22 #include <QWeakPointer> 23 #include <QWriteLocker> 26 #include <QMutableVectorIterator> 44 friend class ::test_Env;
46 using Identifier =
const char*;
67 virtual ~FuncWrapperBase();
70 template<
typename T,
typename ... Args>
71 class FuncWrapper final
72 :
public FuncWrapperBase
75 const std::function<
T(Args ...)> mFunc;
78 FuncWrapper(std::function<
T(Args ...)> pFunc)
79 : mFunc(
std::move(pFunc))
84 T operator()(Args&& ... pArgs)
87 return mFunc(std::forward<Args>(pArgs) ...);
93 using Wrapper = QSharedPointer<FuncWrapperBase>;
94 QVector<Wrapper> mInstancesCreator;
95 QMap<Identifier, void*> mInstancesSingleton;
96 mutable QReadWriteLock mLock;
99 QMap<Identifier, QWeakPointer<QObject>> mSharedInstances;
100 mutable QReadWriteLock mSharedInstancesLock;
102 static Env& getInstance();
105 inline T* fetchRealSingleton()
107 if constexpr (std::is_abstract<T>::value && std::is_destructible<T>::value)
109 static_assert(std::has_virtual_destructor<T>::value,
"Destructor must be virtual");
110 return singleton<T>();
114 return &T::getInstance();
120 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) 121 inline typename std::enable_if<QtPrivate::IsGadgetHelper<T>::IsRealGadget,
T*>::type checkObjectInfo(Identifier pId,
T* pObject)
const 124 inline typename std::enable_if<QtPrivate::IsGadgetHelper<T>::Value,
T*>::type checkObjectInfo(Identifier pId,
T* pObject)
const 133 inline typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value,
T*>::type checkObjectInfo(Identifier pId,
T* pObject)
const 135 if (!std::is_base_of<ThreadSafe, T>() && pObject->thread() != QThread::currentThread())
137 qWarning() << pId <<
"was created in" << pObject->thread()->objectName() <<
"but is requested by" << QThread::currentThread()->objectName();
139 Q_ASSERT(QCoreApplication::applicationName().startsWith(QLatin1String(
"Test_global_Env")));
148 inline T* fetchSingleton()
150 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) 151 static_assert(QtPrivate::IsGadgetHelper<T>::IsRealGadget || QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value,
152 "Singletons needs to be a Q_GADGET or an QObject/Q_OBJECT");
154 static_assert(QtPrivate::IsGadgetHelper<T>::Value || QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value,
155 "Singletons needs to be a Q_GADGET or an QObject/Q_OBJECT");
158 const Identifier
id = T::staticMetaObject.className();
161 const QReadLocker locker(&mLock);
162 obj = mInstancesSingleton.value(
id);
165 obj = fetchRealSingleton<T>();
167 return checkObjectInfo(
id, static_cast<T*>(obj));
171 template<
typename T,
typename ... Args>
172 inline T newObject(Args&& ... pArgs)
const 174 if constexpr (std::is_constructible<
typename std::remove_pointer<T>::type, Args ...>::value)
176 if constexpr (std::is_pointer<T>::value)
178 using t =
typename std::remove_pointer<T>::type;
179 return new t(std::forward<Args>(pArgs) ...);
183 return T(std::forward<Args>(pArgs) ...);
188 static_assert(std::is_pointer<T>::value,
"It is impossible to return implementation of interface by value. Use pointer or add constructor!");
189 auto obj = createNewObject<T>(std::forward<Args>(pArgs) ...);
196 template<
typename T,
typename ... Args>
197 T createObject(Args&& ... pArgs)
const 201 QReadLocker locker(&mLock);
205 for (
auto mock : qAsConst(mInstancesCreator))
207 auto creator = mock.dynamicCast<FuncWrapper<
T, Args ...>>();
211 return (*creator)(std::forward<Args>(pArgs) ...);
217 return newObject<T>(std::forward<Args>(pArgs) ...);
228 return getInstance().fetchSingleton<
T>();
232 template<
typename T,
typename ... Args>
235 return getInstance().createObject<
T>(std::forward<Args>(pArgs) ...);
242 #if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) 243 static_assert(QtPrivate::IsGadgetHelper<T>::IsRealGadget || QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value,
244 "Shared class needs to be a Q_GADGET or an QObject/Q_OBJECT");
246 static_assert(QtPrivate::IsGadgetHelper<T>::Value || QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value,
247 "Shared class needs to be a Q_GADGET or an QObject/Q_OBJECT");
250 const Identifier className = T::staticMetaObject.className();
252 auto& holder = getInstance();
253 holder.mSharedInstancesLock.lockForRead();
254 QSharedPointer<T> shared = qSharedPointerCast<T>(holder.mSharedInstances.value(className));
255 holder.mSharedInstancesLock.unlock();
259 const QWriteLocker locker(&holder.mSharedInstancesLock);
260 shared = qSharedPointerCast<T>(holder.mSharedInstances.value(className));
263 qDebug() <<
"Spawn shared instance:" << className;
264 shared = QSharedPointer<T>::create();
265 holder.mSharedInstances.insert(className, shared.toWeakRef());
276 static void set(
const QMetaObject& pMetaObject,
void* pObject =
nullptr);
278 template<
typename T,
typename ... Args>
281 auto& holder = getInstance();
282 const QReadLocker locker(&holder.mLock);
284 for (
const auto& mock : qAsConst(holder.mInstancesCreator))
286 if (mock.dynamicCast<FuncWrapper<T, Args ...>>())
288 return mock->getCounter();
296 template<
typename T,
typename ... Args>
301 const auto& value = QSharedPointer<FuncWrapper<
T, Args ...>>
::create(std::move(pFunc));
303 auto& holder = getInstance();
304 const QWriteLocker locker(&holder.mLock);
306 QMutableVectorIterator<Wrapper> iter(holder.mInstancesCreator);
307 while (iter.hasNext())
310 if (iter.value().dynamicCast<FuncWrapper<
T, Args ...>>())
312 iter.setValue(value);
317 holder.mInstancesCreator << value;
321 static void setShared(
const QMetaObject& pMetaObject,
const QSharedPointer<QObject>& pObject);
static T * getSingleton()
Definition: Env.h:226
static void clear()
Definition: Env.cpp:38
static void resetCounter()
Definition: Env.cpp:29
T createNewObject(Args &&... pArgs)
Implementation of ActivationContext for Intent based activation on Android systems.
Definition: ActivationContext.h:14
static T create(Args &&... pArgs)
Definition: Env.h:233
#define T(v)
Definition: http_parser.cpp:237
static void setShared(const QMetaObject &pMetaObject, const QSharedPointer< QObject > &pObject)
Definition: Env.cpp:72
Definition: test_Env.cpp:288
static void setCreator(std::function< T(Args ...)> pFunc)
Definition: Env.h:297
static int getCounter()
Definition: Env.h:279
static QSharedPointer< T > getShared()
Definition: Env.h:240