Marble

RoutingRunnerManager.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2008 Henry de Valence <[email protected]>
4 // SPDX-FileCopyrightText: 2010 Dennis Nienhüser <[email protected]>
5 // SPDX-FileCopyrightText: 2010-2013 Bernhard Beschow <[email protected]>
6 // SPDX-FileCopyrightText: 2011 Thibaut Gridel <[email protected]>
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 
24 namespace Marble
25 {
26 
27 class MarbleModel;
28 
29 class Q_DECL_HIDDEN RoutingRunnerManager::Private
30 {
31 public:
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 
49 RoutingRunnerManager::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 
57 RoutingRunnerManager::Private::~Private()
58 {
59  // nothing to do
60 }
61 
62 template<typename T>
63 QList<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 
86 void 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 
95 void 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 
108 RoutingRunnerManager::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 
117 RoutingRunnerManager::~RoutingRunnerManager()
118 {
119  delete d;
120 }
121 
122 void 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 
151 QVector<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"
void start(QRunnable *runnable, int priority)
void setSingleShot(bool singleShot)
QThreadPool * globalInstance()
int exec(QEventLoop::ProcessEventsFlags flags)
void start(int msec)
QAction * quit(const QObject *recvr, const char *slot, QObject *parent)
QueuedConnection
Binds a QML item to a specific geodetic location in screen coordinates.
void setMaxThreadCount(int maxThreadCount)
QDebug mDebug()
a function to replace qDebug() in Marble library code
Definition: MarbleDebug.cpp:31
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Wed Oct 4 2023 04:09:43 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.