Skip to content

Commit

Permalink
QgsSourceSelectProviderRegistry delayed initialization
Browse files Browse the repository at this point in the history
Due to QgsGui being initialized after data provider.
  • Loading branch information
elpaso committed Sep 4, 2017
1 parent 42bd913 commit 1816087
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 33 deletions.
12 changes: 9 additions & 3 deletions python/gui/qgssourceselectproviderregistry.sip
Expand Up @@ -17,6 +17,12 @@ class QgsSourceSelectProviderRegistry
QgsSourceSelectProviderRegistry is not usually directly created, but rather accessed through
QgsGui.sourceSelectProviderRegistry().

.. note::

This class access to QgsProviderRegistry instance to initialize, but QgsProviderRegistry is
typically initialized after QgsGui is constructed, for this reason a delayed initialization has been
implemented in the class.

.. versionadded:: 3.0
%End

Expand All @@ -29,7 +35,7 @@ class QgsSourceSelectProviderRegistry
~QgsSourceSelectProviderRegistry();


QList< QgsSourceSelectProvider *> providers() const;
QList< QgsSourceSelectProvider *> providers();
%Docstring
Get list of available providers
:rtype: list of QgsSourceSelectProvider
Expand All @@ -45,13 +51,13 @@ Add a provider implementation. Takes ownership of the object.
Remove provider implementation from the list (provider object is deleted)
%End

QgsSourceSelectProvider *providerByName( const QString &name ) const;
QgsSourceSelectProvider *providerByName( const QString &name );
%Docstring
Return a provider by name or None if not found
:rtype: QgsSourceSelectProvider
%End

QList<QgsSourceSelectProvider *> providersByKey( const QString &providerKey ) const;
QList<QgsSourceSelectProvider *> providersByKey( const QString &providerKey );
%Docstring
Return a (possibly empty) list of providers by data provider's key
:rtype: list of QgsSourceSelectProvider
Expand Down
72 changes: 45 additions & 27 deletions src/gui/qgssourceselectproviderregistry.cpp
Expand Up @@ -24,33 +24,20 @@ typedef QList<QgsSourceSelectProvider *> *sourceSelectProviders_t();

QgsSourceSelectProviderRegistry::QgsSourceSelectProviderRegistry()
{
QStringList providersList = QgsProviderRegistry::instance()->providerList();

Q_FOREACH ( const QString &key, providersList )
{
std::unique_ptr< QLibrary > library( QgsProviderRegistry::instance()->createProviderLibrary( key ) );
if ( !library )
continue;

sourceSelectProviders_t *sourceSelectProvidersFn = reinterpret_cast< sourceSelectProviders_t * >( cast_to_fptr( library->resolve( "sourceSelectProviders" ) ) );
if ( sourceSelectProvidersFn )
{
QList<QgsSourceSelectProvider *> *providerList = sourceSelectProvidersFn();
// the function is a factory - we keep ownership of the returned providers
for ( auto provider : qgsAsConst( *providerList ) )
{
addProvider( provider );
}
delete providerList;
}
}
// Initialization is delayed
}

QgsSourceSelectProviderRegistry::~QgsSourceSelectProviderRegistry()
{
qDeleteAll( mProviders );
}

QList<QgsSourceSelectProvider *> QgsSourceSelectProviderRegistry::providers()
{
init();
return mProviders;
}

void QgsSourceSelectProviderRegistry::addProvider( QgsSourceSelectProvider *provider )
{
mProviders.append( provider );
Expand All @@ -67,9 +54,10 @@ void QgsSourceSelectProviderRegistry::removeProvider( QgsSourceSelectProvider *p
delete mProviders.takeAt( index );
}

QgsSourceSelectProvider *QgsSourceSelectProviderRegistry::providerByName( const QString &name ) const
QgsSourceSelectProvider *QgsSourceSelectProviderRegistry::providerByName( const QString &name )
{
for ( const auto provider : qgsAsConst( mProviders ) )
const QList<QgsSourceSelectProvider *> providerList = providers();
for ( const auto provider : providerList )
{
if ( provider->name() == name )
{
Expand All @@ -79,15 +67,45 @@ QgsSourceSelectProvider *QgsSourceSelectProviderRegistry::providerByName( const
return nullptr;
}

QList<QgsSourceSelectProvider *> QgsSourceSelectProviderRegistry::providersByKey( const QString &providerKey ) const
QList<QgsSourceSelectProvider *> QgsSourceSelectProviderRegistry::providersByKey( const QString &providerKey )
{
QList<QgsSourceSelectProvider *> providerList;
for ( const auto provider : qgsAsConst( mProviders ) )
QList<QgsSourceSelectProvider *> result;
const QList<QgsSourceSelectProvider *> providerList = providers();
for ( const auto provider : providerList )
{
if ( provider->providerKey() == providerKey )
{
providerList << provider;
result << provider;
}
}
return result;
}

void QgsSourceSelectProviderRegistry::init()
{
if ( mInitialized )
{
return;
}
QStringList providersList = QgsProviderRegistry::instance()->providerList();
Q_FOREACH ( const QString &key, providersList )
{
std::unique_ptr< QLibrary > library( QgsProviderRegistry::instance()->createProviderLibrary( key ) );
if ( !library )
continue;

sourceSelectProviders_t *sourceSelectProvidersFn = reinterpret_cast< sourceSelectProviders_t * >( cast_to_fptr( library->resolve( "sourceSelectProviders" ) ) );
if ( sourceSelectProvidersFn )
{
QList<QgsSourceSelectProvider *> *providerList = sourceSelectProvidersFn();
// the function is a factory - we keep ownership of the returned providers
for ( auto provider : qgsAsConst( *providerList ) )
{
addProvider( provider );
}
delete providerList;
}
}
return providerList;
mInitialized = true;
}

14 changes: 11 additions & 3 deletions src/gui/qgssourceselectproviderregistry.h
Expand Up @@ -28,6 +28,10 @@ class QgsSourceSelectProvider;
* QgsSourceSelectProviderRegistry is not usually directly created, but rather accessed through
* QgsGui::sourceSelectProviderRegistry().
*
* \note This class access to QgsProviderRegistry instance to initialize, but QgsProviderRegistry is
* typically initialized after QgsGui is constructed, for this reason a delayed initialization has been
* implemented in the class.
*
* \since QGIS 3.0
*/
class GUI_EXPORT QgsSourceSelectProviderRegistry
Expand All @@ -43,7 +47,7 @@ class GUI_EXPORT QgsSourceSelectProviderRegistry
QgsSourceSelectProviderRegistry &operator=( const QgsSourceSelectProviderRegistry &rh ) = delete;

//! Get list of available providers
QList< QgsSourceSelectProvider *> providers() const { return mProviders; }
QList< QgsSourceSelectProvider *> providers();

//! Add a provider implementation. Takes ownership of the object.
void addProvider( QgsSourceSelectProvider *provider SIP_TRANSFER );
Expand All @@ -52,13 +56,17 @@ class GUI_EXPORT QgsSourceSelectProviderRegistry
void removeProvider( QgsSourceSelectProvider *provider );

//! Return a provider by name or nullptr if not found
QgsSourceSelectProvider *providerByName( const QString &name ) const;
QgsSourceSelectProvider *providerByName( const QString &name );

//! Return a (possibly empty) list of providers by data provider's key
QList<QgsSourceSelectProvider *> providersByKey( const QString &providerKey ) const;
QList<QgsSourceSelectProvider *> providersByKey( const QString &providerKey );


private:
//! Populate the providers list, this needs to happen after the data provider
//! registry has been initialized.
void init();
bool mInitialized = false;
#ifdef SIP_RUN
QgsSourceSelectProviderRegistry( const QgsSourceSelectProviderRegistry &rh );
#endif
Expand Down

0 comments on commit 1816087

Please sign in to comment.