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 "MarblePlacemarkModel.h"
11#include "MarbleDebug.h"
12#include "MarbleModel.h"
13#include "Planet.h"
14#include "GeoDataDocument.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 QVector<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 {
77 continue;
78 }
79
80 result << plugin;
81 }
82
83 return result;
84}
85
86void RoutingRunnerManager::Private::addRoutingResult( GeoDataDocument *route )
87{
88 if ( route ) {
89 mDebug() << "route retrieved";
90 m_routingResult.push_back( route );
91 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 emit q->routeRetrieved( nullptr );
102 }
103
104 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: plugins ) {
131 if ( !profile.name().isEmpty() && !profile.pluginSettings().contains( plugin->nameId() ) ) {
132 continue;
133 }
134
135 RoutingTask* 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: 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
151QVector<GeoDataDocument*> RoutingRunnerManager::searchRoute( const RouteRequest *request, int timeout ) {
152 QEventLoop localEventLoop;
153 QTimer watchdog;
154 watchdog.setSingleShot(true);
155 connect( &watchdog, SIGNAL(timeout()),
156 &localEventLoop, SLOT(quit()));
157 connect(this, SIGNAL(routingFinished()),
158 &localEventLoop, SLOT(quit()), Qt::QueuedConnection );
159
160 watchdog.start( timeout );
161 retrieveRoute( request );
162 localEventLoop.exec();
163 return d->m_routingResult;
164}
165
166}
167
168#include "moc_RoutingRunnerManager.cpp"
This file contains the headers for MarbleModel.
const QList< QKeySequence > & quit()
Binds a QML item to a specific geodetic location in screen coordinates.
int exec(ProcessEventsFlags flags)
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()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:17 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.