From 25aaa9d4854678ad40e5b6488ebc797705fc8bd8 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Thu, 23 May 2013 17:49:53 +0200 Subject: [PATCH] Make AccountModel loading asynchronous. AccountManager starts up in 3 steps, first waiting for credentials and then for Servent to be ready. During this time an AccountModel could be instantiated in the GUI thread, which needs AccountManager, and if the latter is not ready at that time, the former cannot be populated with sane data. This commit splits the AccountModel ctor so that it waits for AccountManager to be ready before hooking up to its signals and performing the initial model reset. --- src/libtomahawk/accounts/AccountManager.cpp | 6 +++++- src/libtomahawk/accounts/AccountManager.h | 7 +++++-- src/libtomahawk/accounts/AccountModel.cpp | 13 +++++++++++++ src/libtomahawk/accounts/AccountModel.h | 2 ++ 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/libtomahawk/accounts/AccountManager.cpp b/src/libtomahawk/accounts/AccountManager.cpp index 1bc1e49ec..fdc26c216 100644 --- a/src/libtomahawk/accounts/AccountManager.cpp +++ b/src/libtomahawk/accounts/AccountManager.cpp @@ -57,6 +57,7 @@ AccountManager::instance() AccountManager::AccountManager( QObject *parent ) : QObject( parent ) , m_readyForSip( false ) + , m_completelyReady( false ) { s_instance = this; @@ -307,7 +308,7 @@ AccountManager::finishLoadingFromConfig( const QStringList& accountIds ) } m_readyForSip = true; - emit readyForSip(); + emit readyForSip(); //we have to yield to TomahawkApp because we don't know if Servent is ready } @@ -319,6 +320,9 @@ AccountManager::initSIP() { hookupAndEnable( account, true ); } + + m_completelyReady = true; + emit ready(); } diff --git a/src/libtomahawk/accounts/AccountManager.h b/src/libtomahawk/accounts/AccountManager.h index 675017625..99963dd45 100644 --- a/src/libtomahawk/accounts/AccountManager.h +++ b/src/libtomahawk/accounts/AccountManager.h @@ -85,8 +85,9 @@ public: Account* zeroconfAccount() const; - bool isConnected() const { return m_connected; } - bool isReadyForSip() const { return m_readyForSip; } + bool isConnected() const { return m_connected; } //for use by TomahawkApp during startup + bool isReadyForSip() const { return m_readyForSip; } //for use by TomahawkApp during startup + bool isReady() const { return m_completelyReady; } CredentialsManager* credentialsManager() const { return m_creds; } @@ -98,6 +99,7 @@ public slots: signals: void readyForFactories(); //this happens first, right before loading accounts from config void readyForSip(); //then this, so TomahawkApp can call initSIP if Servent is ready + void ready(); //finally, when everything is done void added( Tomahawk::Accounts::Account* ); void removed( Tomahawk::Accounts::Account* ); @@ -132,6 +134,7 @@ private: QList< Account* > m_connectedAccounts; bool m_connected; bool m_readyForSip; + bool m_completelyReady; QHash< AccountType, QList< Account* > > m_accountsByAccountType; QHash< QString, AccountFactory* > m_accountFactories; diff --git a/src/libtomahawk/accounts/AccountModel.cpp b/src/libtomahawk/accounts/AccountModel.cpp index 82eed2c96..ff36e0b6b 100644 --- a/src/libtomahawk/accounts/AccountModel.cpp +++ b/src/libtomahawk/accounts/AccountModel.cpp @@ -40,6 +40,19 @@ using namespace Accounts; AccountModel::AccountModel( QObject* parent ) : QAbstractListModel( parent ) , m_waitingForAtticaLoaded( true ) +{ + tDebug() << "Creating AccountModel"; + if ( !AccountManager::instance()->isReady() ) + { + connect( AccountManager::instance(), SIGNAL( ready() ), SLOT( init() ) ); + } + else + init(); +} + + +void +AccountModel::init() { connect( AtticaManager::instance(), SIGNAL( resolversLoaded( Attica::Content::List ) ), this, SLOT( atticaLoaded() ) ); connect( AtticaManager::instance(), SIGNAL( startedInstalling( QString ) ), this, SLOT( onStartedInstalling( QString ) ) ); diff --git a/src/libtomahawk/accounts/AccountModel.h b/src/libtomahawk/accounts/AccountModel.h index d8c69d6c3..02e38959f 100644 --- a/src/libtomahawk/accounts/AccountModel.h +++ b/src/libtomahawk/accounts/AccountModel.h @@ -100,6 +100,8 @@ signals: void errorInstalling( const QPersistentModelIndex& idx ); private slots: + void init(); + void atticaLoaded(); void loadData();