PostToObject.h
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * ArmarX is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * ArmarX is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * @package ArmarX::Gui
17 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
18 * GNU General Public License
19 */
20
21#pragma once
22
23#include <type_traits>
24#include <utility>
25
26#include <QCoreApplication>
27#include <QEvent>
28#include <QObject>
29#include <QPointer>
30
31namespace armarx
32{
33 /**
34 * Run @p function on the GUI (main) thread's event loop.
35 *
36 * Drop-in replacement for the Qt >= 5.10 overload
37 * QMetaObject::invokeMethod(context, function, Qt::QueuedConnection)
38 * which does not exist on the Qt 5.9 toolchain (Ubuntu 18.04 / bionic) that ArmarX
39 * still builds against. QCoreApplication::postEvent() is thread-safe, so this may be
40 * called from any thread (Ice dispatch, PeriodicTask worker, ...); it only needs the
41 * main thread to run an event loop.
42 *
43 * @p context is captured in a QPointer: if it has been destroyed by the time the
44 * functor runs, the call is skipped - so a lambda that captures @p context stays safe
45 * even if @p context is torn down while the event is queued. The event is delivered
46 * through the application object (which outlives the widgets), so the functor always
47 * runs on the main thread and never mid-destruction of @p context.
48 */
49 template <typename Function>
50 void
51 postToObject(QObject* context, Function&& function)
52 {
53 struct FunctorEvent : QEvent
54 {
55 QPointer<QObject> context;
56 std::decay_t<Function> function;
57
58 FunctorEvent(QObject* context, Function&& function) :
59 QEvent(QEvent::None),
60 context(context),
61 function(std::forward<Function>(function))
62 {
63 }
64
65 ~FunctorEvent() override
66 {
67 if (context)
68 {
69 function();
70 }
71 }
72 };
73
74 if (QCoreApplication::instance() != nullptr)
75 {
76 QCoreApplication::postEvent(
77 QCoreApplication::instance(),
78 new FunctorEvent(context, std::forward<Function>(function)));
79 }
80 }
81} // namespace armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
void postToObject(QObject *context, Function &&function)
Run function on the GUI (main) thread's event loop.