summaryrefslogtreecommitdiff
path: root/src/location
diff options
context:
space:
mode:
authorAlex Wilson <alex.wilson@nokia.com>2012-04-18 14:16:32 +1000
committerQt by Nokia <qt-info@nokia.com>2012-04-20 08:11:12 +0200
commit1925ba8da6fd9c93dcea3636af527d30ffea3d2e (patch)
tree7e788d8f17ce893ba95ccb0cc73bd03deb620336 /src/location
parent65a85f6f49f3ff305cb3517151ba0addc28aa374 (diff)
downloadqtlocation-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.h1
-rw-r--r--src/location/maps/qgeocodingmanagerengine.h1
-rw-r--r--src/location/maps/qgeomappingmanager.h1
-rw-r--r--src/location/maps/qgeomappingmanagerengine.h1
-rw-r--r--src/location/maps/qgeoroutingmanager.h1
-rw-r--r--src/location/maps/qgeoroutingmanagerengine.h1
-rw-r--r--src/location/maps/qgeoserviceprovider.cpp324
-rw-r--r--src/location/maps/qgeoserviceprovider_p.h8
-rw-r--r--src/location/places/qplacemanager.h1
-rw-r--r--src/location/places/qplacemanagerengine.h1
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> &parameters);
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