[964] | 1 | #include "xmlcustomcode.h"
|
---|
| 2 |
|
---|
[980] | 3 | XmlCustomCode* XmlCustomCode::uniqueInstance = NULL;
|
---|
[964] | 4 |
|
---|
| 5 | QScriptValue echo(QScriptContext *context, QScriptEngine*)
|
---|
| 6 | {
|
---|
| 7 | std::cout << context->argument(0).toString().toUtf8().constData() << std::endl;
|
---|
| 8 |
|
---|
| 9 | return "";
|
---|
| 10 | }
|
---|
| 11 |
|
---|
| 12 | XmlCustomCode::XmlCustomCode(): numThreads(omp_get_num_procs()*2)
|
---|
| 13 | {
|
---|
[980] | 14 | // create individual thread script engines
|
---|
| 15 | this->scriptEngines.reserve(this->numThreads);
|
---|
| 16 | this->jsFunctions.reserve(this->numThreads);
|
---|
| 17 | this->getXmlDataFunctions.reserve(this->numThreads);
|
---|
| 18 | this->setXmlDataFunctions.reserve(this->numThreads);
|
---|
[964] | 19 |
|
---|
[980] | 20 | QString jsxmlString;
|
---|
| 21 | QFile jsxmlfile(":/resources/libs/jsxml.js");
|
---|
[964] | 22 |
|
---|
[980] | 23 | jsxmlfile.open(QFile::ReadOnly | QFile::Text);
|
---|
[964] | 24 |
|
---|
[980] | 25 | jsxmlString=QTextStream(&jsxmlfile).readAll();
|
---|
[964] | 26 |
|
---|
[980] | 27 | for(int i=0; i<this->numThreads; i++){
|
---|
| 28 | this->scriptEngines.append(new QScriptEngine());
|
---|
| 29 | this->jsFunctions.append(new QScriptValue());
|
---|
[964] | 30 |
|
---|
[980] | 31 | // main needs to be called so the user code is evaluated
|
---|
| 32 | // alternatively you can do: myFunc=engine.evaluate('(function main(){})'); myFunc.call();
|
---|
| 33 | // Note the () around the function
|
---|
| 34 | this->getXmlDataFunctions.append(new QScriptValue(this->scriptEngines.at(i)->evaluate("(function getXmlData() { return $xmlData; })")));
|
---|
| 35 | this->setXmlDataFunctions.append(new QScriptValue(this->scriptEngines.at(i)->evaluate("(function setXmlData(newXmlData) { $xmlData=newXmlData; })")));
|
---|
[964] | 36 |
|
---|
[980] | 37 | // Add echo function so user can debug the code
|
---|
| 38 | QScriptValue echoFunction = this->scriptEngines.at(i)->newFunction(echo);
|
---|
| 39 | this->scriptEngines.at(i)->globalObject().setProperty("echo", echoFunction);
|
---|
[964] | 40 |
|
---|
[980] | 41 | // Add the js library for XmlEditing
|
---|
| 42 | this->scriptEngines.at(i)->evaluate(jsxmlString);
|
---|
[964] | 43 | }
|
---|
| 44 | }
|
---|
| 45 |
|
---|
[980] | 46 | XmlCustomCode* XmlCustomCode::getInstance(){
|
---|
| 47 |
|
---|
| 48 | if (uniqueInstance==NULL){ // allow only one instance
|
---|
| 49 | uniqueInstance = new XmlCustomCode();
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 | return uniqueInstance;
|
---|
| 53 | }
|
---|
| 54 |
|
---|
[964] | 55 | void XmlCustomCode::executeCustomCode(const QString &jsString, const QVector<QString> &filesToProcess, const bool backupsEnabled, const bool verboseEnabled){
|
---|
| 56 |
|
---|
| 57 | // Reconstruct script functions
|
---|
| 58 | for(int i=0; i<this->numThreads; i++){
|
---|
[967] | 59 | *this->jsFunctions[i]=this->scriptEngines.at(i)->evaluate("(function main() {"+jsString+"})");
|
---|
[964] | 60 | }
|
---|
| 61 |
|
---|
| 62 | QString currXmlFileString;
|
---|
| 63 |
|
---|
| 64 | QScriptValue engineResult; // variable to check for js_errors
|
---|
| 65 | double elapsed_secs=0; // elapsed seconds that a user script took
|
---|
| 66 | clock_t begin; // seconds that a script started
|
---|
| 67 |
|
---|
[967] | 68 | // Single tread if small number of files
|
---|
[964] | 69 | if(filesToProcess.size()<CUSTOM_FILES_PER_THREAD){
|
---|
| 70 | // Process all XmlFiles
|
---|
| 71 | for(int i=0; i<filesToProcess.size(); i++){
|
---|
| 72 |
|
---|
[967] | 73 | customCodeUnwinding(filesToProcess.at(i),currXmlFileString,*this->scriptEngines.at(0),begin,elapsed_secs,engineResult,
|
---|
[980] | 74 | *this->jsFunctions.at(0),*this->getXmlDataFunctions.at(0),*this->setXmlDataFunctions.at(0),backupsEnabled,verboseEnabled);
|
---|
[964] | 75 | }
|
---|
| 76 | }
|
---|
| 77 | else{ // Multithread if there are many files
|
---|
| 78 | // Process all XmlFiles
|
---|
| 79 | #pragma omp parallel for num_threads(this->numThreads) schedule(dynamic)
|
---|
| 80 | for(int i=0; i<filesToProcess.size()-CUSTOM_FILES_PER_THREAD; i+=CUSTOM_FILES_PER_THREAD){
|
---|
| 81 |
|
---|
| 82 | const int tid=omp_get_thread_num();
|
---|
| 83 |
|
---|
| 84 | QString currXmlFileStringThread;
|
---|
| 85 |
|
---|
| 86 | QScriptValue engineResultThread; // variable to check for js_errors
|
---|
| 87 | double elapsedSecsThread=0; // elapsed seconds that a user script took
|
---|
| 88 | clock_t beginThread; // seconds that a script started
|
---|
| 89 |
|
---|
[967] | 90 | customCodeUnwinding(filesToProcess.at(i),currXmlFileStringThread,*this->scriptEngines.at(tid),beginThread,elapsedSecsThread,engineResultThread,
|
---|
| 91 | *this->jsFunctions.at(tid),*this->getXmlDataFunctions.at(tid),*this->setXmlDataFunctions.at(tid),backupsEnabled,verboseEnabled);
|
---|
[964] | 92 |
|
---|
[967] | 93 | customCodeUnwinding(filesToProcess.at(i+1),currXmlFileStringThread,*this->scriptEngines.at(tid),beginThread,elapsedSecsThread,engineResultThread,
|
---|
| 94 | *this->jsFunctions.at(tid),*this->getXmlDataFunctions.at(tid),*this->setXmlDataFunctions.at(tid),backupsEnabled,verboseEnabled);
|
---|
[964] | 95 | }
|
---|
| 96 |
|
---|
| 97 | if(filesToProcess.size()%CUSTOM_FILES_PER_THREAD!=0){
|
---|
| 98 |
|
---|
| 99 | int alreadyProcessedFiles=(filesToProcess.size()/CUSTOM_FILES_PER_THREAD)*CUSTOM_FILES_PER_THREAD;
|
---|
| 100 |
|
---|
| 101 | for(int i=alreadyProcessedFiles; i<filesToProcess.size(); i++){
|
---|
| 102 |
|
---|
[967] | 103 | customCodeUnwinding(filesToProcess.at(i),currXmlFileString,*this->scriptEngines.at(0),begin,elapsed_secs,engineResult,
|
---|
[980] | 104 | *this->jsFunctions.at(0),*this->getXmlDataFunctions.at(0),*this->setXmlDataFunctions.at(0),backupsEnabled,verboseEnabled);
|
---|
[964] | 105 | }
|
---|
| 106 | }
|
---|
| 107 | }
|
---|
| 108 | }
|
---|
| 109 |
|
---|
| 110 | void XmlCustomCode::displayJsException(QScriptEngine &engine, QScriptValue &engineResult){
|
---|
| 111 | if (engine.hasUncaughtException()) {
|
---|
| 112 | UtilXmlTools::displayErrorMessage("@CUSTOM_CODE","Uncaught js exception (user code) at line " +QString::number(engine.uncaughtExceptionLineNumber()) + ":\n" + engineResult.toString());
|
---|
| 113 | }
|
---|
| 114 | }
|
---|