diff options
author | Michal Klocek <michal.klocek@theqtcompany.com> | 2015-04-28 14:00:39 +0200 |
---|---|---|
committer | Michal Klocek <michal.klocek@theqtcompany.com> | 2015-05-21 08:13:17 +0000 |
commit | 3c674e0ec3fcbb1acebd27580ef005d7f6726719 (patch) | |
tree | 970902e2baa57b31bd2851ec1b987e4f70eeb4b1 /src/location/maps/qgeotilerequestmanager.cpp | |
parent | 52b887a8004029cf18942b5d16b1dcf396feabc0 (diff) | |
download | qtlocation-3c674e0ec3fcbb1acebd27580ef005d7f6726719.tar.gz |
Fix missing guarded pointers for mapping engine
Since mapping engine is going to be destroyed
on geoseriveprovider change/plugin unload use
QPointer to track engine existence before
making calls.
This commit refactors a bit QGeoTileRequestManager
to handle all the calls to the enigne. Check for
null pointer before calling the engine. Move
registerMap method to base class.
Update QGeoTiledMapNokia class accordingly.
Change-Id: I886e85e660b2c515e4a617e98e9cc0c3c13781b6
Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
Diffstat (limited to 'src/location/maps/qgeotilerequestmanager.cpp')
-rw-r--r-- | src/location/maps/qgeotilerequestmanager.cpp | 113 |
1 files changed, 58 insertions, 55 deletions
diff --git a/src/location/maps/qgeotilerequestmanager.cpp b/src/location/maps/qgeotilerequestmanager.cpp index bfe6f43a..d689d618 100644 --- a/src/location/maps/qgeotilerequestmanager.cpp +++ b/src/location/maps/qgeotilerequestmanager.cpp @@ -34,13 +34,11 @@ ** ****************************************************************************/ #include "qgeotilerequestmanager_p.h" - -#include <QSharedPointer> -#include <QDebug> #include "qgeotilespec_p.h" #include "qgeotiledmap_p.h" #include "qgeotiledmappingmanagerengine_p.h" #include "qgeotilecache_p.h" +#include <QtCore/QPointer> QT_BEGIN_NAMESPACE @@ -49,51 +47,61 @@ class RetryFuture; class QGeoTileRequestManagerPrivate { public: - explicit QGeoTileRequestManagerPrivate(QGeoTiledMap *map); + explicit QGeoTileRequestManagerPrivate(QGeoTiledMap *map, QGeoTiledMappingManagerEngine *engine); ~QGeoTileRequestManagerPrivate(); - QGeoTiledMap *map_; + QGeoTiledMap *m_map; + QPointer<QGeoTiledMappingManagerEngine> m_engine; QList<QSharedPointer<QGeoTileTexture> > requestTiles(const QSet<QGeoTileSpec> &tiles); void tileError(const QGeoTileSpec &tile, const QString &errorString); - QHash<QGeoTileSpec, int> retries_; - QHash<QGeoTileSpec, QSharedPointer<RetryFuture> > futures_; - QSet<QGeoTileSpec> requested_; + QHash<QGeoTileSpec, int> m_retries; + QHash<QGeoTileSpec, QSharedPointer<RetryFuture> > m_futures; + QSet<QGeoTileSpec> m_requested; void tileFetched(const QGeoTileSpec &spec); }; -QGeoTileRequestManager::QGeoTileRequestManager(QGeoTiledMap *map) - : d_ptr(new QGeoTileRequestManagerPrivate(map)) +QGeoTileRequestManager::QGeoTileRequestManager(QGeoTiledMap *map, QGeoTiledMappingManagerEngine *engine) + : d_ptr(new QGeoTileRequestManagerPrivate(map, engine)) { + if (!d_ptr->m_engine.isNull()) + d_ptr->m_engine->registerMap(d_ptr->m_map); } QGeoTileRequestManager::~QGeoTileRequestManager() { - delete d_ptr; + if (!d_ptr->m_engine.isNull()) + d_ptr->m_engine->deregisterMap(d_ptr->m_map); } QList<QSharedPointer<QGeoTileTexture> > QGeoTileRequestManager::requestTiles(const QSet<QGeoTileSpec> &tiles) { - Q_D(QGeoTileRequestManager); - return d->requestTiles(tiles); + return d_ptr->requestTiles(tiles); } void QGeoTileRequestManager::tileFetched(const QGeoTileSpec &spec) { - Q_D(QGeoTileRequestManager); - d->tileFetched(spec); + d_ptr->tileFetched(spec); +} + +QSharedPointer<QGeoTileTexture> QGeoTileRequestManager::tileTexture(const QGeoTileSpec &spec) +{ + if (d_ptr->m_engine) + return d_ptr->m_engine->getTileTexture(spec); + else + return QSharedPointer<QGeoTileTexture>(); } void QGeoTileRequestManager::tileError(const QGeoTileSpec &tile, const QString &errorString) { - Q_D(QGeoTileRequestManager); - d->tileError(tile, errorString); + d_ptr->tileError(tile, errorString); } -QGeoTileRequestManagerPrivate::QGeoTileRequestManagerPrivate(QGeoTiledMap *map) - : map_(map) +QGeoTileRequestManagerPrivate::QGeoTileRequestManagerPrivate(QGeoTiledMap *map,QGeoTiledMappingManagerEngine *engine) + : m_map(map), + m_engine(engine) { } @@ -103,8 +111,8 @@ QGeoTileRequestManagerPrivate::~QGeoTileRequestManagerPrivate() QList<QSharedPointer<QGeoTileTexture> > QGeoTileRequestManagerPrivate::requestTiles(const QSet<QGeoTileSpec> &tiles) { - QSet<QGeoTileSpec> cancelTiles = requested_ - tiles; - QSet<QGeoTileSpec> requestTiles = tiles - requested_; + QSet<QGeoTileSpec> cancelTiles = m_requested - tiles; + QSet<QGeoTileSpec> requestTiles = tiles - m_requested; QSet<QGeoTileSpec> cached; // int tileSize = tiles.size(); // int newTiles = requestTiles.size(); @@ -113,16 +121,13 @@ QList<QSharedPointer<QGeoTileTexture> > QGeoTileRequestManagerPrivate::requestTi QList<QSharedPointer<QGeoTileTexture> > cachedTex; - QGeoTiledMappingManagerEngine *engine = map_ ? - static_cast<QGeoTiledMappingManagerEngine *>(map_->engine()) : 0; - // remove tiles in cache from request tiles - if (engine) { + if (!m_engine.isNull()) { iter i = requestTiles.constBegin(); iter end = requestTiles.constEnd(); for (; i != end; ++i) { QGeoTileSpec tile = *i; - QSharedPointer<QGeoTileTexture> tex = engine->getTileTexture(tile); + QSharedPointer<QGeoTileTexture> tex = m_engine->getTileTexture(tile); if (tex) { cachedTex << tex; cached.insert(tile); @@ -132,23 +137,23 @@ QList<QSharedPointer<QGeoTileTexture> > QGeoTileRequestManagerPrivate::requestTi requestTiles -= cached; - requested_ -= cancelTiles; - requested_ += requestTiles; + m_requested -= cancelTiles; + m_requested += requestTiles; // qDebug() << "required # tiles: " << tileSize << ", new tiles: " << newTiles << ", total server requests: " << requested_.size(); if (!requestTiles.isEmpty() || !cancelTiles.isEmpty()) { - if (engine) { + if (!m_engine.isNull()) { // qDebug() << "new server requests: " << requestTiles.size() << ", server cancels: " << cancelTiles.size(); - engine->updateTileRequests(map_, requestTiles, cancelTiles); + m_engine->updateTileRequests(m_map, requestTiles, cancelTiles); // Remove any cancelled tiles from the error retry hash to avoid // re-using the numbers for a totally different request cycle. iter i = cancelTiles.constBegin(); iter end = cancelTiles.constEnd(); for (; i != end; ++i) { - retries_.remove(*i); - futures_.remove(*i); + m_retries.remove(*i); + m_futures.remove(*i); } } } @@ -158,10 +163,10 @@ QList<QSharedPointer<QGeoTileTexture> > QGeoTileRequestManagerPrivate::requestTi void QGeoTileRequestManagerPrivate::tileFetched(const QGeoTileSpec &spec) { - map_->newTileFetched(spec); - requested_.remove(spec); - retries_.remove(spec); - futures_.remove(spec); + m_map->updateTile(spec); + m_requested.remove(spec); + m_retries.remove(spec); + m_futures.remove(spec); } // Represents a tile that needs to be retried after a certain period of time @@ -169,52 +174,50 @@ class RetryFuture : public QObject { Q_OBJECT public: - RetryFuture(const QGeoTileSpec &tile, QGeoTiledMap *map, QObject *parent = 0); + RetryFuture(const QGeoTileSpec &tile, QGeoTiledMap *map, QGeoTiledMappingManagerEngine* engine, QObject *parent = 0); public Q_SLOTS: void retry(); private: - QGeoTileSpec tile_; - QGeoTiledMap *map_; + QGeoTileSpec m_tile; + QGeoTiledMap *m_map; + QPointer<QGeoTiledMappingManagerEngine> m_engine; }; -RetryFuture::RetryFuture(const QGeoTileSpec &tile, QGeoTiledMap *map, QObject *parent) - : QObject(parent), tile_(tile), map_(map) +RetryFuture::RetryFuture(const QGeoTileSpec &tile, QGeoTiledMap *map, QGeoTiledMappingManagerEngine* engine, QObject *parent) + : QObject(parent), m_tile(tile), m_map(map), m_engine(engine) {} void RetryFuture::retry() { QSet<QGeoTileSpec> requestTiles; QSet<QGeoTileSpec> cancelTiles; - requestTiles.insert(tile_); - if (map_) { - QGeoTiledMappingManagerEngine *engine = - static_cast<QGeoTiledMappingManagerEngine *>(map_->engine()); - engine->updateTileRequests(map_, requestTiles, cancelTiles); - } + requestTiles.insert(m_tile); + if (!m_engine.isNull()) + m_engine->updateTileRequests(m_map, requestTiles, cancelTiles); } void QGeoTileRequestManagerPrivate::tileError(const QGeoTileSpec &tile, const QString &errorString) { - if (requested_.contains(tile)) { - int count = retries_.value(tile, 0); - retries_.insert(tile, count + 1); + if (m_requested.contains(tile)) { + int count = m_retries.value(tile, 0); + m_retries.insert(tile, count + 1); if (count >= 5) { qWarning("QGeoTileRequestManager: Failed to fetch tile (%d,%d,%d) 5 times, giving up. " "Last error message was: '%s'", tile.x(), tile.y(), tile.zoom(), qPrintable(errorString)); - requested_.remove(tile); - retries_.remove(tile); - futures_.remove(tile); + m_requested.remove(tile); + m_retries.remove(tile); + m_futures.remove(tile); } else { // Exponential time backoff when retrying int delay = (1 << count) * 500; - QSharedPointer<RetryFuture> future(new RetryFuture(tile, map_)); - futures_.insert(tile, future); + QSharedPointer<RetryFuture> future(new RetryFuture(tile,m_map,m_engine)); + m_futures.insert(tile, future); QTimer::singleShot(delay, future.data(), SLOT(retry())); // Passing .data() to singleShot is ok -- Qt will clean up the |