Skip to content

Commit e1f6edb

Browse files
committed
Streamline singleton behavior in a class QgsSingleton
If a singleton is unused in an application, it's not going to be created just to be deleted instantanously on app exit. QgsCoordinateTransformCache will also be cleaned on exit.
1 parent fa1e803 commit e1f6edb

10 files changed

+81
-55
lines changed

src/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ SET(QGIS_CORE_HDRS
557557
qgssimplifymethod.h
558558
qgssnapper.h
559559
qgsspatialindex.h
560+
qgssingleton.h
560561
qgstolerance.h
561562
qgsvectordataprovider.h
562563
qgsvectorlayercache.h

src/core/qgsapplication.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@
1414
***************************************************************************/
1515

1616
#include "qgsapplication.h"
17+
#include "qgscrscache.h"
18+
#include "qgsexception.h"
19+
#include "qgsgeometry.h"
1720
#include "qgslogger.h"
1821
#include "qgsmaplayerregistry.h"
19-
#include "qgsproviderregistry.h"
2022
#include "qgsnetworkaccessmanager.h"
21-
#include "qgsexception.h"
22-
#include "qgsgeometry.h"
23+
#include "qgsproviderregistry.h"
2324

2425
#include <QDir>
2526
#include <QFile>
@@ -607,11 +608,13 @@ void QgsApplication::initQgis()
607608

608609
void QgsApplication::exitQgis()
609610
{
610-
delete QgsMapLayerRegistry::instance();
611-
611+
// Cleanup providers
612612
delete QgsProviderRegistry::instance();
613613

614-
delete QgsNetworkAccessManager::instance();
614+
// Cleanup known singletons
615+
QgsMapLayerRegistry::cleanup();
616+
QgsNetworkAccessManager::cleanup();
617+
QgsCoordinateTransformCache::cleanup();
615618
}
616619

617620
QString QgsApplication::showSettings()

src/core/qgscrscache.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,15 @@
1818
#include "qgscrscache.h"
1919
#include "qgscoordinatetransform.h"
2020

21-
22-
QgsCoordinateTransformCache* QgsCoordinateTransformCache::instance()
23-
{
24-
static QgsCoordinateTransformCache mInstance;
25-
return &mInstance;
26-
}
27-
2821
QgsCoordinateTransformCache::~QgsCoordinateTransformCache()
2922
{
3023
QHash< QPair< QString, QString >, QgsCoordinateTransform* >::const_iterator tIt = mTransforms.constBegin();
3124
for ( ; tIt != mTransforms.constEnd(); ++tIt )
3225
{
3326
delete tIt.value();
3427
}
28+
29+
mTransforms.clear();
3530
}
3631

3732
const QgsCoordinateTransform* QgsCoordinateTransformCache::transform( const QString& srcAuthId, const QString& destAuthId, int srcDatumTransform, int destDatumTransform )

src/core/qgscrscache.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@
1919
#define QGSCRSCACHE_H
2020

2121
#include "qgscoordinatereferencesystem.h"
22+
#include "qgssingleton.h"
2223
#include <QHash>
2324

2425
class QgsCoordinateTransform;
2526

2627
/**Cache coordinate transform by authid of source/dest transformation to avoid the
2728
overhead of initialisation for each redraw*/
28-
class CORE_EXPORT QgsCoordinateTransformCache
29+
class CORE_EXPORT QgsCoordinateTransformCache : public QgsSingleton<QgsCoordinateTransformCache>
2930
{
3031
public:
31-
static QgsCoordinateTransformCache* instance();
3232
~QgsCoordinateTransformCache();
3333
/**Returns coordinate transformation. Cache keeps ownership
3434
@param srcAuthId auth id string of source crs
@@ -41,7 +41,6 @@ class CORE_EXPORT QgsCoordinateTransformCache
4141
void invalidateCrs( const QString& crsAuthId );
4242

4343
private:
44-
static QgsCoordinateTransformCache* mInstance;
4544
QMultiHash< QPair< QString, QString >, QgsCoordinateTransform* > mTransforms; //same auth_id pairs might have different datum transformations
4645
};
4746

src/core/qgsmaplayerregistry.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,6 @@
1919
#include "qgsmaplayer.h"
2020
#include "qgslogger.h"
2121

22-
//
23-
// Static calls to enforce singleton behaviour
24-
//
25-
QgsMapLayerRegistry *QgsMapLayerRegistry::mInstance = 0;
26-
QgsMapLayerRegistry *QgsMapLayerRegistry::instance()
27-
{
28-
if ( mInstance == 0 )
29-
{
30-
mInstance = new QgsMapLayerRegistry();
31-
}
32-
return mInstance;
33-
}
34-
3522
//
3623
// Main class begins now...
3724
//

src/core/qgsmaplayerregistry.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,20 @@
2323
#include <QSet>
2424
#include <QObject>
2525
#include <QStringList>
26+
27+
#include "qgssingleton.h"
2628
class QString;
2729
class QgsMapLayer;
2830

2931
/** \ingroup core
3032
* This class tracks map layers that are currently loaded and provides
3133
* a means to fetch a pointer to a map layer and delete it.
3234
*/
33-
class CORE_EXPORT QgsMapLayerRegistry : public QObject
35+
class CORE_EXPORT QgsMapLayerRegistry : public QObject, public QgsSingleton<QgsMapLayerRegistry>
3436
{
3537
Q_OBJECT
3638

3739
public:
38-
//! Returns the instance pointer, creating the object on the first call
39-
static QgsMapLayerRegistry * instance();
40-
4140
//! Return the number of registered layers.
4241
int count();
4342

@@ -239,9 +238,10 @@ class CORE_EXPORT QgsMapLayerRegistry : public QObject
239238
//! private singleton constructor
240239
QgsMapLayerRegistry( QObject * parent = 0 );
241240

242-
static QgsMapLayerRegistry *mInstance;
243241
QMap<QString, QgsMapLayer*> mMapLayers;
244242
QSet<QgsMapLayer*> mOwnedLayers;
243+
244+
friend class QgsSingleton; // Let QgsSingleton access private constructor
245245
}; // class QgsMapLayerRegistry
246246

247247
#endif //QgsMapLayerRegistry_H

src/core/qgsnetworkaccessmanager.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,19 +86,6 @@ class QgsNetworkProxyFactory : public QNetworkProxyFactory
8686
}
8787
};
8888

89-
//
90-
// Static calls to enforce singleton behaviour
91-
//
92-
QgsNetworkAccessManager* QgsNetworkAccessManager::sInstance = 0;
93-
QgsNetworkAccessManager* QgsNetworkAccessManager::instance()
94-
{
95-
if ( sInstance == 0 )
96-
{
97-
sInstance = new QgsNetworkAccessManager();
98-
}
99-
return sInstance;
100-
}
101-
10289
QgsNetworkAccessManager::QgsNetworkAccessManager( QObject *parent )
10390
: QNetworkAccessManager( parent )
10491
, mUseSystemProxy( false )

src/core/qgsnetworkaccessmanager.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <QNetworkProxy>
2525
#include <QNetworkRequest>
2626

27+
#include "qgssingleton.h"
28+
2729
/*
2830
* \class QgsNetworkAccessManager
2931
* \brief network access manager for QGIS
@@ -41,15 +43,11 @@
4143
* that the fallback proxy should not be used for, then no proxy will be used.
4244
*
4345
*/
44-
class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager
46+
class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager, public QgsSingleton<QgsNetworkAccessManager>
4547
{
4648
Q_OBJECT
4749

4850
public:
49-
//! returns a pointer to the single instance
50-
// and creates that instance on the first call.
51-
static QgsNetworkAccessManager* instance();
52-
5351
QgsNetworkAccessManager( QObject *parent = 0 );
5452

5553
//! destructor
@@ -100,7 +98,6 @@ class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager
10098
QNetworkProxy mFallbackProxy;
10199
QStringList mExcludedURLs;
102100
bool mUseSystemProxy;
103-
static QgsNetworkAccessManager* sInstance;
104101
};
105102

106103
#endif // QGSNETWORKACCESSMANAGER_H

src/core/qgsproviderregistry.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ QgsProviderRegistry::~QgsProviderRegistry()
208208

209209
while ( it != mProviders.end() )
210210
{
211-
QgsDebugMsg( QString( "cleanup:%1" ).arg( it->first ) );
211+
QgsDebugMsg( QString( "cleanup: %1" ).arg( it->first ) );
212212
QString lib = it->second->library();
213213
QLibrary myLib( lib );
214214
if ( myLib.isLoaded() )
@@ -405,7 +405,7 @@ QWidget* QgsProviderRegistry::selectWidget( const QString & providerKey,
405405

406406
#if QT_VERSION >= 0x050000
407407
QFunctionPointer QgsProviderRegistry::function( QString const & providerKey,
408-
QString const & functionName )
408+
QString const & functionName )
409409
{
410410
QLibrary myLib( library( providerKey ) );
411411

src/core/qgssingleton.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/***************************************************************************
2+
qgssingleton.h
3+
--------------------------------------
4+
Date : 24.11.2014
5+
Copyright : (C) 2014 Matthias Kuhn
6+
Email : matthias dot kuhn at gmx dot ch
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSSINGLETON_H
17+
#define QGSSINGLETON_H
18+
19+
template <typename T>
20+
class QgsSingleton
21+
{
22+
public:
23+
static T* instance()
24+
{
25+
if ( sInstance == 0 )
26+
{
27+
sInstance = createInstance();
28+
}
29+
return sInstance;
30+
}
31+
32+
static void cleanup()
33+
{
34+
delete sInstance;
35+
sInstance = 0;
36+
}
37+
38+
protected:
39+
virtual ~QgsSingleton() {}
40+
41+
explicit QgsSingleton()
42+
{
43+
Q_ASSERT( sInstance == 0 );
44+
sInstance = static_cast<T*>( this );
45+
}
46+
47+
private:
48+
static T* sInstance;
49+
static T* createInstance()
50+
{
51+
return new T;
52+
}
53+
};
54+
55+
template <typename T> T* QgsSingleton<T>::sInstance = 0;
56+
57+
#endif // QGSSINGLETON_H

0 commit comments

Comments
 (0)