Browse files

Return IODevices for track URLs through callbacks.

  • Loading branch information...
1 parent 20bfb48 commit 230fbdcef9de35a008549d0a18df461484ce5f24 @teo teo committed Mar 14, 2013
View
56 src/libtomahawk/audio/AudioEngine.cpp
@@ -2,6 +2,7 @@
*
* Copyright 2010-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
+ * Copyright 2013, Teo Mrnjavac <teo@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
@@ -39,6 +40,8 @@
#include "utils/Logger.h"
#include "playlist/SingleTrackPlaylistInterface.h"
+#include <boost/bind.hpp>
+
#include <QtCore/QUrl>
#include <QDir>
#include <QtNetwork/QNetworkReply>
@@ -430,30 +433,43 @@ AudioEngine::onNowPlayingInfoReady( const Tomahawk::InfoSystem::InfoType type )
}
-bool
+void
AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
{
- bool err = false;
+ if ( result.isNull() )
{
- QSharedPointer<QIODevice> io;
+ stop();
+ return;
+ }
- if ( result.isNull() )
- err = true;
- else
- {
- setCurrentTrack( result );
+ setCurrentTrack( result );
- if ( !TomahawkUtils::isHttpResult( m_currentTrack->url() ) &&
- !TomahawkUtils::isLocalResult( m_currentTrack->url() ) )
- {
- io = Servent::instance()->getIODeviceForUrl( m_currentTrack );
+ if ( !TomahawkUtils::isHttpResult( m_currentTrack->url() ) &&
+ !TomahawkUtils::isLocalResult( m_currentTrack->url() ) )
+ {
+ boost::function< void ( QSharedPointer< QIODevice >& ) > callback =
+ boost::bind( &AudioEngine::performLoadTrack, this, result, _1 );
+ Servent::instance()->getIODeviceForUrl( m_currentTrack, callback );
+ }
+ else
+ {
+ QSharedPointer< QIODevice > io;
+ performLoadTrack( result, io );
+ }
+}
- if ( !io || io.isNull() )
- {
- tLog() << "Error getting iodevice for" << result->url();
- err = true;
- }
- }
+
+void
+AudioEngine::performLoadTrack( const Tomahawk::result_ptr& result, QSharedPointer< QIODevice >& io )
+{
+ bool err = false;
+ {
+ if ( !TomahawkUtils::isHttpResult( m_currentTrack->url() ) &&
+ !TomahawkUtils::isLocalResult( m_currentTrack->url() ) &&
+ ( !io || io.isNull() ) )
+ {
+ tLog() << "Error getting iodevice for" << result->url();
+ err = true;
}
if ( !err )
@@ -520,11 +536,11 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
if ( err )
{
stop();
- return false;
+ return;
}
m_waitingOnNewTrack = false;
- return true;
+ return;
}
View
4 src/libtomahawk/audio/AudioEngine.h
@@ -2,6 +2,7 @@
*
* Copyright 2010-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
+ * Copyright 2013, Teo Mrnjavac <teo@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
@@ -128,7 +129,8 @@ public slots:
void error( AudioEngine::AudioErrorCode errorCode );
private slots:
- bool loadTrack( const Tomahawk::result_ptr& result );
+ void loadTrack( const Tomahawk::result_ptr& result ); //async!
+ void performLoadTrack( const Tomahawk::result_ptr& result, QSharedPointer< QIODevice >& io ); //only call from loadTrack kthxbi
void loadPreviousTrack();
void loadNextTrack();
View
63 src/libtomahawk/network/Servent.cpp
@@ -2,6 +2,7 @@
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
+ * Copyright 2013, Teo Mrnjavac <teo@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
@@ -75,17 +76,18 @@ Servent::Servent( QObject* parent )
setProxy( QNetworkProxy::NoProxy );
{
- boost::function<QSharedPointer<QIODevice>(result_ptr)> fac = boost::bind( &Servent::localFileIODeviceFactory, this, _1 );
+ // _1 = result, _2 = callback function for IODevice
+ IODeviceFactoryFunc fac = boost::bind( &Servent::localFileIODeviceFactory, this, _1, _2 );
this->registerIODeviceFactory( "file", fac );
}
{
- boost::function<QSharedPointer<QIODevice>(result_ptr)> fac = boost::bind( &Servent::remoteIODeviceFactory, this, _1 );
+ IODeviceFactoryFunc fac = boost::bind( &Servent::remoteIODeviceFactory, this, _1, _2 );
this->registerIODeviceFactory( "servent", fac );
}
{
- boost::function<QSharedPointer<QIODevice>(result_ptr)> fac = boost::bind( &Servent::httpIODeviceFactory, this, _1 );
+ IODeviceFactoryFunc fac = boost::bind( &Servent::httpIODeviceFactory, this, _1, _2 );
this->registerIODeviceFactory( "http", fac );
this->registerIODeviceFactory( "https", fac );
}
@@ -944,8 +946,9 @@ Servent::claimOffer( ControlConnection* cc, const QString &nodeid, const QString
}
-QSharedPointer<QIODevice>
-Servent::remoteIODeviceFactory( const result_ptr& result )
+void
+Servent::remoteIODeviceFactory( const Tomahawk::result_ptr& result,
+ boost::function< void ( QSharedPointer< QIODevice >& ) > callback )
{
QSharedPointer<QIODevice> sp;
@@ -954,12 +957,18 @@ Servent::remoteIODeviceFactory( const result_ptr& result )
const QString fileId = parts.at( 1 );
source_ptr s = SourceList::instance()->get( sourceName );
if ( s.isNull() || !s->controlConnection() )
- return sp;
+ {
+ callback( sp );
+ return;
+ }
ControlConnection* cc = s->controlConnection();
StreamConnection* sc = new StreamConnection( this, cc, fileId, result );
createParallelConnection( cc, sc, QString( "FILE_REQUEST_KEY:%1" ).arg( fileId ) );
- return sc->iodevice();
+
+ //boost::functions cannot accept temporaries as parameters
+ sp = sc->iodevice();
+ callback( sp );
}
@@ -1066,45 +1075,61 @@ Servent::triggerDBSync()
void
-Servent::registerIODeviceFactory( const QString &proto, boost::function<QSharedPointer<QIODevice>(Tomahawk::result_ptr)> fac )
+Servent::registerIODeviceFactory( const QString &proto,
+ IODeviceFactoryFunc fac )
{
m_iofactories.insert( proto, fac );
}
-QSharedPointer<QIODevice>
-Servent::getIODeviceForUrl( const Tomahawk::result_ptr& result )
+void
+Servent::getIODeviceForUrl( const Tomahawk::result_ptr& result,
+ boost::function< void ( QSharedPointer< QIODevice >& ) > callback )
{
QSharedPointer<QIODevice> sp;
QRegExp rx( "^([a-zA-Z0-9]+)://(.+)$" );
if ( rx.indexIn( result->url() ) == -1 )
- return sp;
+ {
+ callback( sp );
+ return;
+ }
const QString proto = rx.cap( 1 );
if ( !m_iofactories.contains( proto ) )
- return sp;
+ {
+ callback( sp );
+ return;
+ }
- return m_iofactories.value( proto )( result );
+ //QtScriptResolverHelper::customIODeviceFactory is async!
+ m_iofactories.value( proto )( result, callback );
}
-QSharedPointer<QIODevice>
-Servent::localFileIODeviceFactory( const Tomahawk::result_ptr& result )
+void
+Servent::localFileIODeviceFactory( const Tomahawk::result_ptr& result,
+ boost::function< void ( QSharedPointer< QIODevice >& ) > callback )
{
// ignore "file://" at front of url
QFile* io = new QFile( result->url().mid( QString( "file://" ).length() ) );
if ( io )
io->open( QIODevice::ReadOnly );
- return QSharedPointer<QIODevice>( io );
+ //boost::functions cannot accept temporaries as parameters
+ QSharedPointer< QIODevice > sp = QSharedPointer<QIODevice>( io );
+ callback( sp );
}
-QSharedPointer<QIODevice>
-Servent::httpIODeviceFactory( const Tomahawk::result_ptr& result )
+void
+Servent::httpIODeviceFactory( const Tomahawk::result_ptr& result,
+ boost::function< void ( QSharedPointer< QIODevice >& ) > callback )
{
QNetworkRequest req( result->url() );
QNetworkReply* reply = TomahawkUtils::nam()->get( req );
- return QSharedPointer<QIODevice>( reply, &QObject::deleteLater );
+
+ //boost::functions cannot accept temporaries as parameters
+ QSharedPointer< QIODevice > sp = QSharedPointer< QIODevice >( reply, &QObject::deleteLater );
+ callback( sp );
}
View
16 src/libtomahawk/network/Servent.h
@@ -2,6 +2,7 @@
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
+ * Copyright 2013, Teo Mrnjavac <teo@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
@@ -54,6 +55,9 @@ class PortFwdThread;
class PeerInfo;
class SipInfo;
+typedef boost::function< void( const Tomahawk::result_ptr&,
+ boost::function< void( QSharedPointer< QIODevice >& ) > )> IODeviceFactoryFunc;
+
// this is used to hold a bit of state, so when a connected signal is emitted
// from a socket, we can associate it with a Connection object etc.
class DLLEXPORT QTcpSocketExtra : public QTcpSocket
@@ -121,18 +125,18 @@ public slots:
QString externalAddress() const { return !m_externalHostname.isNull() ? m_externalHostname : m_externalAddress.toString(); }
int externalPort() const { return m_externalPort; }
- QSharedPointer< QIODevice > remoteIODeviceFactory( const Tomahawk::result_ptr& );
static bool isIPWhitelisted( QHostAddress ip );
bool connectedToSession( const QString& session );
unsigned int numConnectedPeers() const { return m_controlconnections.length(); }
QList< StreamConnection* > streams() const { return m_scsessions; }
- QSharedPointer< QIODevice > getIODeviceForUrl( const Tomahawk::result_ptr& result );
- void registerIODeviceFactory( const QString &proto, boost::function< QSharedPointer< QIODevice >(Tomahawk::result_ptr) > fac );
- QSharedPointer< QIODevice > localFileIODeviceFactory( const Tomahawk::result_ptr& result );
- QSharedPointer< QIODevice > httpIODeviceFactory( const Tomahawk::result_ptr& result );
+ void getIODeviceForUrl( const Tomahawk::result_ptr& result, boost::function< void ( QSharedPointer< QIODevice >& ) > callback );
+ void registerIODeviceFactory( const QString &proto, IODeviceFactoryFunc fac );
+ void remoteIODeviceFactory( const Tomahawk::result_ptr& result, boost::function< void ( QSharedPointer< QIODevice >& ) > callback );
+ void localFileIODeviceFactory( const Tomahawk::result_ptr& result, boost::function< void ( QSharedPointer< QIODevice >& ) > callback );
+ void httpIODeviceFactory( const Tomahawk::result_ptr& result, boost::function< void ( QSharedPointer< QIODevice >& ) > callback );
bool isReady() const { return m_ready; };
@@ -184,7 +188,7 @@ private slots:
QList< StreamConnection* > m_scsessions;
QMutex m_ftsession_mut;
- QMap< QString,boost::function< QSharedPointer< QIODevice >(Tomahawk::result_ptr) > > m_iofactories;
+ QMap< QString, IODeviceFactoryFunc > m_iofactories;
QPointer< PortFwdThread > m_portfwd;
static Servent* s_instance;
View
20 src/libtomahawk/network/StreamConnection.cpp
@@ -2,6 +2,7 @@
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
+ * Copyright 2013, Teo Mrnjavac <teo@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
@@ -19,10 +20,7 @@
#include "StreamConnection.h"
-#include <QFile>
-
#include "Result.h"
-
#include "BufferIoDevice.h"
#include "network/ControlConnection.h"
#include "network/Servent.h"
@@ -31,6 +29,10 @@
#include "SourceList.h"
#include "utils/Logger.h"
+#include <boost/bind.hpp>
+
+#include <QFile>
+
using namespace Tomahawk;
@@ -179,8 +181,16 @@ StreamConnection::startSending( const Tomahawk::result_ptr& result )
m_result = result;
qDebug() << "Starting to transmit" << m_result->url();
- QSharedPointer<QIODevice> io = Servent::instance()->getIODeviceForUrl( m_result );
- if( !io )
+ boost::function< void ( QSharedPointer< QIODevice >& ) > callback =
+ boost::bind( &StreamConnection::reallyStartSending, this, result, _1 );
+ Servent::instance()->getIODeviceForUrl( m_result, callback );
+}
+
+
+void
+StreamConnection::reallyStartSending( const Tomahawk::result_ptr& result, QSharedPointer< QIODevice >& io )
+{
+ if( !io || io.isNull() )
{
qDebug() << "Couldn't read from source:" << m_result->url();
shutdown();
View
4 src/libtomahawk/network/StreamConnection.h
@@ -2,6 +2,7 @@
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
+ * Copyright 2013, Teo Mrnjavac <teo@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
@@ -71,7 +72,8 @@ protected slots:
virtual void handleMsg( msg_ptr msg );
private slots:
- void startSending( const Tomahawk::result_ptr& );
+ void startSending( const Tomahawk::result_ptr& result );
+ void reallyStartSending( const Tomahawk::result_ptr& result, QSharedPointer< QIODevice >& io ); //only called back from startSending
void sendSome();
void showStats( qint64 tx, qint64 rx );
View
21 src/libtomahawk/resolvers/QtScriptResolver.cpp
@@ -293,7 +293,9 @@ QtScriptResolverHelper::md5( const QByteArray& input )
void
QtScriptResolverHelper::addCustomUrlHandler( const QString& protocol, const QString& callbackFuncName )
{
- boost::function<QSharedPointer<QIODevice>(Tomahawk::result_ptr)> fac = boost::bind( &QtScriptResolverHelper::customIODeviceFactory, this, _1 );
+ boost::function< void( const Tomahawk::result_ptr&,
+ boost::function< void( QSharedPointer< QIODevice >& ) > )> fac =
+ boost::bind( &QtScriptResolverHelper::customIODeviceFactory, this, _1, _2 );
Servent::instance()->registerIODeviceFactory( protocol, fac );
m_urlCallback = callbackFuncName;
@@ -314,22 +316,31 @@ QtScriptResolverHelper::base64Decode( const QByteArray& input )
}
-QSharedPointer< QIODevice >
-QtScriptResolverHelper::customIODeviceFactory( const Tomahawk::result_ptr& result )
+void
+QtScriptResolverHelper::customIODeviceFactory( const Tomahawk::result_ptr& result,
+ boost::function< void( QSharedPointer< QIODevice >& ) > callback )
{
QString getUrl = QString( "Tomahawk.resolver.instance.%1( '%2' );" ).arg( m_urlCallback )
.arg( QString( QUrl( result->url() ).toEncoded() ) );
QString urlStr = m_resolver->m_engine->mainFrame()->evaluateJavaScript( getUrl ).toString();
+ QSharedPointer< QIODevice > sp;
if ( urlStr.isEmpty() )
- return QSharedPointer< QIODevice >();
+ {
+
+ callback( sp );
+ return;
+ }
QUrl url = QUrl::fromEncoded( urlStr.toUtf8() );
QNetworkRequest req( url );
tDebug() << "Creating a QNetowrkReply with url:" << req.url().toString();
QNetworkReply* reply = TomahawkUtils::nam()->get( req );
- return QSharedPointer<QIODevice>( reply, &QObject::deleteLater );
+
+ //boost::functions cannot accept temporaries as parameters
+ sp = QSharedPointer< QIODevice >( reply, &QObject::deleteLater );
+ callback( sp );
}
View
3 src/libtomahawk/resolvers/QtScriptResolver.h
@@ -59,7 +59,8 @@ Q_OBJECT
Q_INVOKABLE QByteArray base64Encode( const QByteArray& input );
Q_INVOKABLE QByteArray base64Decode( const QByteArray& input );
- QSharedPointer<QIODevice> customIODeviceFactory( const Tomahawk::result_ptr& result );
+ void customIODeviceFactory( const Tomahawk::result_ptr& result,
+ boost::function< void( QSharedPointer< QIODevice >& ) > callback ); // async
public slots:
QByteArray readRaw( const QString& fileName );
View
15 src/web/Api_v1.cpp
@@ -3,6 +3,7 @@
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
+ * Copyright 2013, Teo Mrnjavac <teo@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
@@ -30,6 +31,8 @@
#include "Pipeline.h"
#include "Source.h"
+#include <boost/bind.hpp>
+
#include <QHash>
@@ -189,8 +192,16 @@ Api_v1::sid( QxtWebRequestEvent* event, QString unused )
return send404( event );
}
- QSharedPointer<QIODevice> iodev = Servent::instance()->getIODeviceForUrl( rp );
- if ( iodev.isNull() )
+ boost::function< void ( QSharedPointer< QIODevice >& ) > callback =
+ boost::bind( &Api_v1::processSid, this, event, rp, _1 );
+ Servent::instance()->getIODeviceForUrl( rp, callback );
+}
+
+
+void
+Api_v1::processSid( QxtWebRequestEvent* event, Tomahawk::result_ptr& rp, QSharedPointer< QIODevice >& iodev )
+{
+ if ( !iodev || iodev.isNull() )
{
return send404( event ); // 503?
}
View
8 src/web/Api_v1.h
@@ -2,6 +2,7 @@
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
+ * Copyright 2013, Teo Mrnjavac <teo@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
@@ -36,6 +37,12 @@
#include <QSharedPointer>
#include <QStringList>
+namespace Tomahawk
+{
+ class Result;
+ typedef QSharedPointer< Result > result_ptr;
+}
+
class Api_v1 : public QxtWebSlotService
{
Q_OBJECT
@@ -70,6 +77,7 @@ public slots:
void index( QxtWebRequestEvent* event );
private:
+ void processSid( QxtWebRequestEvent* event, Tomahawk::result_ptr&, QSharedPointer< QIODevice >& );
QxtWebRequestEvent* m_storedEvent;
};

0 comments on commit 230fbdc

Please sign in to comment.