source: XmlTools2/trunk/xmlcustomcode.cpp@ 966

Last change on this file since 966 was 964, checked in by s10k, 11 years ago

XmlTools
More speedup, about 3 times faster now than the current AEI build

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