Marble

RoutingRunnerManager.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2008 Henry de Valence <hdevalence@gmail.com>
4// SPDX-FileCopyrightText: 2010 Dennis Nienhüser <nienhueser@kde.org>
5// SPDX-FileCopyrightText: 2010-2013 Bernhard Beschow <bbeschow@cs.tu-berlin.de>
6// SPDX-FileCopyrightText: 2011 Thibaut Gridel <tgridel@free.fr>
7
8#include "RoutingRunnerManager.h"
9
10#include "GeoDataDocument.h"
11#include "MarbleDebug.h"
12#include "MarbleModel.h"
13#include "MarblePlacemarkModel.h"
14#include "Planet.h"
15#include "PluginManager.h"
16#include "RoutingRunnerPlugin.h"
17#include "RunnerTask.h"
18#include "routing/RouteRequest.h"
19#include "routing/RoutingProfilesModel.h"
20
21#include <QThreadPool>
22#include <QTimer>
23
24namespace Marble
25{
26
27class MarbleModel;
28
29class Q_DECL_HIDDEN RoutingRunnerManager::Private
30{
31public:
32 Private(RoutingRunnerManager *parent, const MarbleModel *marbleModel);
33
34 ~Private();
35
36 template<typename T>
37 QList<T *> plugins(const QList<T *> &plugins) const;
38
39 void addRoutingResult(GeoDataDocument *route);
40 void cleanupRoutingTask(RoutingTask *task);
41
42 RoutingRunnerManager *const q;
43 const MarbleModel *const m_marbleModel;
44 const PluginManager *const m_pluginManager;
45 QList<RoutingTask *> m_routingTasks;
46 QList<GeoDataDocument *> m_routingResult;
47};
48
49RoutingRunnerManager::Private::Private(RoutingRunnerManager *parent, const MarbleModel *marbleModel)
50 : q(parent)
51 , m_marbleModel(marbleModel)
52 , m_pluginManager(marbleModel->pluginManager())
53{
54 qRegisterMetaType<GeoDataDocument *>("GeoDataDocument*");
55}
56
57RoutingRunnerManager::Private::~Private()
58{
59 // nothing to do
60}
61
62template<typename T>
63QList<T *> RoutingRunnerManager::Private::plugins(const QList<T *> &plugins) const
64{
65 QList<T *> result;
66 for (T *plugin : plugins) {
67 if ((m_marbleModel && m_marbleModel->workOffline() && !plugin->canWorkOffline())) {
68 continue;
69 }
70
71 if (!plugin->canWork()) {
72 continue;
73 }
74
75 if (m_marbleModel && !plugin->supportsCelestialBody(m_marbleModel->planet()->id())) {
76 continue;
77 }
78
79 result << plugin;
80 }
81
82 return result;
83}
84
85void RoutingRunnerManager::Private::addRoutingResult(GeoDataDocument *route)
86{
87 if (route) {
88 mDebug() << "route retrieved";
89 m_routingResult.push_back(route);
90 qWarning() << route;
91 Q_EMIT q->routeRetrieved(route);
92 }
93}
94
95void RoutingRunnerManager::Private::cleanupRoutingTask(RoutingTask *task)
96{
97 m_routingTasks.removeAll(task);
98 mDebug() << "removing task" << m_routingTasks.size() << " " << (quintptr)task;
99 if (m_routingTasks.isEmpty()) {
100 if (m_routingResult.isEmpty()) {
101 Q_EMIT q->routeRetrieved(nullptr);
102 }
103
104 Q_EMIT q->routingFinished();
105 }
106}
107
108RoutingRunnerManager::RoutingRunnerManager(const MarbleModel *marbleModel, QObject *parent)
109 : QObject(parent)
110 , d(new Private(this, marbleModel))
111{
112 if (QThreadPool::globalInstance()->maxThreadCount() < 4) {
114 }
115}
116
117RoutingRunnerManager::~RoutingRunnerManager()
118{
119 delete d;
120}
121
122void RoutingRunnerManager::retrieveRoute(const RouteRequest *request)
123{
124 RoutingProfile profile = request->routingProfile();
125
126 d->m_routingTasks.clear();
127 d->m_routingResult.clear();
128
129 QList<RoutingRunnerPlugin *> plugins = d->plugins(d->m_pluginManager->routingRunnerPlugins());
130 for (RoutingRunnerPlugin *plugin : std::as_const(plugins)) {
131 if (!profile.name().isEmpty() && !profile.pluginSettings().contains(plugin->nameId())) {
132 continue;
133 }
134
135 auto task = new RoutingTask(plugin->newRunner(), this, request);
136 connect(task, SIGNAL(finished(RoutingTask *)), this, SLOT(cleanupRoutingTask(RoutingTask *)));
137 mDebug() << "route task" << plugin->nameId() << " " << (quintptr)task;
138 d->m_routingTasks << task;
139 }
140
141 for (RoutingTask *task : std::as_const(d->m_routingTasks)) {
143 }
144
145 if (d->m_routingTasks.isEmpty()) {
146 mDebug() << "No suitable routing plugins found, cannot retrieve a route";
147 d->cleanupRoutingTask(nullptr);
148 }
149}
150
151QList<GeoDataDocument *> RoutingRunnerManager::searchRoute(const RouteRequest *request, int timeout)
152{
153 QEventLoop localEventLoop;
154 QTimer watchdog;
155 watchdog.setSingleShot(true);
156 connect(&watchdog, &QTimer::timeout, &localEventLoop, &QEventLoop::quit);
157 connect(this, &RoutingRunnerManager::routingFinished, &localEventLoop, &QEventLoop::quit, Qt::QueuedConnection);
158
159 watchdog.start(timeout);
160 retrieveRoute(request);
161 localEventLoop.exec();
162 return d->m_routingResult;
163}
164
165}
166
167#include "moc_RoutingRunnerManager.cpp"
This file contains the headers for MarbleModel.
Binds a QML item to a specific geodetic location in screen coordinates.
int exec(ProcessEventsFlags flags)
void quit()
qsizetype removeAll(const AT &t)
QueuedConnection
QTaskBuilder< Task > task(Task &&task)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QThreadPool * globalInstance()
void setMaxThreadCount(int maxThreadCount)
void start(Callable &&callableToRun, int priority)
void setSingleShot(bool singleShot)
void start()
void timeout()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 4 2024 16:37:04 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.