libquentier  0.8.0
The library for rich desktop clients of Evernote service
Post.h
1 /*
2  * Copyright 2021-2024 Dmitry Ivanov
3  *
4  * This file is part of libquentier
5  *
6  * libquentier is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, version 3 of the License.
9  *
10  * libquentier is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libquentier. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #pragma once
20 
21 #include <QAbstractEventDispatcher>
22 #include <QMetaObject>
23 #include <QObject>
24 
25 #include <QThread>
26 
27 #include <memory>
28 #include <utility>
29 
30 namespace quentier::threading {
31 
32 template <typename Function>
33 void postToObject(QObject * object, Function && function)
34 {
35  Q_ASSERT(object);
36 
37  QMetaObject::invokeMethod(
38  object, std::forward<Function>(function), Qt::QueuedConnection);
39 }
40 
41 template <typename Function>
42 void postToThread(QThread * pThread, Function && function)
43 {
44  Q_ASSERT(pThread);
45  Q_ASSERT(!pThread->isFinished());
46 
47  QObject * pObject = QAbstractEventDispatcher::instance(pThread);
48  if (!pObject) {
49  // Thread's event loop has not been started yet. Create a dummy QObject,
50  // move it to the target thread, set things up so that it would be
51  // destroyed after the job is done and use postToObject.
52  auto pDummyObj = std::make_unique<QObject>();
53  pDummyObj->moveToThread(pThread);
54  postToObject(
55  pDummyObj.get(),
56  [pObj = pDummyObj.get(),
57  function = std::forward<Function>(function)]() mutable {
58  pObj->deleteLater();
59  function();
60  });
61  Q_UNUSED(pDummyObj.release()) // NOLINT
62  return;
63  }
64 
65  if (pThread == QThread::currentThread()) {
66  // Already on the target thread, executing the function right away
67  function();
68  return;
69  }
70 
71  QMetaObject::invokeMethod(pObject, std::forward<Function>(function));
72 }
73 
74 } // namespace quentier::threading
Definition: threading/Factory.h:24