1
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
3
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
4
* Copyright 2012 Leo Franchi <lfranchi@kde.org>
5
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
7
* Tomahawk is free software: you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation, either version 3 of the License, or
10
* (at your option) any later version.
12
* Tomahawk is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
21
#include <QCoreApplication>
23
#include "InfoSystem.h"
24
#include "TomahawkSettings.h"
25
#include "InfoSystemCache.h"
26
#include "InfoSystemWorker.h"
27
#include "utils/TomahawkUtils.h"
28
#include "utils/Logger.h"
37
static const int DEFAULT_TIMEOUT_MILLIS = 10000;
39
InfoRequestData::InfoRequestData()
40
: requestId( TomahawkUtils::infosystemRequestId() )
42
init( QString() , Tomahawk::InfoSystem::InfoNoInfo, QVariant(), QVariantMap() );
46
InfoRequestData::InfoRequestData( const quint64 rId, const QString& callr, const InfoType typ, const QVariant& inputvar, const QVariantMap& custom )
49
init( callr, typ, inputvar, custom );
54
InfoRequestData::init( const QString& callr, const InfoType typ, const QVariant& inputvar, const QVariantMap& custom )
56
internalId = TomahawkUtils::infosystemRequestId();
61
timeoutMillis = DEFAULT_TIMEOUT_MILLIS;
66
InfoPlugin::InfoPlugin()
71
InfoPlugin::~InfoPlugin()
75
InfoSystem* InfoSystem::s_instance = 0;
78
InfoSystem::instance()
81
s_instance = new InfoSystem( 0 );
87
InfoSystem::InfoSystem( QObject *parent )
90
, m_infoSystemCacheThreadController( 0 )
91
, m_infoSystemWorkerThreadController( 0 )
95
qDebug() << Q_FUNC_INFO;
97
m_infoSystemCacheThreadController = new InfoSystemCacheThread( this );
98
m_infoSystemCacheThreadController->start( QThread::IdlePriority );
100
m_infoSystemWorkerThreadController = new InfoSystemWorkerThread( this );
101
m_infoSystemWorkerThreadController->start();
103
QTimer::singleShot( 0, this, SLOT( init() ) );
107
InfoSystem::~InfoSystem()
109
tDebug() << Q_FUNC_INFO << " beginning";
111
if ( m_infoSystemWorkerThreadController )
113
m_infoSystemWorkerThreadController->quit();
114
m_infoSystemWorkerThreadController->wait( 60000 );
116
delete m_infoSystemWorkerThreadController;
117
m_infoSystemWorkerThreadController = 0;
119
tDebug() << Q_FUNC_INFO << " done deleting worker";
121
if( m_infoSystemCacheThreadController )
123
m_infoSystemCacheThreadController->quit();
124
m_infoSystemCacheThreadController->wait( 60000 );
126
delete m_infoSystemCacheThreadController;
127
m_infoSystemCacheThreadController = 0;
130
tDebug() << Q_FUNC_INFO << " done deleting cache";
137
tDebug() << Q_FUNC_INFO;
141
if ( !m_infoSystemCacheThreadController->cache() || !m_infoSystemWorkerThreadController->worker() )
143
QTimer::singleShot( 0, this, SLOT( init() ) );
147
Tomahawk::InfoSystem::InfoSystemCache* cache = m_infoSystemCacheThreadController->cache();
148
Tomahawk::InfoSystem::InfoSystemWorker* worker = m_infoSystemWorkerThreadController->worker();
150
connect( cache, SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
151
worker, SLOT( infoSlot( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection );
153
connect( worker, SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
154
this, SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ), Qt::UniqueConnection );
156
connect( worker, SIGNAL( finished( QString ) ), this, SIGNAL( finished( QString ) ), Qt::UniqueConnection );
158
connect( worker, SIGNAL( finished( QString, Tomahawk::InfoSystem::InfoType ) ),
159
this, SIGNAL( finished( QString, Tomahawk::InfoSystem::InfoType ) ), Qt::UniqueConnection );
161
qRegisterMetaType< Tomahawk::InfoSystem::InfoTypeSet >();
162
connect( worker, SIGNAL( updatedSupportedGetTypes( Tomahawk::InfoSystem::InfoTypeSet ) ),
163
this, SLOT( receiveUpdatedSupportedGetTypes( Tomahawk::InfoSystem::InfoTypeSet ) ) );
164
connect( worker, SIGNAL( updatedSupportedPushTypes( Tomahawk::InfoSystem::InfoTypeSet ) ),
165
this, SLOT( receiveUpdatedSupportedPushTypes( Tomahawk::InfoSystem::InfoTypeSet ) ) );
167
QMetaObject::invokeMethod( worker, "init", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoSystemCache*, cache ) );
174
InfoSystem::getInfo( const InfoRequestData &requestData )
176
//qDebug() << Q_FUNC_INFO;
177
if ( !m_inited || !m_infoSystemWorkerThreadController->worker() )
182
QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "getInfo", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoRequestData, requestData ) );
188
InfoSystem::getInfo( const QString &caller, const QVariantMap &customData, const InfoTypeMap &inputMap, const InfoTimeoutMap &timeoutMap, bool allSources )
190
if ( !m_inited || !m_infoSystemWorkerThreadController->worker() )
195
InfoRequestData requestData;
196
requestData.caller = caller;
197
requestData.customData = customData;
198
requestData.allSources = allSources;
199
Q_FOREACH( InfoType type, inputMap.keys() )
201
requestData.type = type;
202
requestData.input = inputMap[ type ];
203
requestData.timeoutMillis = timeoutMap.contains( type ) ? timeoutMap[ type ] : DEFAULT_TIMEOUT_MILLIS;
204
QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "getInfo", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoRequestData, requestData ) );
211
InfoSystem::pushInfo( InfoPushData pushData )
213
tDebug() << Q_FUNC_INFO << "type is " << pushData.type;
214
if ( !m_inited || !m_infoSystemWorkerThreadController->worker() )
220
PushInfoPair pushInfoPair( QVariantMap(), pushData.input );
221
pushData.infoPair = pushInfoPair;
222
QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "pushInfo", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoPushData, pushData ) );
229
InfoSystem::pushInfo( const QString &caller, const InfoTypeMap &input, const PushInfoFlags pushFlags )
231
if ( !m_inited || !m_infoSystemWorkerThreadController->worker() )
237
Q_FOREACH( InfoType type, input.keys() )
239
InfoPushData pushData( caller, type, input[ type ], pushFlags );
240
pushData.infoPair = PushInfoPair( QVariantMap(), pushData.input );
241
QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "pushInfo", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoPushData, pushData ) );
249
InfoSystem::addInfoPlugin( Tomahawk::InfoSystem::InfoPluginPtr plugin )
251
// Init is not complete (waiting for worker thread to start and create worker object) so keep trying till then
252
if ( !m_inited || !m_infoSystemWorkerThreadController->worker() )
254
QMetaObject::invokeMethod( this, "addInfoPlugin", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoPluginPtr, plugin ) );
258
if ( plugin.isNull() )
260
tDebug() << Q_FUNC_INFO << "Given plugin is null!";
264
if ( plugin.data()->thread() != m_infoSystemWorkerThreadController->worker()->thread() )
267
tDebug() << Q_FUNC_INFO << "The object must be moved to the worker thread first, see InfoSystem::workerThread()";
271
tDebug() << Q_FUNC_INFO << plugin.data();
272
QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "addInfoPlugin", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoPluginPtr, plugin ) );
277
InfoSystem::removeInfoPlugin( Tomahawk::InfoSystem::InfoPluginPtr plugin )
279
// Init is not complete (waiting for worker th read to start and create worker object) so keep trying till then
280
if ( !m_inited || !m_infoSystemWorkerThreadController->worker() )
282
QMetaObject::invokeMethod( this, "removeInfoPlugin", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoPluginPtr, plugin ) );
286
if ( plugin.isNull() )
288
tDebug() << Q_FUNC_INFO << "Given plugin is null!";
292
if ( plugin.data()->thread() != m_infoSystemWorkerThreadController->worker()->thread() )
294
tDebug() << Q_FUNC_INFO << "The object must be moved to the worker thread first, see InfoSystem::workerThread()";
298
tDebug() << Q_FUNC_INFO << plugin.data();
299
QMetaObject::invokeMethod( m_infoSystemWorkerThreadController->worker(), "removeInfoPlugin", Qt::QueuedConnection, Q_ARG( Tomahawk::InfoSystem::InfoPluginPtr, plugin ) );
304
InfoSystem::receiveUpdatedSupportedGetTypes( InfoTypeSet supportedTypes )
306
m_supportedGetTypes = supportedTypes;
307
emit updatedSupportedGetTypes( m_supportedGetTypes );
312
InfoSystem::receiveUpdatedSupportedPushTypes( InfoTypeSet supportedTypes )
314
m_supportedPushTypes = supportedTypes;
315
emit updatedSupportedPushTypes( m_supportedPushTypes );
319
QWeakPointer< QThread >
320
InfoSystem::workerThread() const
322
if ( m_infoSystemWorkerThreadController->isRunning() && m_infoSystemWorkerThreadController->worker() )
323
return QWeakPointer< QThread >( m_infoSystemWorkerThreadController->worker()->thread() );
325
return QWeakPointer< QThread >();
329
InfoSystemCacheThread::InfoSystemCacheThread( QObject *parent )
332
tDebug() << Q_FUNC_INFO;
336
InfoSystemCacheThread::~InfoSystemCacheThread()
338
tDebug() << Q_FUNC_INFO;
343
InfoSystemCacheThread::InfoSystemCacheThread::run()
345
m_cache = QWeakPointer< InfoSystemCache >( new InfoSystemCache() );
347
if ( !m_cache.isNull() )
348
delete m_cache.data();
353
InfoSystemCacheThread::cache() const
355
if ( m_cache.isNull() )
357
return m_cache.data();
361
InfoSystemWorkerThread::InfoSystemWorkerThread( QObject *parent )
364
tDebug() << Q_FUNC_INFO;
367
InfoSystemWorkerThread::~InfoSystemWorkerThread()
369
tDebug() << Q_FUNC_INFO;
373
InfoSystemWorkerThread::InfoSystemWorkerThread::run()
375
m_worker = QWeakPointer< InfoSystemWorker >( new InfoSystemWorker() );
377
if( !m_worker.isNull() )
378
delete m_worker.data();
382
InfoSystemWorkerThread::worker() const
384
if ( m_worker.isNull() )
386
return m_worker.data();
390
} //namespace InfoSystem
392
} //namespace Tomahawk