[C++/JS/Qt] QtScript gebruiken als basis voor app plugins?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Hyperz
  • Registratie: Augustus 2009
  • Laatst online: 09-07 02:45
Hoi :).

Ik ben onlangs begonnen met het aanleren van C++ en Qt, komende van C#. Nu zit ik al een tijdje met een probleem waar ik maar niet uit geraak, namelijk hoe kan ik QtScript gebruiken voor het toevoegen van plugin support in een applicatie? De app heeft een subfolder genaamd "scripts" waar meerdere javascript bestanden (plugins) geplaatst worden. Die plugins zien er zo uit:


JavaScript:
1
2
3
4
5
6
7
function Plugin()
{
    this.naam = "Mijn Plugin";
}

Plugin.prototype.doeIets = function() { /* ... */ }
Plugin.prototype.doeIetsAnders = function(arg1, arg2) { /* ... */ }


Iedere plugin heeft dus een naam en een eigen implementatie van de doeIets en doeIetsAnders functies. Om een plugin te laden doe ik het volgende in C++:


C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
engine = new QScriptEngine();
engine->importExtension("qt.core");
engine->importExtension("qt.network");

...

// plugin lezen en evalueren
QFile file("./scripts/plugin.js");
file.open(QFile::ReadOnly | QFile::Text);
engine->evaluate(file.readAll());
file.close()

QScriptValue instance = engine->globalObject().property("Plugin").construct();
QScriptValue naam = instance.property("naam");
QScriptValue doeIets = instance.property("doeIets");
QScriptValue doeIetsAnders = instance.property("doeIetsAnders");


So far so good. Ik heb toegang tot de naam property en ik kan de functies uitvoeren. Maar wat ik eigenlijk wil bereiken is een C++ class die iedentiek is aan het javascript Plugin object. Eerst dacht ik van een class te maken waar ik een QScriptValue (bvb de instance variable van hierboven) kan meegeven in de constructor en deze dan te gebruiken in de wrapper functies. Zoiets dus:


C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
PluginWrapper::PluginWrapper(const QScriptValue &value, QObject *parent) : QObject(parent)
{
    m_value = value;
}

QString PluginWrapper::naam()
{
    return m_value.property("naam").toString();
}

void PluginWrapper::doeIets()
{
    m_value.property("doeIets").call(m_value, QScriptValueList());
}

void PluginWrapper::doeIetsAnders(QString &arg1, QString &arg2)
{
    m_value.property("doeIetsAnders").call(m_value, QScriptValueList() << arg1 << arg2);
}


Maar dit lijkt me niet echt een goede oplossing (?), en QScriptValueList accepteert maar een paar Qt types. Nu is mijn vraag, wat is de beste manier om de javascript plugins toegankelijk te maken in C++? De Qt documentatie zegt ook niets over dit soort situaties en Google ook niet :(.

Iemand ervaring hiermee? Alvast bedankt :).

Asus P8P67 EVO | i5 2500k (4.8 GHz) | Sapphire HD 7970 Vapor-X GHz Ed. | 8 GB DDR3 1600 | 1 TB HDD


Acties:
  • 0 Henk 'm!

  • cenix
  • Registratie: September 2001
  • Laatst online: 16-09 20:24
Ik weet niet hoe het zit met deze methode, maar ik heb eens ooit C++/Qt objecten in JavaScript aanroepbaar gemaakt met een embedded web browser (zie QWebView - een webkit gebaseerde engine). Je kon daar met Q_DECLARE_METADATA oid eigen types maken. Je werkte daar met Q_PROPERTY en Q_INVOKABLE om properties en methoden aanroepbaar te maken.
Ik weet niet of het helpt voor jouw probleem maar het is het bekijken waard denk ik.

Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Javascript ondersteunt sowieso maar een paar types, vandaar dat QScriptValueList er ook zo weinig ondersteunt.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • Hyperz
  • Registratie: Augustus 2009
  • Laatst online: 09-07 02:45
cenix schreef op dinsdag 18 oktober 2011 @ 20:25:
Ik weet niet hoe het zit met deze methode, maar ik heb eens ooit C++/Qt objecten in JavaScript aanroepbaar gemaakt met een embedded web browser (zie QWebView - een webkit gebaseerde engine). Je kon daar met Q_DECLARE_METADATA oid eigen types maken. Je werkte daar met Q_PROPERTY en Q_INVOKABLE om properties en methoden aanroepbaar te maken.
Ik weet niet of het helpt voor jouw probleem maar het is het bekijken waard denk ik.
Voor zover ik kan zien is dat handig om C++ dingen in JS beschikbaar te maken. De Qt documentatie is hier ook redelijk duidelijk over. C++ classes in beschikbaar maken JS is niet zo moeilijk, maar custom JS classes (objects) beschikbaar maken in C++ lijkt een ander verhaal. Nergens kan ik daar info over vinden.
MSalters schreef op woensdag 19 oktober 2011 @ 00:40:
Javascript ondersteunt sowieso maar een paar types, vandaar dat QScriptValueList er ook zo weinig ondersteunt.
By default, maar niet als je C++/Qt types export naar JS of gebruik maakt van de standaard QtScript extensies.

Ik heb gisteren nog wat zitten Googelen en kwam het volgende tegen op stackoverflow: http://stackoverflow.com/...222/problems-with-qscript. Dit doet me vermoeden dat ik het probleem misschien kan oplossen d.m.v. prototype-based inheritance in JS. Bvb een PluginBase class aanmaken in C++ en deze exporten naar JS en dan iets doen als dit:

JavaScript:
1
2
Plugin.prototype = new PluginBase();
Plugin.prototype.constructor = Plugin;


En dan in C++ de Plugin instance casten naar PluginBase via qscriptvalue_cast(). Geen idee of dit werkt maar ik ga het eens proberen.

Asus P8P67 EVO | i5 2500k (4.8 GHz) | Sapphire HD 7970 Vapor-X GHz Ed. | 8 GB DDR3 1600 | 1 TB HDD