1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-07-31 03:10:12 +02:00

Load chart data objects in a thread, as they call synchronous db methods

This commit is contained in:
Leo Franchi
2011-12-23 08:00:25 -06:00
parent c4c74d84dc
commit 3987ce7690
7 changed files with 243 additions and 36 deletions

View File

@@ -119,6 +119,7 @@ set( libGuiSources
widgets/playlisttypeselectordlg.cpp
widgets/welcomewidget.cpp
widgets/whatshotwidget.cpp
widgets/ChartDataLoader.cpp
widgets/RecentlyPlayedPlaylistsModel.cpp
widgets/RecentPlaylistsModel.cpp
widgets/OverlayButton.cpp
@@ -237,6 +238,7 @@ set( libGuiHeaders
widgets/welcomewidget.h
widgets/whatshotwidget.h
widgets/whatshotwidget_p.h
widgets/ChartDataLoader.h
widgets/RecentlyPlayedPlaylistsModel.h
widgets/RecentPlaylistsModel.h
widgets/OverlayButton.h

View File

@@ -453,7 +453,7 @@ ChartsPlugin::chartReturned()
QVariantList chartResponse = res.value( "list" ).toList();
QList< Tomahawk::InfoSystem::InfoStringHash > top_tracks;
QList< Tomahawk::InfoSystem::InfoStringHash > top_albums;
QStringList top_artists;
QList< Tomahawk::InfoSystem::InfoStringHash > top_artists;
/// Deside what type, we need to handle it differently
/// @todo: We allready know the type, append it to breadcrumb hash
@@ -528,7 +528,9 @@ ChartsPlugin::chartReturned()
}
else
{
top_artists.append( artist );
Tomahawk::InfoSystem::InfoStringHash artistHash;
artistHash["artist"] = artist;
top_artists.append( artistHash );
}
}
@@ -538,7 +540,7 @@ ChartsPlugin::chartReturned()
if( chartType() == Artist )
{
tDebug() << "ChartsPlugin:" << "\tgot " << top_artists.size() << " artists";
returnedData[ "artists" ] = QVariant::fromValue< QStringList >( top_artists );
returnedData[ "artists" ] = QVariant::fromValue< QList< Tomahawk::InfoSystem::InfoStringHash > >( top_artists );
returnedData[ "type" ] = "artists";
}

View File

@@ -0,0 +1,72 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
*
* Tomahawk 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 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ChartDataLoader.h"
using namespace Tomahawk;
ChartDataLoader::ChartDataLoader()
: QObject( 0 )
{
}
void
ChartDataLoader::go()
{
qDebug() << "CHART LOADING DATA!" << QThread::currentThreadId();
switch ( m_type )
{
case Track:
{
QList< query_ptr > track_ptrs;
foreach ( const Tomahawk::InfoSystem::InfoStringHash& track, m_data )
{
track_ptrs << Query::get( track[ "artist" ], track[ "track" ], QString(), uuid(), false );
}
emit tracks( this, track_ptrs );
break;
}
case Artist:
{
QList< artist_ptr > artist_ptrs;
foreach ( const Tomahawk::InfoSystem::InfoStringHash& artistname, m_data ) {
artist_ptrs << Artist::get( artistname[ "artist" ], false );
}
emit artists( this, artist_ptrs );
break;
}
case Album:
{
QList< album_ptr > album_ptrs;
foreach ( const Tomahawk::InfoSystem::InfoStringHash& album, m_data )
{
tDebug( LOGVERBOSE) << Q_FUNC_INFO << "Getting album" << album[ "album" ] << "By" << album[ "artist" ];
artist_ptr artistPtr = Artist::get( album[ "artist" ], false );
album_ptr albumPtr = Album::get( artistPtr, album[ "album" ], false );
album_ptrs << albumPtr;
}
emit albums( this, album_ptrs );
break;
}
}
}

View File

@@ -0,0 +1,67 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
*
* Tomahawk 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 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CHARTDATALOADER_H
#define CHARTDATALOADER_H
#include "infosystem/infosystem.h"
#include "query.h"
#include "artist.h"
#include "album.h"
#include <QObject>
namespace Tomahawk
{
/**
Synchronous loading of track, artist, album objects from the db
into their respective tomahawk types. Move this object to a thread
and listen to the result signals.
*/
class ChartDataLoader : public QObject
{
Q_OBJECT
public:
enum DataType {
Track,
Artist,
Album
};
ChartDataLoader();
void setType( DataType type ) { m_type = type; }
void setData( const QList< InfoSystem::InfoStringHash >& data ) { m_data = data; }
public slots:
void go();
signals:
void tracks( Tomahawk::ChartDataLoader*, const QList< Tomahawk::query_ptr >& tracks );
void artists( Tomahawk::ChartDataLoader*, const QList< Tomahawk::artist_ptr >& artists );
void albums( Tomahawk::ChartDataLoader*, const QList< Tomahawk::album_ptr >& albums );
private:
DataType m_type;
QList<InfoSystem::InfoStringHash> m_data;
};
}
#endif // CHARTDATALOADER_H

View File

@@ -29,6 +29,7 @@
#include "sourcelist.h"
#include "tomahawksettings.h"
#include "RecentPlaylistsModel.h"
#include "ChartDataLoader.h"
#include "audio/audioengine.h"
#include "dynamic/GeneratorInterface.h"
@@ -53,6 +54,7 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent )
, ui( new Ui::WhatsHotWidget )
, m_playlistInterface( 0 )
, m_sortedProxy( 0 )
, m_workerThread( 0 )
{
ui->setupUi( this );
@@ -94,6 +96,9 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent )
m_playlistInterface = new ChartsPlaylistInterface( this );
m_workerThread = new QThread( this );
m_workerThread->start();
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
@@ -106,6 +111,7 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent )
WhatsHotWidget::~WhatsHotWidget()
{
m_workerThread->exit(0);
delete m_playlistInterface;
delete ui;
}
@@ -239,68 +245,61 @@ WhatsHotWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestDat
const QString chartId = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >().value( "chart_id" );
m_queuedFetches.remove( chartId );
if( type == "artists" )
ChartDataLoader* loader = new ChartDataLoader();
loader->setProperty( "chartid", chartId );
loader->moveToThread( m_workerThread );
qDebug() << "SCHEDULING LOADING FROM THREAD:" << QThread::currentThreadId();
if ( type == "artists" )
{
const QStringList artists = returnedData["artists"].toStringList();
loader->setType( ChartDataLoader::Artist );
loader->setData( returnedData[ "artists" ].value< QList< Tomahawk::InfoSystem::InfoStringHash > >() );
connect( loader, SIGNAL( artists( Tomahawk::ChartDataLoader*, QList< Tomahawk::artist_ptr > ) ), this, SLOT( chartArtistsLoaded( Tomahawk::ChartDataLoader*, QList< Tomahawk::artist_ptr > ) ) );
TreeModel* artistsModel = new TreeModel( ui->artistsViewLeft );
artistsModel->setColumnStyle( TreeModel::TrackOnly );
foreach ( const QString& artist, artists )
{
artist_ptr artistPtr = Artist::get( artist, false );
artistsModel->addArtists( artistPtr );
}
m_artistModels[ chartId ] = artistsModel;
if ( m_queueItemToShow == chartId )
setLeftViewArtists( artistsModel );
}
else if( type == "albums" )
else if ( type == "albums" )
{
QList<album_ptr> al;
const QList< Tomahawk::InfoSystem::InfoStringHash > albums = returnedData[ "albums" ].value< QList< Tomahawk::InfoSystem::InfoStringHash > >();
loader->setType( ChartDataLoader::Album );
loader->setData( returnedData[ "albums" ].value< QList< Tomahawk::InfoSystem::InfoStringHash > >() );
connect( loader, SIGNAL( albums( Tomahawk::ChartDataLoader*, QList< Tomahawk::album_ptr > ) ), this, SLOT( chartAlbumsLoaded( Tomahawk::ChartDataLoader*, QList< Tomahawk::album_ptr > ) ) );
AlbumModel* albumModel = new AlbumModel( ui->additionsView );
foreach ( const Tomahawk::InfoSystem::InfoStringHash& album, albums )
{
tDebug( LOGVERBOSE) << Q_FUNC_INFO << "Getting album" << album[ "album" ] << "By" << album[ "artist" ];
artist_ptr artistPtr = Artist::get( album[ "artist" ], false );
album_ptr albumPtr = Album::get( artistPtr, album[ "album" ], false );
al << albumPtr;
}
albumModel->addAlbums( al );
m_albumModels[ chartId ] = albumModel;
if ( m_queueItemToShow == chartId )
setLeftViewAlbums( albumModel );
}
else if( type == "tracks" )
else if ( type == "tracks" )
{
const QList< Tomahawk::InfoSystem::InfoStringHash > tracks = returnedData[ "tracks" ].value< QList< Tomahawk::InfoSystem::InfoStringHash > >();
loader->setType( ChartDataLoader::Track );
loader->setData( returnedData[ "tracks" ].value< QList< Tomahawk::InfoSystem::InfoStringHash > >() );
connect( loader, SIGNAL( tracks( Tomahawk::ChartDataLoader*, QList< Tomahawk::query_ptr > ) ), this, SLOT( chartTracksLoaded( Tomahawk::ChartDataLoader*, QList< Tomahawk::query_ptr > ) ) );
PlaylistModel* trackModel = new PlaylistModel( ui->tracksViewLeft );
trackModel->setStyle( TrackModel::Short );
QList<query_ptr> tracklist;
foreach ( const Tomahawk::InfoSystem::InfoStringHash& track, tracks )
{
query_ptr query = Query::get( track[ "artist" ], track[ "track" ], QString(), uuid(), false );
tracklist << query;
}
Pipeline::instance()->resolve( tracklist );
trackModel->append( tracklist );
m_trackModels[ chartId ] = trackModel;
if ( m_queueItemToShow == chartId )
setLeftViewTracks( trackModel );
}
else
{
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "WhatsHot: got unknown chart type" << type;
}
QMetaObject::invokeMethod( loader, "go", Qt::QueuedConnection );
break;
}
@@ -473,3 +472,52 @@ WhatsHotWidget::setLeftViewTracks( PlaylistModel* model )
ui->tracksViewLeft->proxyModel()->sort( -1 );
ui->stackLeft->setCurrentIndex( 0 );
}
void
WhatsHotWidget::chartArtistsLoaded( ChartDataLoader* loader, const QList< artist_ptr >& artists )
{
qDebug() << "DOING CHART ARTIST DATA LOAD!";
QString chartId = loader->property( "chartid" ).toString();
Q_ASSERT( m_artistModels.contains( chartId ) );
if ( !m_artistModels.contains( chartId ) )
{
foreach( const artist_ptr& artist, artists )
m_artistModels[ chartId ]->addArtists( artist );
}
loader->deleteLater();
}
void
WhatsHotWidget::chartTracksLoaded( ChartDataLoader* loader, const QList< query_ptr >& tracks )
{
qDebug() << "DOING CHART TRACK DATA LOAD!";
QString chartId = loader->property( "chartid" ).toString();
Q_ASSERT( m_trackModels.contains( chartId ) );
if ( m_trackModels.contains( chartId ) )
{
Pipeline::instance()->resolve( tracks );
m_trackModels[ chartId ]->append( tracks );
}
loader->deleteLater();
}
void
WhatsHotWidget::chartAlbumsLoaded( ChartDataLoader* loader, const QList< album_ptr >& albums )
{
qDebug() << "DOING CHART ALBUMS DATA LOAD!";
QString chartId = loader->property( "chartid" ).toString();
Q_ASSERT( m_albumModels.contains( chartId ) );
if ( m_albumModels.contains( chartId ) )
m_albumModels[ chartId ]->addAlbums( albums );
loader->deleteLater();
}

View File

@@ -46,6 +46,11 @@ namespace Ui
class WhatsHotWidget;
}
namespace Tomahawk
{
class ChartDataLoader;
}
/**
* \class
* \brief The tomahawk page that shows music charts.
@@ -83,6 +88,11 @@ private slots:
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
void infoSystemFinished( QString target );
void leftCrumbIndexChanged( QModelIndex );
void chartArtistsLoaded( Tomahawk::ChartDataLoader*, const QList< Tomahawk::artist_ptr >& );
void chartAlbumsLoaded( Tomahawk::ChartDataLoader*, const QList< Tomahawk::album_ptr >& );
void chartTracksLoaded( Tomahawk::ChartDataLoader*, const QList< Tomahawk::query_ptr >& );
private:
void setLeftViewArtists( TreeModel* artistModel );
void setLeftViewAlbums( AlbumModel* albumModel );
@@ -96,6 +106,11 @@ private:
QStandardItemModel* m_crumbModelLeft;
QSortFilterProxyModel* m_sortedProxy;
// Load artist, album, and track objects in a thread
// {Artist,Album,Track}::get() calls are all synchronous db calls
// and we don't want to lock up out UI in case the db is busy (e.g. on startup)
QThread* m_workerThread;
// Cache our model data
QHash< QString, AlbumModel* > m_albumModels;
QHash< QString, TreeModel* > m_artistModels;

View File

@@ -175,6 +175,7 @@
NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier];
OSStatus httpResult = LSSetDefaultHandlerForURLScheme((CFStringRef)@"tomahawk", (CFStringRef)bundleID);
Q_UNUSED(httpResult);
//TODO: Check httpResult and httpsResult for errors
}
return self;