mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-07-31 19:30:21 +02:00
Port ScriptInfoPlugin to new generic script plugin infrastructure
This commit is contained in:
@@ -4,7 +4,7 @@ if(window.Promise === undefined) {
|
||||
}
|
||||
|
||||
// TODO: find a way to enumerate TypeInfo instead of copying this manually
|
||||
|
||||
Tomahawk.InfoSystem = Tomahawk.InfoSystem || {};
|
||||
Tomahawk.InfoSystem.InfoType = Object.create(null);
|
||||
|
||||
Tomahawk.InfoSystem.InfoType.InfoNoInfo = 0; //WARNING: *ALWAYS* keep this first!
|
||||
@@ -92,25 +92,6 @@ Tomahawk.InfoSystem.PushInfoFlags = Object.create(null);
|
||||
Tomahawk.InfoSystem.PushInfoFlags.PushNoFlag = 1;
|
||||
Tomahawk.InfoSystem.PushInfoFlags.PushShortUrlFlag = 2;
|
||||
|
||||
|
||||
Tomahawk.InfoSystem._infoPluginIdCounter = 0;
|
||||
Tomahawk.InfoSystem._infoPluginHash = Object.create(null);
|
||||
|
||||
Tomahawk.InfoSystem.addInfoPlugin = function (infoPlugin) {
|
||||
var infoPluginId = Tomahawk.InfoSystem._infoPluginIdCounter++;
|
||||
Tomahawk.InfoSystem._infoPluginHash[infoPluginId] = infoPlugin;
|
||||
Tomahawk.InfoSystem.nativeAddInfoPlugin(infoPluginId);
|
||||
};
|
||||
|
||||
Tomahawk.InfoSystem.getInfoPlugin = function (infoPluginId) {
|
||||
return Tomahawk.InfoSystem._infoPluginHash[infoPluginId];
|
||||
};
|
||||
|
||||
Tomahawk.InfoSystem.removeInfoPlugin = function (infoPluginId) {
|
||||
Tomahawk.log('Removing info plugins from JS is not implemented yet');
|
||||
Tomahawk.assert(false);
|
||||
};
|
||||
|
||||
Tomahawk.InfoSystem.InfoPlugin = {
|
||||
infoTypeString: function (infoType) {
|
||||
for (var currentInfoTypeString in Tomahawk.InfoSystem.InfoType) {
|
||||
@@ -119,13 +100,8 @@ Tomahawk.InfoSystem.InfoPlugin = {
|
||||
}
|
||||
}
|
||||
},
|
||||
// we can get around infoPluginId here probably ... but internal either way
|
||||
_notInCache: function (infoPluginId, requestId, requestType, criteria) {
|
||||
this.notInCache(requestType, criteria).then(function(result) {
|
||||
Tomahawk.InfoSystem.nativeAddInfoRequestResult(infoPluginId, requestId, result.maxAge, result.data);
|
||||
}).catch(function() {
|
||||
// TODO: how to handle errors here?!
|
||||
});
|
||||
_notInCache: function (params) {
|
||||
return this.notInCache(params.type, params.criteria);
|
||||
},
|
||||
notInCache: function (infoType, criteria) {
|
||||
var requestMethod = 'request' + this.infoTypeString(infoType);
|
||||
@@ -136,14 +112,8 @@ Tomahawk.InfoSystem.InfoPlugin = {
|
||||
var pushMethod = 'push' + this.infoTypeString(pushData.type);
|
||||
return this[pushMethod](pushData);
|
||||
},
|
||||
// we can get around infoPluginId here probably ... but internal either way
|
||||
_getInfo: function (infoPluginId, requestId, type, infoHash) {
|
||||
this.getInfo(type, infoHash).then(function(result) {
|
||||
Tomahawk.InfoSystem.nativeGetCachedInfo(infoPluginId, requestId, result.newMaxAge, result.criteria)
|
||||
}, function() {
|
||||
Tomahawk.log("Call nativeDataError");
|
||||
Tomahawk.InfoSystem.nativeDataError();
|
||||
});
|
||||
_getInfo: function (params) {
|
||||
return this.getInfo(params.type, params.data);
|
||||
},
|
||||
getInfo: function (type, infoHash) {
|
||||
var getInfoMethod = 'get' + this.infoTypeString(type);
|
||||
|
@@ -615,8 +615,8 @@ Tomahawk.PluginManager = {
|
||||
Tomahawk.registerScriptPlugin(type, object.id);
|
||||
},
|
||||
|
||||
invoke: function (requestId, objectId, methodName, params ) {
|
||||
Tomahawk.log("requestId: " + requestId + " objectId: " + objectId + " methodName: " + methodName + " params: " + params);
|
||||
|
||||
invokeSync: function (objectId, methodName, params) {
|
||||
if (!this.objects[objectId]) {
|
||||
Tomahawk.log("Object not found!");
|
||||
} else {
|
||||
@@ -625,7 +625,15 @@ Tomahawk.PluginManager = {
|
||||
}
|
||||
}
|
||||
|
||||
Promise.resolve(this.objects[objectId][methodName](params)).then(function (result) {
|
||||
if (typeof this.objects[objectId][methodName] === 'function') {
|
||||
return this.objects[objectId][methodName](params);
|
||||
}
|
||||
|
||||
return this.objects[objectId][methodName];
|
||||
},
|
||||
|
||||
invoke: function (requestId, objectId, methodName, params ) {
|
||||
Promise.resolve(this.invokeSync(objectId, methodName, params)).then(function (result) {
|
||||
if (typeof result === 'object') {
|
||||
Tomahawk.reportScriptJobResults({
|
||||
requestId: requestId,
|
||||
@@ -634,7 +642,7 @@ Tomahawk.PluginManager = {
|
||||
} else {
|
||||
Tomahawk.reportScriptJobResults({
|
||||
requestId: requestId,
|
||||
error: "Scripts need to return objects for requests"
|
||||
error: "Scripts need to return objects for requests: methodName: " + methodName + " params: " + JSON.encode(params)
|
||||
});
|
||||
}
|
||||
}, function (error) {
|
||||
|
@@ -85,7 +85,6 @@ set( libGuiSources
|
||||
resolvers/ExternalResolverGui.cpp
|
||||
resolvers/ScriptResolver.cpp
|
||||
resolvers/ScriptInfoPlugin.cpp
|
||||
resolvers/JSInfoSystemHelper.cpp
|
||||
resolvers/JSResolver.cpp
|
||||
resolvers/JSResolverHelper.cpp
|
||||
resolvers/ScriptEngine.cpp
|
||||
|
@@ -32,8 +32,8 @@
|
||||
using namespace Tomahawk;
|
||||
|
||||
JSAccount::JSAccount( const QString& name )
|
||||
: m_engine( new ScriptEngine( this ) )
|
||||
, m_name( name )
|
||||
: ScriptAccount( name )
|
||||
, m_engine( new ScriptEngine( this ) )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ JSAccount::scriptPluginFactory( const QString& type, ScriptObject* object )
|
||||
if ( type == "resolver" )
|
||||
{
|
||||
Q_ASSERT( m_resolver );
|
||||
m_resolver->m_object = object;
|
||||
m_resolver->m_scriptObject = object;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -150,6 +150,26 @@ JSAccount::startJob( ScriptJob* scriptJob )
|
||||
}
|
||||
|
||||
|
||||
const QVariant
|
||||
JSAccount::syncInvoke( ScriptObject* scriptObject, const QString& methodName, const QVariantMap& arguments )
|
||||
{
|
||||
QString eval = QString(
|
||||
"Tomahawk.PluginManager.invokeSync("
|
||||
"'%1'," // objectId
|
||||
"'%2'," // methodName
|
||||
"%3" // arguments
|
||||
");"
|
||||
).arg( scriptObject->id() )
|
||||
.arg( methodName )
|
||||
.arg( serializeQVariantMap( arguments ) );
|
||||
|
||||
// Remove when new scripting api turned out to work reliably
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << eval;
|
||||
|
||||
return evaluateJavaScriptWithResult( eval );
|
||||
}
|
||||
|
||||
|
||||
const QString
|
||||
JSAccount::name() const
|
||||
{
|
||||
|
@@ -45,6 +45,7 @@ public:
|
||||
JSAccount( const QString& name );
|
||||
|
||||
void startJob( ScriptJob* scriptJob ) override;
|
||||
const QVariant syncInvoke( ScriptObject* scriptObject, const QString& methodName, const QVariantMap& arguments ) override;
|
||||
|
||||
const QString name() const;
|
||||
|
||||
|
@@ -1,116 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.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 "JSInfoSystemHelper_p.h"
|
||||
#include "ScriptInfoPlugin.h"
|
||||
|
||||
#include "JSAccount.h"
|
||||
#include "../utils/Logger.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
JSInfoSystemHelper::JSInfoSystemHelper( JSAccount* parent )
|
||||
: QObject( parent )
|
||||
, d_ptr( new JSInfoSystemHelperPrivate( this, parent ) )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
JSInfoSystemHelper::~JSInfoSystemHelper()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QStringList JSInfoSystemHelper::requiredScriptPaths() const
|
||||
{
|
||||
return QStringList()
|
||||
<< RESPATH "js/tomahawk-infosystem.js";
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSInfoSystemHelper::nativeAddInfoPlugin( int id )
|
||||
{
|
||||
Q_D( JSInfoSystemHelper );
|
||||
|
||||
// create infoplugin instance
|
||||
ScriptInfoPlugin* scriptInfoPlugin = new ScriptInfoPlugin( id, d->scriptAccount );
|
||||
Tomahawk::InfoSystem::InfoPluginPtr infoPlugin( scriptInfoPlugin );
|
||||
|
||||
// move it to infosystem thread
|
||||
infoPlugin->moveToThread( Tomahawk::InfoSystem::InfoSystem::instance()->workerThread().data() );
|
||||
|
||||
// add it to local list of infoplugins
|
||||
d->infoPlugins[id] = scriptInfoPlugin;
|
||||
|
||||
// add it to infosystem
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->addInfoPlugin( infoPlugin );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSInfoSystemHelper::nativeRemoveInfoPlugin( int id )
|
||||
{
|
||||
Q_UNUSED( id );
|
||||
tLog() << "Removing Info plugins from JS is not implemented yet";
|
||||
Q_ASSERT( false );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSInfoSystemHelper::nativeAddInfoRequestResult( int infoPluginId, int requestId, int maxAge, const QVariantMap& returnedData )
|
||||
{
|
||||
Q_D( JSInfoSystemHelper );
|
||||
|
||||
if ( !d->infoPlugins[ infoPluginId ] )
|
||||
{
|
||||
Q_ASSERT( d->infoPlugins[ infoPluginId ] );
|
||||
return;
|
||||
}
|
||||
|
||||
d->infoPlugins[ infoPluginId ]->addInfoRequestResult( requestId, maxAge, returnedData );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSInfoSystemHelper::nativeGetCachedInfo( int infoPluginId, int requestId, int newMaxAge, const QVariantMap& criteria )
|
||||
{
|
||||
Q_D( JSInfoSystemHelper );
|
||||
|
||||
if ( !d->infoPlugins[ infoPluginId ] )
|
||||
{
|
||||
Q_ASSERT( d->infoPlugins[ infoPluginId ] );
|
||||
return;
|
||||
}
|
||||
|
||||
d->infoPlugins[ infoPluginId ]->emitGetCachedInfo( requestId, criteria, newMaxAge );
|
||||
}
|
||||
|
||||
|
||||
void JSInfoSystemHelper::nativeDataError( int infoPluginId, int requestId )
|
||||
{
|
||||
Q_D( JSInfoSystemHelper );
|
||||
|
||||
if ( !d->infoPlugins[ infoPluginId ] )
|
||||
{
|
||||
Q_ASSERT( d->infoPlugins[ infoPluginId ] );
|
||||
return;
|
||||
}
|
||||
|
||||
d->infoPlugins[ infoPluginId ]->emitInfo( requestId, QVariantMap() );
|
||||
}
|
@@ -1,55 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.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 TOMAHAWK_JSINFOSYSTEMHELPER_H
|
||||
#define TOMAHAWK_JSINFOSYSTEMHELPER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
class JSAccount;
|
||||
class JSInfoSystemHelperPrivate;
|
||||
|
||||
class JSInfoSystemHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
JSInfoSystemHelper( JSAccount* parent );
|
||||
~JSInfoSystemHelper();
|
||||
|
||||
QStringList requiredScriptPaths() const;
|
||||
|
||||
Q_INVOKABLE void nativeAddInfoPlugin( int id );
|
||||
Q_INVOKABLE void nativeRemoveInfoPlugin( int id );
|
||||
|
||||
Q_INVOKABLE void nativeAddInfoRequestResult( int infoPluginId, int requestId, int maxAge, const QVariantMap& returnedData );
|
||||
Q_INVOKABLE void nativeGetCachedInfo( int infoPluginId, int requestId, int newMaxAge, const QVariantMap& criteria);
|
||||
Q_INVOKABLE void nativeDataError( int infoPluginId, int requestId );
|
||||
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE( JSInfoSystemHelper )
|
||||
QScopedPointer<JSInfoSystemHelperPrivate> d_ptr;
|
||||
};
|
||||
|
||||
} // ns: Tomahawk
|
||||
|
||||
#endif // TOMAHAWK_JSINFOSYSTEMHELPER_H
|
@@ -1,49 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.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 TOMAHAWK_JSINFOSYSTEMHELPER_P_H
|
||||
#define TOMAHAWK_JSINFOSYSTEMHELPER_P_H
|
||||
|
||||
#include "JSResolver.h"
|
||||
#include "JSInfoSystemHelper.h"
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
class JSInfoSystemHelperPrivate
|
||||
{
|
||||
friend class JSInfoSystemHelper;
|
||||
public:
|
||||
JSInfoSystemHelperPrivate( JSInfoSystemHelper* q, JSAccount* scriptAccount )
|
||||
: q_ptr ( q )
|
||||
, scriptAccount ( scriptAccount )
|
||||
{
|
||||
}
|
||||
|
||||
JSInfoSystemHelper* q_ptr;
|
||||
Q_DECLARE_PUBLIC ( JSInfoSystemHelper )
|
||||
|
||||
private:
|
||||
JSAccount* scriptAccount;
|
||||
QMap<int,ScriptInfoPlugin*> infoPlugins;
|
||||
|
||||
};
|
||||
|
||||
} // ns: Tomahawk
|
||||
|
||||
#endif // TOMAHAWK_JSINFOSYSTEMHELPER_P_H
|
@@ -233,15 +233,10 @@ JSResolver::init()
|
||||
|
||||
// tomahawk-infosystem.js
|
||||
{
|
||||
// TODO: be smarter about this, only instantiate this if the resolver supports infoplugins
|
||||
|
||||
// add c++ part of tomahawk infosystem bindings as Tomahawk.InfoSystem
|
||||
d->infoSystemHelper = new JSInfoSystemHelper( d->scriptAccount.get() );
|
||||
d->scriptAccount->addToJavaScriptWindowObject( "_TomahawkInfoSystem", d->infoSystemHelper );
|
||||
d->scriptAccount->evaluateJavaScript( "Tomahawk.InfoSystem = _TomahawkInfoSystem;" );
|
||||
// TODO: be smarter about this, only include this if the resolver supports infoplugins
|
||||
|
||||
// add deps
|
||||
d->scriptAccount->loadScripts( d->infoSystemHelper->requiredScriptPaths() );
|
||||
d->scriptAccount->loadScript( RESPATH "js/tomahawk-infosystem.js" );
|
||||
}
|
||||
|
||||
// add resolver dependencies, if any
|
||||
|
@@ -25,7 +25,6 @@
|
||||
#include "JSResolver.h"
|
||||
|
||||
#include "JSResolverHelper.h"
|
||||
#include "JSInfoSystemHelper.h"
|
||||
#include "database/fuzzyindex/FuzzyIndex.h"
|
||||
|
||||
#include <memory> // unique_ptr
|
||||
@@ -44,7 +43,6 @@ public:
|
||||
, stopped( true )
|
||||
, error( Tomahawk::ExternalResolver::NoError )
|
||||
, resolverHelper( new JSResolverHelper( scriptPath, q ) )
|
||||
, infoSystemHelper( nullptr )
|
||||
, requiredScriptPaths( additionalScriptPaths )
|
||||
{
|
||||
}
|
||||
@@ -63,7 +61,6 @@ private:
|
||||
Tomahawk::ExternalResolver::ErrorState error;
|
||||
|
||||
JSResolverHelper* resolverHelper;
|
||||
JSInfoSystemHelper* infoSystemHelper;
|
||||
QScopedPointer<FuzzyIndex> fuzzyIndex;
|
||||
QPointer< AccountConfigWidget > configWidget;
|
||||
QList< QVariant > dataWidgets;
|
||||
|
@@ -21,13 +21,21 @@
|
||||
#include "ScriptObject.h"
|
||||
#include "../utils/Logger.h"
|
||||
|
||||
|
||||
// TODO: register factory methods instead of hardcoding all plugin types in here
|
||||
#include "../utils/LinkGenerator.h"
|
||||
#include "ScriptLinkGeneratorPlugin.h"
|
||||
#include "ScriptInfoPlugin.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
ScriptAccount::ScriptAccount( const QString& name )
|
||||
: QObject()
|
||||
, m_name( name )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static QString
|
||||
requestIdGenerator()
|
||||
{
|
||||
@@ -43,6 +51,9 @@ ScriptAccount::invoke( ScriptObject* scriptObject, const QString& methodName, co
|
||||
QString requestId = requestIdGenerator();
|
||||
|
||||
ScriptJob* job = new ScriptJob( requestId, scriptObject, methodName, arguments );
|
||||
// TODO: setParent through QueuedConnection
|
||||
|
||||
|
||||
connect( job, SIGNAL( destroyed( QString ) ), SLOT( onJobDeleted( QString ) ) );
|
||||
m_jobs.insert( requestId, job );
|
||||
|
||||
@@ -97,6 +108,18 @@ ScriptAccount::scriptPluginFactory( const QString& type, ScriptObject* object )
|
||||
ScriptLinkGeneratorPlugin* lgp = new ScriptLinkGeneratorPlugin( object );
|
||||
Utils::LinkGenerator::instance()->addPlugin( lgp );
|
||||
}
|
||||
else if ( type == "infoPlugin" )
|
||||
{
|
||||
// create infoplugin instance
|
||||
ScriptInfoPlugin* scriptInfoPlugin = new ScriptInfoPlugin( object, m_name );
|
||||
Tomahawk::InfoSystem::InfoPluginPtr infoPlugin( scriptInfoPlugin );
|
||||
|
||||
// move it to infosystem thread
|
||||
infoPlugin->moveToThread( Tomahawk::InfoSystem::InfoSystem::instance()->workerThread().data() );
|
||||
|
||||
// add it to infosystem
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->addInfoPlugin( infoPlugin );
|
||||
}
|
||||
else
|
||||
{
|
||||
tLog() << "This plugin type is not handled by Tomahawk";
|
||||
|
@@ -39,9 +39,12 @@ class DLLEXPORT ScriptAccount : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScriptAccount( const QString& name );
|
||||
virtual ~ScriptAccount() {}
|
||||
|
||||
ScriptJob* invoke( ScriptObject* scriptObject, const QString& methodName, const QVariantMap& arguments );
|
||||
virtual const QVariant syncInvoke( ScriptObject* scriptObject, const QString& methodName, const QVariantMap& arguments ) = 0;
|
||||
|
||||
virtual void startJob( ScriptJob* scriptJob ) = 0;
|
||||
|
||||
void reportScriptJobResult( const QVariantMap& result );
|
||||
@@ -53,6 +56,7 @@ private slots:
|
||||
void onJobDeleted( const QString& jobId );
|
||||
|
||||
private: // TODO: pimple, might be renamed before tho
|
||||
QString m_name;
|
||||
QHash< QString, ScriptJob* > m_jobs;
|
||||
QHash< QString, ScriptObject* > m_objects;
|
||||
};
|
||||
|
@@ -20,22 +20,25 @@
|
||||
|
||||
#include "JSAccount.h"
|
||||
#include "Typedefs.h"
|
||||
#include "ScriptObject.h"
|
||||
#include "ScriptJob.h"
|
||||
|
||||
#include "../utils/Logger.h"
|
||||
#include "../utils/Json.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
ScriptInfoPlugin::ScriptInfoPlugin( int id, JSAccount *resolver )
|
||||
: d_ptr( new ScriptInfoPluginPrivate( this, id, resolver ) )
|
||||
ScriptInfoPlugin::ScriptInfoPlugin( ScriptObject* scriptObject, const QString& name )
|
||||
: d_ptr( new ScriptInfoPluginPrivate( this ) )
|
||||
, ScriptPlugin( scriptObject )
|
||||
{
|
||||
Q_ASSERT( resolver );
|
||||
Q_ASSERT( scriptObject );
|
||||
|
||||
// read in supported GetTypes and PushTypes - we can do this safely because we are still in WebKit thread here
|
||||
m_supportedGetTypes = parseSupportedTypes( callMethodOnInfoPluginWithResult( "supportedGetTypes" ) );
|
||||
m_supportedPushTypes = parseSupportedTypes( callMethodOnInfoPluginWithResult( "supportedPushTypes" ) );
|
||||
m_supportedGetTypes = parseSupportedTypes( m_scriptObject->syncInvoke( "supportedGetTypes" ) );
|
||||
m_supportedPushTypes = parseSupportedTypes( m_scriptObject->syncInvoke( "supportedPushTypes" ) );
|
||||
|
||||
setFriendlyName( QString( "ScriptInfoPlugin: %1" ).arg( resolver->name() ) );
|
||||
setFriendlyName( QString( "ScriptInfoPlugin: %1" ).arg( name ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -55,28 +58,29 @@ ScriptInfoPlugin::getInfo( Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
Q_D( ScriptInfoPlugin );
|
||||
|
||||
d->requestDataCache[ requestData.requestId ] = requestData;
|
||||
|
||||
QString eval = QString( "_getInfo(%1, %2, %3, %4)" )
|
||||
.arg( d->id ) // infoPluginId
|
||||
.arg( requestData.requestId ) // requestId
|
||||
.arg( requestData.type ) // type
|
||||
.arg( serializeQVariantMap( convertInfoStringHashToQVariantMap( requestData.input.value<Tomahawk::InfoSystem::InfoStringHash>() ) ) ); // infoHash
|
||||
QVariantMap arguments;
|
||||
arguments[ "type" ] = requestData.type;
|
||||
arguments[ "data" ] = convertInfoStringHashToQVariantMap( requestData.input.value<Tomahawk::InfoSystem::InfoStringHash>() );
|
||||
|
||||
callMethodOnInfoPlugin( eval );
|
||||
ScriptJob* job = m_scriptObject->invoke( "_getInfo", arguments );
|
||||
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( onGetInfoRequestDone( QVariantMap ) ) );
|
||||
|
||||
d->requestDataCache[ job->id().toInt() ] = requestData;
|
||||
job->start();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptInfoPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
|
||||
{
|
||||
QString eval = QString( "pushInfo({ type: %1, pushFlags: %2, input: %3, additionalInput: %4})" )
|
||||
.arg( pushData.type )
|
||||
.arg( pushData.pushFlags )
|
||||
.arg( serializeQVariantMap ( pushData.infoPair.second.toMap() ) )
|
||||
.arg( serializeQVariantMap( pushData.infoPair.first ) );
|
||||
QVariantMap arguments;
|
||||
arguments[ "type" ] = pushData.type;
|
||||
arguments[ "pushFlags" ] = pushData.pushFlags;
|
||||
arguments[ "input" ] = serializeQVariantMap ( pushData.infoPair.second.toMap() );
|
||||
arguments[ "additionalInput" ] = serializeQVariantMap( pushData.infoPair.first );
|
||||
|
||||
callMethodOnInfoPlugin( eval );
|
||||
m_scriptObject->invoke( "pushInfo", arguments );
|
||||
}
|
||||
|
||||
|
||||
@@ -85,112 +89,70 @@ ScriptInfoPlugin::notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria,
|
||||
{
|
||||
Q_D( ScriptInfoPlugin );
|
||||
|
||||
d->requestDataCache[ requestData.requestId ] = requestData;
|
||||
d->criteriaCache[ requestData.requestId ] = criteria;
|
||||
QVariantMap arguments;
|
||||
arguments[ "type" ] = requestData.type;
|
||||
arguments[ "criteria" ] = convertInfoStringHashToQVariantMap( criteria );
|
||||
|
||||
ScriptJob* job = m_scriptObject->invoke( "_notInCache", arguments );
|
||||
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( onNotInCacheRequestDone( QVariantMap ) ) );
|
||||
d->requestDataCache[ job->id().toInt() ] = requestData;
|
||||
d->criteriaCache[ job->id().toInt() ] = criteria;
|
||||
|
||||
QString eval = QString( "_notInCache(%1, %2, %3, %4)" )
|
||||
.arg( d->id )
|
||||
.arg( requestData.requestId )
|
||||
.arg( requestData.type )
|
||||
.arg( serializeQVariantMap( convertInfoStringHashToQVariantMap( criteria ) ) );
|
||||
|
||||
callMethodOnInfoPlugin( eval );
|
||||
job->start();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptInfoPlugin::addInfoRequestResult( int requestId, qint64 maxAge, const QVariantMap& returnedData )
|
||||
ScriptInfoPlugin::onGetInfoRequestDone( const QVariantMap& result )
|
||||
{
|
||||
if ( QThread::currentThread() != thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( this, "addInfoRequestResult", Qt::QueuedConnection, Q_ARG( int, requestId ), Q_ARG( qint64, maxAge ), Q_ARG( QVariantMap, returnedData ) );
|
||||
return;
|
||||
}
|
||||
Q_ASSERT( QThread::currentThread() == thread() );
|
||||
|
||||
Q_D( ScriptInfoPlugin );
|
||||
|
||||
|
||||
|
||||
ScriptJob* job = qobject_cast< ScriptJob* >( sender() );
|
||||
|
||||
if ( job->error() )
|
||||
{
|
||||
emit info( d->requestDataCache[ job->id().toInt() ], QVariantMap() );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
emit getCachedInfo( convertQVariantMapToInfoStringHash( result[ "criteria" ].toMap() ), result[ "newMaxAge" ].toLongLong(), d->requestDataCache[ job->id().toInt() ] );
|
||||
}
|
||||
|
||||
d->requestDataCache.remove( job->id().toInt() );
|
||||
sender()->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptInfoPlugin::onNotInCacheRequestDone( const QVariantMap& result )
|
||||
{
|
||||
Q_ASSERT( QThread::currentThread() == thread() );
|
||||
|
||||
Q_D( ScriptInfoPlugin );
|
||||
|
||||
ScriptJob* job = qobject_cast< ScriptJob* >( sender() );
|
||||
|
||||
// retrieve requestData from cache and delete it
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData = d->requestDataCache[ requestId ];
|
||||
d->requestDataCache.remove( requestId );
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData = d->requestDataCache[ job->id().toInt() ];
|
||||
d->requestDataCache.remove( job->id().toInt() );
|
||||
|
||||
emit info( requestData, returnedData );
|
||||
emit info( requestData, result[ "data" ].toMap() );
|
||||
|
||||
// retrieve criteria from cache and delete it
|
||||
Tomahawk::InfoSystem::InfoStringHash criteria = d->criteriaCache[ requestId ];
|
||||
d->criteriaCache.remove( requestId );
|
||||
Tomahawk::InfoSystem::InfoStringHash criteria = d->criteriaCache[ job->id().toInt() ];
|
||||
d->criteriaCache.remove( job->id().toInt() );
|
||||
|
||||
emit updateCache( criteria, maxAge, requestData.type, returnedData );
|
||||
emit updateCache( criteria, result[ "maxAge" ].toLongLong(), requestData.type, result[ "data" ].toMap() );
|
||||
|
||||
sender()->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptInfoPlugin::emitGetCachedInfo( int requestId, const QVariantMap& criteria, int newMaxAge )
|
||||
{
|
||||
if ( QThread::currentThread() != thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( this, "emitGetCachedInfo", Qt::QueuedConnection, Q_ARG( int, requestId ), Q_ARG( QVariantMap, criteria ), Q_ARG( int, newMaxAge ) );
|
||||
return;
|
||||
}
|
||||
|
||||
Q_D( ScriptInfoPlugin );
|
||||
|
||||
|
||||
emit getCachedInfo( convertQVariantMapToInfoStringHash( criteria ), newMaxAge, d->requestDataCache[ requestId ]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptInfoPlugin::emitInfo( int requestId, const QVariantMap& output )
|
||||
{
|
||||
if ( QThread::currentThread() != thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( this, "emitInfo", Qt::QueuedConnection, Q_ARG( int, requestId ), Q_ARG( QVariantMap, output ) );
|
||||
return;
|
||||
}
|
||||
|
||||
Q_D( ScriptInfoPlugin );
|
||||
|
||||
emit info( d->requestDataCache[ requestId ], output );
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
ScriptInfoPlugin::serviceGetter() const
|
||||
{
|
||||
Q_D( const ScriptInfoPlugin );
|
||||
|
||||
return QString( "Tomahawk.InfoSystem.getInfoPlugin(%1)" ).arg( d->id );
|
||||
}
|
||||
|
||||
// TODO: DRY, really move things into base class
|
||||
void
|
||||
ScriptInfoPlugin::callMethodOnInfoPlugin( const QString& scriptSource )
|
||||
{
|
||||
Q_D( ScriptInfoPlugin );
|
||||
|
||||
QString eval = QString( "%1.%2" ).arg( serviceGetter() ).arg( scriptSource );
|
||||
|
||||
tLog() << Q_FUNC_INFO << eval;
|
||||
|
||||
d->resolver->evaluateJavaScript( eval );
|
||||
}
|
||||
|
||||
|
||||
QVariant
|
||||
ScriptInfoPlugin::callMethodOnInfoPluginWithResult(const QString& scriptSource)
|
||||
{
|
||||
Q_D( ScriptInfoPlugin );
|
||||
|
||||
QString eval = QString( "%1.%2" ).arg( serviceGetter() ).arg( scriptSource );
|
||||
|
||||
tLog() << Q_FUNC_INFO << eval;
|
||||
|
||||
return d->resolver->evaluateJavaScriptWithResult( eval );
|
||||
}
|
||||
|
||||
|
||||
|
||||
QSet< Tomahawk::InfoSystem::InfoType >
|
||||
ScriptInfoPlugin::parseSupportedTypes( const QVariant& variant )
|
||||
{
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#define TOMAHAWK_SCRIPTINFOPLUGIN_H
|
||||
|
||||
#include "../infosystem/InfoSystem.h"
|
||||
#include "ScriptPlugin.h"
|
||||
|
||||
#include "DllMacro.h"
|
||||
|
||||
@@ -29,9 +30,10 @@ namespace Tomahawk
|
||||
|
||||
class JSAccount;
|
||||
class ScriptInfoPluginPrivate;
|
||||
class ScriptObject;
|
||||
|
||||
|
||||
class DLLEXPORT ScriptInfoPlugin : public Tomahawk::InfoSystem::InfoPlugin
|
||||
class DLLEXPORT ScriptInfoPlugin : public Tomahawk::InfoSystem::InfoPlugin, Tomahawk::ScriptPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -39,14 +41,9 @@ public:
|
||||
/**
|
||||
* @param id unique identifier to identify an infoplugin in its scope
|
||||
*/
|
||||
ScriptInfoPlugin( int id, JSAccount* resolver );
|
||||
ScriptInfoPlugin( ScriptObject* scriptObject, const QString& name );
|
||||
virtual ~ScriptInfoPlugin();
|
||||
|
||||
|
||||
Q_INVOKABLE void addInfoRequestResult( int requestId, qint64 maxAge, const QVariantMap& returnedData );
|
||||
Q_INVOKABLE void emitGetCachedInfo( int requestId, const QVariantMap& criteria, int newMaxAge );
|
||||
Q_INVOKABLE void emitInfo( int requestId, const QVariantMap& output );
|
||||
|
||||
protected slots:
|
||||
void init() override;
|
||||
|
||||
@@ -54,11 +51,8 @@ protected slots:
|
||||
void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData ) override;
|
||||
void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) override;
|
||||
|
||||
protected:
|
||||
// TODO: create JSAccount base class and move these methods there
|
||||
QString serviceGetter() const; // = 0
|
||||
void callMethodOnInfoPlugin( const QString& scriptSource );
|
||||
QVariant callMethodOnInfoPluginWithResult( const QString& scriptSource );
|
||||
void onGetInfoRequestDone( const QVariantMap& result );
|
||||
void onNotInCacheRequestDone( const QVariantMap& result );
|
||||
|
||||
private:
|
||||
static QSet< Tomahawk::InfoSystem::InfoType > parseSupportedTypes(const QVariant& variant);
|
||||
|
@@ -28,20 +28,14 @@ class ScriptInfoPluginPrivate
|
||||
{
|
||||
friend class ScriptInfoPlugin;
|
||||
public:
|
||||
ScriptInfoPluginPrivate( ScriptInfoPlugin* q, int id, JSAccount* resolver )
|
||||
ScriptInfoPluginPrivate( ScriptInfoPlugin* q )
|
||||
: q_ptr ( q )
|
||||
, id( id )
|
||||
, resolver( resolver )
|
||||
{
|
||||
}
|
||||
ScriptInfoPlugin* q_ptr;
|
||||
Q_DECLARE_PUBLIC ( ScriptInfoPlugin )
|
||||
|
||||
private:
|
||||
int id;
|
||||
// HACK: ScriptInfoPlugin needs to be refactored to track a ScriptObject
|
||||
JSAccount* resolver;
|
||||
|
||||
QMap< int, Tomahawk::InfoSystem::InfoRequestData > requestDataCache;
|
||||
QMap< int, Tomahawk::InfoSystem::InfoStringHash > criteriaCache;
|
||||
};
|
||||
|
@@ -18,12 +18,14 @@
|
||||
|
||||
#include "ScriptJob.h"
|
||||
#include "ScriptObject.h"
|
||||
|
||||
#include <QMetaObject>
|
||||
#include <QThread>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
ScriptJob::ScriptJob( const QString& id, ScriptObject* scriptObject, const QString& methodName, const QVariantMap& arguments )
|
||||
: QObject( scriptObject )
|
||||
: QObject( scriptObject->thread() == QThread::currentThread() ? scriptObject : nullptr )
|
||||
, m_error( false )
|
||||
, m_id( id )
|
||||
, m_scriptObject( scriptObject )
|
||||
|
@@ -43,6 +43,15 @@ ScriptObject::invoke( const QString& methodName, const QVariantMap& arguments )
|
||||
}
|
||||
|
||||
|
||||
const QVariant
|
||||
ScriptObject::syncInvoke(const QString& methodName, const QVariantMap& arguments)
|
||||
{
|
||||
Q_D( ScriptObject );
|
||||
|
||||
return d->scriptAccount->syncInvoke( this, methodName, arguments );
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
ScriptObject::id() const
|
||||
{
|
||||
|
@@ -42,6 +42,11 @@ public:
|
||||
|
||||
ScriptJob* invoke( const QString& methodName, const QVariantMap& arguments = QVariantMap() );
|
||||
|
||||
/**
|
||||
* Avoid using this if possible, it's blocking and can only be used from the gui thread
|
||||
*/
|
||||
const QVariant syncInvoke( const QString& methodName, const QVariantMap& arguments = QVariantMap() );
|
||||
|
||||
protected:
|
||||
QString id() const;
|
||||
|
||||
|
@@ -21,7 +21,7 @@
|
||||
using namespace Tomahawk;
|
||||
|
||||
ScriptPlugin::ScriptPlugin( ScriptObject* object )
|
||||
: m_object( object )
|
||||
: m_scriptObject( object )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -35,5 +35,5 @@ ScriptPlugin::~ScriptPlugin()
|
||||
ScriptObject*
|
||||
ScriptPlugin::scriptObject() const
|
||||
{
|
||||
return m_object;
|
||||
return m_scriptObject;
|
||||
}
|
||||
|
@@ -35,7 +35,7 @@ public:
|
||||
ScriptObject* scriptObject() const;
|
||||
|
||||
protected: // TODO: pimple
|
||||
ScriptObject* m_object;
|
||||
ScriptObject* m_scriptObject;
|
||||
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user