From 5cde25cefed51a6a5cec13303617724764dfbca3 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 2 Apr 2011 10:24:48 +0200 Subject: [PATCH] * Properly thread QtScriptResolver. --- src/resolvers/qtscriptresolver.cpp | 126 +++++++++++++++++++++-------- src/resolvers/qtscriptresolver.h | 39 +++++++-- 2 files changed, 125 insertions(+), 40 deletions(-) diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index d4c0cc5f5..a19147b14 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -27,19 +27,86 @@ QtScriptResolver::QtScriptResolver( const QString& scriptPath ) : Tomahawk::ExternalResolver( scriptPath ) - , m_engine( new ScriptEngine( this ) ) - , m_thread( new QThread( this ) ) , m_ready( false ) , m_stopped( false ) { qDebug() << Q_FUNC_INFO << scriptPath; + m_thread = new ScriptThread( scriptPath, this ); + connect( m_thread, SIGNAL( engineFound( QString, unsigned int, unsigned int, unsigned int ) ), + SLOT( onEngineFound( QString, unsigned int, unsigned int, unsigned int ) ) ); + m_thread->start(); - QFile scriptFile( scriptPath ); + connect( this, SIGNAL( destroyed( QObject* ) ), m_thread, SLOT( deleteLater() ) ); +} + + +QtScriptResolver::~QtScriptResolver() +{ + Tomahawk::Pipeline::instance()->removeResolver( this ); + delete m_thread; +} + + +void +QtScriptResolver::resolve( const Tomahawk::query_ptr& query ) +{ + m_thread->resolve( query ); +} + + +void +QtScriptResolver::onEngineFound( const QString& name, unsigned int weight, unsigned int timeout, unsigned int preference ) +{ + m_name = name; + m_weight = weight; + m_timeout = timeout; + m_preference = preference; + + qDebug() << "QTSCRIPT" << filePath() << "READY," << endl + << "name" << m_name << endl + << "weight" << m_weight << endl + << "timeout" << m_timeout << endl + << "preference" << m_preference; + + m_ready = true; + Tomahawk::Pipeline::instance()->addResolver( this ); +} + + +ScriptThread::ScriptThread( const QString& scriptPath, QtScriptResolver* parent ) + : QThread() + , m_parent( parent ) + , m_scriptPath( scriptPath ) +{ + moveToThread( this ); +} + + +void +ScriptThread::resolve( const Tomahawk::query_ptr& query ) +{ + m_engine->resolve( query ); +} + + +void +ScriptThread::run() +{ + QTimer::singleShot( 0, this, SLOT( initEngine() ) ); + exec(); +} + + +void +ScriptThread::initEngine() +{ + m_engine = new ScriptEngine( m_parent, this ); + QFile scriptFile( m_scriptPath ); if ( !scriptFile.open( QIODevice::ReadOnly ) ) { - qDebug() << Q_FUNC_INFO << "Failed loading JavaScript resolver:" << scriptPath; + qDebug() << Q_FUNC_INFO << "Failed loading JavaScript resolver:" << m_scriptPath; deleteLater(); return; } @@ -48,43 +115,32 @@ QtScriptResolver::QtScriptResolver( const QString& scriptPath ) m_engine->mainFrame()->evaluateJavaScript( scriptFile.readAll() ); scriptFile.close(); + QString name; + unsigned int weight, preference, timeout; QVariantMap m = m_engine->mainFrame()->evaluateJavaScript( "getSettings();" ).toMap(); - m_name = m.value( "name" ).toString(); - m_weight = m.value( "weight", 0 ).toUInt(); - m_timeout = m.value( "timeout", 25 ).toUInt() * 1000; - m_preference = m.value( "preference", 0 ).toUInt(); + name = m.value( "name" ).toString(); + weight = m.value( "weight", 0 ).toUInt(); + timeout = m.value( "timeout", 25 ).toUInt() * 1000; + preference = m.value( "preference", 0 ).toUInt(); - qDebug() << "QTSCRIPT" << filePath() << "READY," << endl - << "name" << m_name << endl - << "weight" << m_weight << endl - << "timeout" << m_timeout << endl - << "preference" << m_preference; - - m_engine->moveToThread( m_thread ); - m_ready = true; - Tomahawk::Pipeline::instance()->addResolver( this ); - - connect( this, SIGNAL( destroyed( QObject* ) ), m_thread, SLOT( deleteLater() ) ); -} - - -QtScriptResolver::~QtScriptResolver() -{ - Tomahawk::Pipeline::instance()->removeResolver( this ); - delete m_engine; -} - - -void -QtScriptResolver::resolve( const Tomahawk::query_ptr& query ) -{ - QMetaObject::invokeMethod( m_engine, "resolve", Qt::QueuedConnection, Q_ARG( Tomahawk::query_ptr, query ) ); + qDebug() << Q_FUNC_INFO << name << weight << timeout << preference; + emit engineFound( name, weight, timeout, preference ); } void ScriptEngine::resolve( const Tomahawk::query_ptr& query ) { + if ( QThread::currentThread() != thread() ) + { +// qDebug() << "Reinvoking in correct thread:" << Q_FUNC_INFO; + QMetaObject::invokeMethod( this, "resolve", + Qt::QueuedConnection, + Q_ARG(Tomahawk::query_ptr, query) + ); + return; + } + qDebug() << Q_FUNC_INFO << query->toString(); QString eval = QString( "resolve( '%1', '%2', '%3', '%4' );" ) .arg( query->id().replace( "'", "\\'" ) ) @@ -113,9 +169,9 @@ ScriptEngine::resolve( const Tomahawk::query_ptr& query ) rp->setBitrate( m.value( "bitrate" ).toUInt() ); rp->setUrl( m.value( "url" ).toString() ); rp->setSize( m.value( "size" ).toUInt() ); - rp->setScore( m.value( "score" ).toFloat() * ( (float)m_parent->weight() / 100.0 ) ); + rp->setScore( m.value( "score" ).toFloat() * ( (float)m_resolver->weight() / 100.0 ) ); rp->setRID( uuid() ); - rp->setFriendlySource( m_parent->name() ); + rp->setFriendlySource( m_resolver->name() ); if ( m.contains( "year" ) ) { diff --git a/src/resolvers/qtscriptresolver.h b/src/resolvers/qtscriptresolver.h index 05b55cc71..7c69fe103 100644 --- a/src/resolvers/qtscriptresolver.h +++ b/src/resolvers/qtscriptresolver.h @@ -26,9 +26,11 @@ #include #include #include +#include #include #include +class ScriptThread; class QtScriptResolver; class ScriptEngine : public QWebPage @@ -36,9 +38,10 @@ class ScriptEngine : public QWebPage Q_OBJECT public: - explicit ScriptEngine( QtScriptResolver* parent ) + explicit ScriptEngine( QtScriptResolver* resolver, ScriptThread* parent ) : QWebPage( (QObject*)parent ) , m_parent( parent ) + , m_resolver( resolver ) {} public slots: @@ -54,9 +57,35 @@ protected: { qDebug() << "JAVASCRIPT ERROR:" << message << lineNumber << sourceID; } private: - QtScriptResolver* m_parent; + ScriptThread* m_parent; + QtScriptResolver* m_resolver; }; + +class ScriptThread : public QThread +{ +Q_OBJECT + +public: + ScriptThread( const QString& scriptPath, QtScriptResolver* parent ); + + void run(); + + virtual void resolve( const Tomahawk::query_ptr& query ); + +signals: + void engineFound( const QString& name, unsigned int weight, unsigned int timeout, unsigned int preference ); + +private slots: + void initEngine(); + +private: + ScriptEngine* m_engine; + QtScriptResolver* m_parent; + QString m_scriptPath; +}; + + class QtScriptResolver : public Tomahawk::ExternalResolver { Q_OBJECT @@ -76,12 +105,12 @@ public slots: signals: void finished(); - + private slots: + void onEngineFound( const QString& name, unsigned int weight, unsigned int timeout, unsigned int preference ); private: - ScriptEngine* m_engine; - QThread* m_thread; + ScriptThread* m_thread; QString m_name; unsigned int m_weight, m_preference, m_timeout;