diff options
author | Alex Wilson <alex.wilson@nokia.com> | 2012-04-18 14:16:32 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-04-20 08:11:12 +0200 |
commit | 1925ba8da6fd9c93dcea3636af527d30ffea3d2e (patch) | |
tree | 7e788d8f17ce893ba95ccb0cc73bd03deb620336 /src/location | |
parent | 65a85f6f49f3ff305cb3517151ba0addc28aa374 (diff) | |
download | qtlocation-1925ba8da6fd9c93dcea3636af527d30ffea3d2e.tar.gz |
Clean up duplicated code in qgeoserviceprovider.cpp
Duplication reduction with the Power of Templates (tm).
Change-Id: I119d83bdc965416788263b295e368b243c2b897e
Reviewed-by: Aaron McCarthy <aaron.mccarthy@nokia.com>
Diffstat (limited to 'src/location')
-rw-r--r-- | src/location/maps/qgeocodingmanager.h | 1 | ||||
-rw-r--r-- | src/location/maps/qgeocodingmanagerengine.h | 1 | ||||
-rw-r--r-- | src/location/maps/qgeomappingmanager.h | 1 | ||||
-rw-r--r-- | src/location/maps/qgeomappingmanagerengine.h | 1 | ||||
-rw-r--r-- | src/location/maps/qgeoroutingmanager.h | 1 | ||||
-rw-r--r-- | src/location/maps/qgeoroutingmanagerengine.h | 1 | ||||
-rw-r--r-- | src/location/maps/qgeoserviceprovider.cpp | 324 | ||||
-rw-r--r-- | src/location/maps/qgeoserviceprovider_p.h | 8 | ||||
-rw-r--r-- | src/location/places/qplacemanager.h | 1 | ||||
-rw-r--r-- | src/location/places/qplacemanagerengine.h | 1 |
10 files changed, 124 insertions, 216 deletions
diff --git a/src/location/maps/qgeocodingmanager.h b/src/location/maps/qgeocodingmanager.h index b3a9c339..7d7f9c5d 100644 --- a/src/location/maps/qgeocodingmanager.h +++ b/src/location/maps/qgeocodingmanager.h @@ -93,6 +93,7 @@ private: Q_DISABLE_COPY(QGeocodingManager) friend class QGeoServiceProvider; + friend class QGeoServiceProviderPrivate; }; QT_END_NAMESPACE diff --git a/src/location/maps/qgeocodingmanagerengine.h b/src/location/maps/qgeocodingmanagerengine.h index d4a4451f..6e2bed6b 100644 --- a/src/location/maps/qgeocodingmanagerengine.h +++ b/src/location/maps/qgeocodingmanagerengine.h @@ -92,6 +92,7 @@ private: Q_DISABLE_COPY(QGeocodingManagerEngine) friend class QGeoServiceProvider; + friend class QGeoServiceProviderPrivate; }; QT_END_NAMESPACE diff --git a/src/location/maps/qgeomappingmanager.h b/src/location/maps/qgeomappingmanager.h index 995288d9..197f596b 100644 --- a/src/location/maps/qgeomappingmanager.h +++ b/src/location/maps/qgeomappingmanager.h @@ -94,6 +94,7 @@ private: Q_DISABLE_COPY(QGeoMappingManager) friend class QGeoServiceProvider; + friend class QGeoServiceProviderPrivate; }; QT_END_NAMESPACE diff --git a/src/location/maps/qgeomappingmanagerengine.h b/src/location/maps/qgeomappingmanagerengine.h index 5a14b1ee..9812c4c8 100644 --- a/src/location/maps/qgeomappingmanagerengine.h +++ b/src/location/maps/qgeomappingmanagerengine.h @@ -113,6 +113,7 @@ private: Q_DISABLE_COPY(QGeoMappingManagerEngine) friend class QGeoServiceProvider; + friend class QGeoServiceProviderPrivate; }; QT_END_NAMESPACE diff --git a/src/location/maps/qgeoroutingmanager.h b/src/location/maps/qgeoroutingmanager.h index c9131ac4..2bde0389 100644 --- a/src/location/maps/qgeoroutingmanager.h +++ b/src/location/maps/qgeoroutingmanager.h @@ -92,6 +92,7 @@ private: Q_DISABLE_COPY(QGeoRoutingManager) friend class QGeoServiceProvider; + friend class QGeoServiceProviderPrivate; }; QT_END_NAMESPACE diff --git a/src/location/maps/qgeoroutingmanagerengine.h b/src/location/maps/qgeoroutingmanagerengine.h index 3ddf863f..66c01548 100644 --- a/src/location/maps/qgeoroutingmanagerengine.h +++ b/src/location/maps/qgeoroutingmanagerengine.h @@ -101,6 +101,7 @@ private: Q_DISABLE_COPY(QGeoRoutingManagerEngine) friend class QGeoServiceProvider; + friend class QGeoServiceProviderPrivate; }; QT_END_NAMESPACE diff --git a/src/location/maps/qgeoserviceprovider.cpp b/src/location/maps/qgeoserviceprovider.cpp index fa337aed..9e72bfed 100644 --- a/src/location/maps/qgeoserviceprovider.cpp +++ b/src/location/maps/qgeoserviceprovider.cpp @@ -165,20 +165,26 @@ QGeoServiceProvider::~QGeoServiceProvider() delete d_ptr; } -QGeoServiceProvider::RoutingFeatures QGeoServiceProvider::routingFeatures() const +/* Template for the routingFeatures(), geocodingFeatures() etc methods. + * Ideally, the enumName would be a template parameter, but strings + * are not a valid const expr. :( */ +template <class Flags> +Flags QGeoServiceProviderPrivate::features(const char *enumName) { - const QMetaObject *mo = QGeoServiceProvider::metaObject(); + const QMetaObject *mo = &QGeoServiceProvider::staticMetaObject; const QMetaEnum en = mo->enumerator( - mo->indexOfEnumerator("RoutingFeatures")); - - RoutingFeatures ret = NoRoutingFeatures; - if (d_ptr->metaData.contains(QStringLiteral("Features")) - && d_ptr->metaData.value(QStringLiteral("Features")).isArray()) { - QJsonArray features = d_ptr->metaData.value(QStringLiteral("Features")).toArray(); + mo->indexOfEnumerator(enumName)); + + /* We need the typename keyword here, or Flags::enum_type will be parsed + * as a non-type and lead to an error */ + Flags ret = typename Flags::enum_type(0); + if (this->metaData.contains(QStringLiteral("Features")) + && this->metaData.value(QStringLiteral("Features")).isArray()) { + QJsonArray features = this->metaData.value(QStringLiteral("Features")).toArray(); foreach (QJsonValue v, features) { int val = en.keyToValue(v.toString().toAscii().constData()); if (v.isString() && val != -1) { - ret |= RoutingFeature(val); + ret |= typename Flags::enum_type(val); } } } @@ -186,67 +192,102 @@ QGeoServiceProvider::RoutingFeatures QGeoServiceProvider::routingFeatures() cons return ret; } -QGeoServiceProvider::GeocodingFeatures QGeoServiceProvider::geocodingFeatures() const +QGeoServiceProvider::RoutingFeatures QGeoServiceProvider::routingFeatures() const { - const QMetaObject *mo = QGeoServiceProvider::metaObject(); - const QMetaEnum en = mo->enumerator( - mo->indexOfEnumerator("GeocodingFeatures")); - - GeocodingFeatures ret = NoGeocodingFeatures; - if (d_ptr->metaData.contains(QStringLiteral("Features")) - && d_ptr->metaData.value(QStringLiteral("Features")).isArray()) { - QJsonArray features = d_ptr->metaData.value(QStringLiteral("Features")).toArray(); - foreach (QJsonValue v, features) { - int val = en.keyToValue(v.toString().toAscii().constData()); - if (v.isString() && val != -1) { - ret |= GeocodingFeature(val); - } - } - } + return d_ptr->features<RoutingFeatures>("RoutingFeatures"); +} - return ret; +QGeoServiceProvider::GeocodingFeatures QGeoServiceProvider::geocodingFeatures() const +{ + return d_ptr->features<GeocodingFeatures>("GeocodingFeatures"); } QGeoServiceProvider::MappingFeatures QGeoServiceProvider::mappingFeatures() const { - const QMetaObject *mo = QGeoServiceProvider::metaObject(); - const QMetaEnum en = mo->enumerator( - mo->indexOfEnumerator("MappingFeatures")); + return d_ptr->features<MappingFeatures>("MappingFeatures"); +} - MappingFeatures ret = NoMappingFeatures; - if (d_ptr->metaData.contains(QStringLiteral("Features")) - && d_ptr->metaData.value(QStringLiteral("Features")).isArray()) { - QJsonArray features = d_ptr->metaData.value(QStringLiteral("Features")).toArray(); - foreach (QJsonValue v, features) { - int val = en.keyToValue(v.toString().toAscii().constData()); - if (v.isString() && val != -1) { - ret |= MappingFeature(val); - } - } - } +QGeoServiceProvider::PlacesFeatures QGeoServiceProvider::placesFeatures() const +{ + return d_ptr->features<PlacesFeatures>("PlacesFeatures"); +} - return ret; +/* Sadly, these are necessary to figure out which of the factory->createX + * methods we need to call. Ideally it would be nice to find a way to embed + * these into the manager() template. */ +template <class Engine> +Engine *createEngine(QGeoServiceProviderPrivate *d_ptr) +{ + return 0; +} +template <> QGeocodingManagerEngine *createEngine<QGeocodingManagerEngine>(QGeoServiceProviderPrivate *d_ptr) +{ + return d_ptr->factory->createGeocodingManagerEngine(d_ptr->parameterMap, &(d_ptr->geocodeError), &(d_ptr->geocodeErrorString)); +} +template <> QGeoRoutingManagerEngine *createEngine<QGeoRoutingManagerEngine>(QGeoServiceProviderPrivate *d_ptr) +{ + return d_ptr->factory->createRoutingManagerEngine(d_ptr->parameterMap, &(d_ptr->routingError), &(d_ptr->routingErrorString)); +} +template <> QGeoMappingManagerEngine *createEngine<QGeoMappingManagerEngine>(QGeoServiceProviderPrivate *d_ptr) +{ + return d_ptr->factory->createMappingManagerEngine(d_ptr->parameterMap, &(d_ptr->mappingError), &(d_ptr->mappingErrorString)); +} +template <> QPlaceManagerEngine *createEngine<QPlaceManagerEngine>(QGeoServiceProviderPrivate *d_ptr) +{ + return d_ptr->factory->createPlaceManagerEngine(d_ptr->parameterMap, &(d_ptr->placeError), &(d_ptr->placeErrorString)); } -QGeoServiceProvider::PlacesFeatures QGeoServiceProvider::placesFeatures() const +/* Template for generating the code for each of the geocodingManager(), + * mappingManager() etc methods */ +template <class Manager, class Engine> +Manager *QGeoServiceProviderPrivate::manager(QGeoServiceProvider::Error *_error, + QString *_errorString, Manager **_manager) { - const QMetaObject *mo = QGeoServiceProvider::metaObject(); - const QMetaEnum en = mo->enumerator( - mo->indexOfEnumerator("PlacesFeatures")); + // make local references just so this method is easier to read + QGeoServiceProvider::Error &error = *_error; + QString &errorString = *_errorString; + Manager * &manager = *_manager; - PlacesFeatures ret = NoPlacesFeatures; - if (d_ptr->metaData.contains(QStringLiteral("Features")) - && d_ptr->metaData.value(QStringLiteral("Features")).isArray()) { - QJsonArray features = d_ptr->metaData.value(QStringLiteral("Features")).toArray(); - foreach (QJsonValue v, features) { - int val = en.keyToValue(v.toString().toAscii().constData()); - if (v.isString() && val != -1) { - ret |= PlacesFeature(val); - } + if (!this->factory) + this->loadPlugin(this->parameterMap); + + if (!this->factory || error != QGeoServiceProvider::NoError) + return 0; + + if (!manager) { + Engine *engine = createEngine<Engine>(this); + + if (engine) { + engine->setManagerName( + this->metaData.value(QStringLiteral("Provider")).toString()); + engine->setManagerVersion( + int(this->metaData.value(QStringLiteral("Version")).toDouble())); + manager = new Manager(engine); + } else { + error = QGeoServiceProvider::NotSupportedError; + errorString = QLatin1String("The service provider does not support the "); + errorString.append(Manager::staticMetaObject.className()); + errorString.append(" type."); + } + + if (error != QGeoServiceProvider::NoError) { + if (manager) + delete manager; + manager = 0; + this->error = error; + this->errorString = errorString; } + + if (manager && this->localeSet) + manager->setLocale(this->locale); } - return ret; + if (manager) { + this->error = QGeoServiceProvider::NoError; + this->errorString.clear(); + } + + return manager; } /*! @@ -272,45 +313,9 @@ QGeoServiceProvider::PlacesFeatures QGeoServiceProvider::placesFeatures() const */ QGeocodingManager* QGeoServiceProvider::geocodingManager() const { - if (!d_ptr->factory) - d_ptr->loadPlugin(d_ptr->parameterMap); - - if (!d_ptr->factory || d_ptr->geocodeError != QGeoServiceProvider::NoError) - return 0; - - if (!d_ptr->geocodingManager) { - QGeocodingManagerEngine *engine = d_ptr->factory->createGeocodingManagerEngine(d_ptr->parameterMap, - &(d_ptr->geocodeError), - &(d_ptr->geocodeErrorString)); - if (engine) { - engine->setManagerName( - d_ptr->metaData.value(QStringLiteral("Provider")).toString()); - engine->setManagerVersion( - int(d_ptr->metaData.value(QStringLiteral("Version")).toDouble())); - d_ptr->geocodingManager = new QGeocodingManager(engine); - } else { - d_ptr->geocodeError = QGeoServiceProvider::NotSupportedError; - d_ptr->geocodeErrorString = QLatin1String("The service provider does not support geocodingManager()."); - } - - if (d_ptr->geocodeError != QGeoServiceProvider::NoError) { - if (d_ptr->geocodingManager) - delete d_ptr->geocodingManager; - d_ptr->geocodingManager = 0; - d_ptr->error = d_ptr->geocodeError; - d_ptr->errorString = d_ptr->geocodeErrorString; - } - - if (d_ptr->geocodingManager && d_ptr->localeSet) - d_ptr->geocodingManager->setLocale(d_ptr->locale); - } - - if (d_ptr->geocodingManager) { - d_ptr->error = QGeoServiceProvider::NoError; - d_ptr->errorString.clear(); - } - - return d_ptr->geocodingManager; + return d_ptr->manager<QGeocodingManager, QGeocodingManagerEngine>( + &(d_ptr->geocodeError), &(d_ptr->geocodeErrorString), + &(d_ptr->geocodingManager)); } /*! @@ -335,46 +340,9 @@ QGeocodingManager* QGeoServiceProvider::geocodingManager() const */ QGeoMappingManager* QGeoServiceProvider::mappingManager() const { - if (!d_ptr->factory) - d_ptr->loadPlugin(d_ptr->parameterMap); - - if (!d_ptr->factory || (d_ptr->mappingError != QGeoServiceProvider::NoError)) - return 0; - - if (!d_ptr->mappingManager) { - QGeoMappingManagerEngine *engine = d_ptr->factory->createMappingManagerEngine(d_ptr->parameterMap, - &(d_ptr->mappingError), - &(d_ptr->mappingErrorString)); - - if (engine) { - engine->setManagerName( - d_ptr->metaData.value(QStringLiteral("Provider")).toString()); - engine->setManagerVersion( - int(d_ptr->metaData.value(QStringLiteral("Version")).toDouble())); - d_ptr->mappingManager = new QGeoMappingManager(engine); - } else { - d_ptr->mappingError = QGeoServiceProvider::NotSupportedError; - d_ptr->mappingErrorString = QLatin1String("The service provider does not support mappingManager()."); - } - - if (d_ptr->mappingError != QGeoServiceProvider::NoError) { - if (d_ptr->mappingManager) - delete d_ptr->mappingManager; - d_ptr->mappingManager = 0; - d_ptr->error = d_ptr->mappingError; - d_ptr->errorString = d_ptr->mappingErrorString; - } - - if (d_ptr->mappingManager && d_ptr->localeSet) - d_ptr->mappingManager->setLocale(d_ptr->locale); - } - - if (d_ptr->mappingManager) { - d_ptr->error = QGeoServiceProvider::NoError; - d_ptr->errorString.clear(); - } - - return d_ptr->mappingManager; + return d_ptr->manager<QGeoMappingManager, QGeoMappingManagerEngine>( + &(d_ptr->mappingError), &(d_ptr->mappingErrorString), + &(d_ptr->mappingManager)); } /*! @@ -399,46 +367,9 @@ QGeoMappingManager* QGeoServiceProvider::mappingManager() const */ QGeoRoutingManager* QGeoServiceProvider::routingManager() const { - if (!d_ptr->factory) - d_ptr->loadPlugin(d_ptr->parameterMap); - - if (!d_ptr->factory || (d_ptr->routingError != QGeoServiceProvider::NoError)) - return 0; - - if (!d_ptr->routingManager) { - QGeoRoutingManagerEngine *engine = d_ptr->factory->createRoutingManagerEngine(d_ptr->parameterMap, - &(d_ptr->routingError), - &(d_ptr->routingErrorString)); - - if (engine) { - engine->setManagerName( - d_ptr->metaData.value(QStringLiteral("Provider")).toString()); - engine->setManagerVersion( - int(d_ptr->metaData.value(QStringLiteral("Version")).toDouble())); - d_ptr->routingManager = new QGeoRoutingManager(engine); - } else { - d_ptr->routingError = QGeoServiceProvider::NotSupportedError; - d_ptr->routingErrorString = QLatin1String("The service provider does not support routingManager()."); - } - - if (d_ptr->routingError != QGeoServiceProvider::NoError) { - if (d_ptr->routingManager) - delete d_ptr->routingManager; - d_ptr->routingManager = 0; - d_ptr->error = d_ptr->routingError; - d_ptr->errorString = d_ptr->routingErrorString; - } - - if (d_ptr->routingManager && d_ptr->localeSet) - d_ptr->routingManager->setLocale(d_ptr->locale); - } - - if (d_ptr->routingManager) { - d_ptr->error = QGeoServiceProvider::NoError; - d_ptr->errorString.clear(); - } - - return d_ptr->routingManager; + return d_ptr->manager<QGeoRoutingManager, QGeoRoutingManagerEngine>( + &(d_ptr->routingError), &(d_ptr->routingErrorString), + &(d_ptr->routingManager)); } /*! @@ -462,48 +393,9 @@ QGeoRoutingManager* QGeoServiceProvider::routingManager() const */ QPlaceManager *QGeoServiceProvider::placeManager() const { - if (!d_ptr->factory) - d_ptr->loadPlugin(d_ptr->parameterMap); - - if (!d_ptr->factory || (d_ptr->placeError != QGeoServiceProvider::NoError)) - return 0; - - if (!d_ptr->placeManager) { - QPlaceManagerEngine *engine = d_ptr->factory->createPlaceManagerEngine(d_ptr->parameterMap, - &(d_ptr->placeError), - &(d_ptr->placeErrorString)); - - if (engine) { - engine->setManagerName( - d_ptr->metaData.value(QStringLiteral("Provider")).toString()); - engine->setManagerVersion( - int(d_ptr->metaData.value(QStringLiteral("Version")).toDouble())); - d_ptr->placeManager = new QPlaceManager(engine); - engine->d_ptr->manager = d_ptr->placeManager; - - } else { - d_ptr->placeError = QGeoServiceProvider::NotSupportedError; - d_ptr->placeErrorString = QLatin1String("The service provider does not support placeManager()."); - } - - if (d_ptr->placeError != QGeoServiceProvider::NoError) { - if (d_ptr->placeManager) - delete d_ptr->placeManager; - d_ptr->placeManager = 0; - d_ptr->error = d_ptr->placeError; - d_ptr->errorString = d_ptr->placeErrorString; - } - - if (d_ptr->placeManager && d_ptr->localeSet) - d_ptr->placeManager->setLocale(d_ptr->locale); - } - - if (d_ptr->placeManager) { - d_ptr->error = QGeoServiceProvider::NoError; - d_ptr->errorString.clear(); - } - - return d_ptr->placeManager; + return d_ptr->manager<QPlaceManager, QPlaceManagerEngine>( + &(d_ptr->placeError), &(d_ptr->placeErrorString), + &(d_ptr->placeManager)); } /*! diff --git a/src/location/maps/qgeoserviceprovider_p.h b/src/location/maps/qgeoserviceprovider_p.h index 191f3517..f1d24ddf 100644 --- a/src/location/maps/qgeoserviceprovider_p.h +++ b/src/location/maps/qgeoserviceprovider_p.h @@ -77,6 +77,14 @@ public: void loadMeta(); void loadPlugin(const QMap<QString, QVariant> ¶meters); void unload(); + + /* helper templates for generating the feature and manager accessors */ + template <class Manager, class Engine> + Manager *manager(QGeoServiceProvider::Error *error, + QString *errorString, Manager **manager); + template <class Flags> + Flags features(const char *enumName); + QGeoServiceProviderFactory *factory; QJsonObject metaData; diff --git a/src/location/places/qplacemanager.h b/src/location/places/qplacemanager.h index 36e53415..4a3a76cd 100644 --- a/src/location/places/qplacemanager.h +++ b/src/location/places/qplacemanager.h @@ -127,6 +127,7 @@ private: QPlaceManagerEngine *d; friend class QGeoServiceProvider; + friend class QGeoServiceProviderPrivate; friend class QPlaceIcon; }; diff --git a/src/location/places/qplacemanagerengine.h b/src/location/places/qplacemanagerengine.h index 66ee4f30..e6100eda 100644 --- a/src/location/places/qplacemanagerengine.h +++ b/src/location/places/qplacemanagerengine.h @@ -117,6 +117,7 @@ private: Q_DISABLE_COPY(QPlaceManagerEngine) friend class QGeoServiceProvider; + friend class QGeoServiceProviderPrivate; }; QT_END_NAMESPACE |