mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Streamline singleton behavior in a class QgsSingleton, take two
delete provider registry after map layer registry to avoid crashes
This commit is contained in:
parent
e61d27e180
commit
b4a8547197
@ -557,6 +557,7 @@ SET(QGIS_CORE_HDRS
|
||||
qgssimplifymethod.h
|
||||
qgssnapper.h
|
||||
qgsspatialindex.h
|
||||
qgssingleton.h
|
||||
qgstolerance.h
|
||||
qgsvectordataprovider.h
|
||||
qgsvectorlayercache.h
|
||||
|
@ -14,12 +14,13 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsapplication.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgsproviderregistry.h"
|
||||
#include "qgsnetworkaccessmanager.h"
|
||||
#include "qgscrscache.h"
|
||||
#include "qgsexception.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgsnetworkaccessmanager.h"
|
||||
#include "qgsproviderregistry.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
@ -607,11 +608,13 @@ void QgsApplication::initQgis()
|
||||
|
||||
void QgsApplication::exitQgis()
|
||||
{
|
||||
delete QgsMapLayerRegistry::instance();
|
||||
// Cleanup known singletons
|
||||
QgsMapLayerRegistry::cleanup();
|
||||
QgsNetworkAccessManager::cleanup();
|
||||
QgsCoordinateTransformCache::cleanup();
|
||||
|
||||
// Cleanup providers
|
||||
delete QgsProviderRegistry::instance();
|
||||
|
||||
delete QgsNetworkAccessManager::instance();
|
||||
}
|
||||
|
||||
QString QgsApplication::showSettings()
|
||||
|
@ -18,13 +18,6 @@
|
||||
#include "qgscrscache.h"
|
||||
#include "qgscoordinatetransform.h"
|
||||
|
||||
|
||||
QgsCoordinateTransformCache* QgsCoordinateTransformCache::instance()
|
||||
{
|
||||
static QgsCoordinateTransformCache mInstance;
|
||||
return &mInstance;
|
||||
}
|
||||
|
||||
QgsCoordinateTransformCache::~QgsCoordinateTransformCache()
|
||||
{
|
||||
QHash< QPair< QString, QString >, QgsCoordinateTransform* >::const_iterator tIt = mTransforms.constBegin();
|
||||
@ -32,6 +25,8 @@ QgsCoordinateTransformCache::~QgsCoordinateTransformCache()
|
||||
{
|
||||
delete tIt.value();
|
||||
}
|
||||
|
||||
mTransforms.clear();
|
||||
}
|
||||
|
||||
const QgsCoordinateTransform* QgsCoordinateTransformCache::transform( const QString& srcAuthId, const QString& destAuthId, int srcDatumTransform, int destDatumTransform )
|
||||
|
@ -19,16 +19,16 @@
|
||||
#define QGSCRSCACHE_H
|
||||
|
||||
#include "qgscoordinatereferencesystem.h"
|
||||
#include "qgssingleton.h"
|
||||
#include <QHash>
|
||||
|
||||
class QgsCoordinateTransform;
|
||||
|
||||
/**Cache coordinate transform by authid of source/dest transformation to avoid the
|
||||
overhead of initialisation for each redraw*/
|
||||
class CORE_EXPORT QgsCoordinateTransformCache
|
||||
class CORE_EXPORT QgsCoordinateTransformCache : public QgsSingleton<QgsCoordinateTransformCache>
|
||||
{
|
||||
public:
|
||||
static QgsCoordinateTransformCache* instance();
|
||||
~QgsCoordinateTransformCache();
|
||||
/**Returns coordinate transformation. Cache keeps ownership
|
||||
@param srcAuthId auth id string of source crs
|
||||
@ -41,7 +41,6 @@ class CORE_EXPORT QgsCoordinateTransformCache
|
||||
void invalidateCrs( const QString& crsAuthId );
|
||||
|
||||
private:
|
||||
static QgsCoordinateTransformCache* mInstance;
|
||||
QMultiHash< QPair< QString, QString >, QgsCoordinateTransform* > mTransforms; //same auth_id pairs might have different datum transformations
|
||||
};
|
||||
|
||||
|
@ -19,19 +19,6 @@
|
||||
#include "qgsmaplayer.h"
|
||||
#include "qgslogger.h"
|
||||
|
||||
//
|
||||
// Static calls to enforce singleton behaviour
|
||||
//
|
||||
QgsMapLayerRegistry *QgsMapLayerRegistry::mInstance = 0;
|
||||
QgsMapLayerRegistry *QgsMapLayerRegistry::instance()
|
||||
{
|
||||
if ( mInstance == 0 )
|
||||
{
|
||||
mInstance = new QgsMapLayerRegistry();
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
//
|
||||
// Main class begins now...
|
||||
//
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include <QSet>
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
|
||||
#include "qgssingleton.h"
|
||||
class QString;
|
||||
class QgsMapLayer;
|
||||
|
||||
@ -30,14 +32,11 @@ class QgsMapLayer;
|
||||
* This class tracks map layers that are currently loaded and provides
|
||||
* a means to fetch a pointer to a map layer and delete it.
|
||||
*/
|
||||
class CORE_EXPORT QgsMapLayerRegistry : public QObject
|
||||
class CORE_EXPORT QgsMapLayerRegistry : public QObject, public QgsSingleton<QgsMapLayerRegistry>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! Returns the instance pointer, creating the object on the first call
|
||||
static QgsMapLayerRegistry * instance();
|
||||
|
||||
//! Return the number of registered layers.
|
||||
int count();
|
||||
|
||||
@ -239,9 +238,10 @@ class CORE_EXPORT QgsMapLayerRegistry : public QObject
|
||||
//! private singleton constructor
|
||||
QgsMapLayerRegistry( QObject * parent = 0 );
|
||||
|
||||
static QgsMapLayerRegistry *mInstance;
|
||||
QMap<QString, QgsMapLayer*> mMapLayers;
|
||||
QSet<QgsMapLayer*> mOwnedLayers;
|
||||
|
||||
friend class QgsSingleton; // Let QgsSingleton access private constructor
|
||||
}; // class QgsMapLayerRegistry
|
||||
|
||||
#endif //QgsMapLayerRegistry_H
|
||||
|
@ -86,19 +86,6 @@ class QgsNetworkProxyFactory : public QNetworkProxyFactory
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// Static calls to enforce singleton behaviour
|
||||
//
|
||||
QgsNetworkAccessManager* QgsNetworkAccessManager::sInstance = 0;
|
||||
QgsNetworkAccessManager* QgsNetworkAccessManager::instance()
|
||||
{
|
||||
if ( sInstance == 0 )
|
||||
{
|
||||
sInstance = new QgsNetworkAccessManager();
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
QgsNetworkAccessManager::QgsNetworkAccessManager( QObject *parent )
|
||||
: QNetworkAccessManager( parent )
|
||||
, mUseSystemProxy( false )
|
||||
|
@ -24,6 +24,8 @@
|
||||
#include <QNetworkProxy>
|
||||
#include <QNetworkRequest>
|
||||
|
||||
#include "qgssingleton.h"
|
||||
|
||||
/*
|
||||
* \class QgsNetworkAccessManager
|
||||
* \brief network access manager for QGIS
|
||||
@ -41,15 +43,11 @@
|
||||
* that the fallback proxy should not be used for, then no proxy will be used.
|
||||
*
|
||||
*/
|
||||
class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager
|
||||
class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager, public QgsSingleton<QgsNetworkAccessManager>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
//! returns a pointer to the single instance
|
||||
// and creates that instance on the first call.
|
||||
static QgsNetworkAccessManager* instance();
|
||||
|
||||
QgsNetworkAccessManager( QObject *parent = 0 );
|
||||
|
||||
//! destructor
|
||||
@ -100,7 +98,6 @@ class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager
|
||||
QNetworkProxy mFallbackProxy;
|
||||
QStringList mExcludedURLs;
|
||||
bool mUseSystemProxy;
|
||||
static QgsNetworkAccessManager* sInstance;
|
||||
};
|
||||
|
||||
#endif // QGSNETWORKACCESSMANAGER_H
|
||||
|
@ -208,7 +208,7 @@ QgsProviderRegistry::~QgsProviderRegistry()
|
||||
|
||||
while ( it != mProviders.end() )
|
||||
{
|
||||
QgsDebugMsg( QString( "cleanup:%1" ).arg( it->first ) );
|
||||
QgsDebugMsg( QString( "cleanup: %1" ).arg( it->first ) );
|
||||
QString lib = it->second->library();
|
||||
QLibrary myLib( lib );
|
||||
if ( myLib.isLoaded() )
|
||||
@ -405,7 +405,7 @@ QWidget* QgsProviderRegistry::selectWidget( const QString & providerKey,
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
QFunctionPointer QgsProviderRegistry::function( QString const & providerKey,
|
||||
QString const & functionName )
|
||||
QString const & functionName )
|
||||
{
|
||||
QLibrary myLib( library( providerKey ) );
|
||||
|
||||
|
57
src/core/qgssingleton.h
Normal file
57
src/core/qgssingleton.h
Normal file
@ -0,0 +1,57 @@
|
||||
/***************************************************************************
|
||||
qgssingleton.h
|
||||
--------------------------------------
|
||||
Date : 24.11.2014
|
||||
Copyright : (C) 2014 Matthias Kuhn
|
||||
Email : matthias dot kuhn at gmx dot ch
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSSINGLETON_H
|
||||
#define QGSSINGLETON_H
|
||||
|
||||
template <typename T>
|
||||
class QgsSingleton
|
||||
{
|
||||
public:
|
||||
static T* instance()
|
||||
{
|
||||
if ( sInstance == 0 )
|
||||
{
|
||||
sInstance = createInstance();
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
static void cleanup()
|
||||
{
|
||||
delete sInstance;
|
||||
sInstance = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~QgsSingleton() {}
|
||||
|
||||
explicit QgsSingleton()
|
||||
{
|
||||
Q_ASSERT( sInstance == 0 );
|
||||
sInstance = static_cast<T*>( this );
|
||||
}
|
||||
|
||||
private:
|
||||
static T* sInstance;
|
||||
static T* createInstance()
|
||||
{
|
||||
return new T;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> T* QgsSingleton<T>::sInstance = 0;
|
||||
|
||||
#endif // QGSSINGLETON_H
|
Loading…
x
Reference in New Issue
Block a user