source: XmlTools2/trunk/xmlcustomcode.cpp@ 981

Last change on this file since 981 was 980, checked in by s10k, 11 years ago

XmlTools
Singleton implementation

File size: 5.1 KB
Line 
1#include "xmlcustomcode.h"
2
3XmlCustomCode* XmlCustomCode::uniqueInstance = NULL;
4
5QScriptValue echo(QScriptContext *context, QScriptEngine*)
6{
7 std::cout << context->argument(0).toString().toUtf8().constData() << std::endl;
8
9 return "";
10}
11
12XmlCustomCode::XmlCustomCode(): numThreads(omp_get_num_procs()*2)
13{
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);
19
20 QString jsxmlString;
21 QFile jsxmlfile(":/resources/libs/jsxml.js");
22
23 jsxmlfile.open(QFile::ReadOnly | QFile::Text);
24
25 jsxmlString=QTextStream(&jsxmlfile).readAll();
26
27 for(int i=0; i<this->numThreads; i++){
28 this->scriptEngines.append(new QScriptEngine());
29 this->jsFunctions.append(new QScriptValue());
30
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; })")));
36
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);
40
41 // Add the js library for XmlEditing
42 this->scriptEngines.at(i)->evaluate(jsxmlString);
43 }
44}
45
46XmlCustomCode* XmlCustomCode::getInstance(){
47
48 if (uniqueInstance==NULL){ // allow only one instance
49 uniqueInstance = new XmlCustomCode();
50 }
51
52 return uniqueInstance;
53}
54
55void 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++){
59 *this->jsFunctions[i]=this->scriptEngines.at(i)->evaluate("(function main() {"+jsString+"})");
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
68 // Single tread if small number of files
69 if(filesToProcess.size()<CUSTOM_FILES_PER_THREAD){
70 // Process all XmlFiles
71 for(int i=0; i<filesToProcess.size(); i++){
72
73 customCodeUnwinding(filesToProcess.at(i),currXmlFileString,*this->scriptEngines.at(0),begin,elapsed_secs,engineResult,
74 *this->jsFunctions.at(0),*this->getXmlDataFunctions.at(0),*this->setXmlDataFunctions.at(0),backupsEnabled,verboseEnabled);
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
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);
92
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);
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
103 customCodeUnwinding(filesToProcess.at(i),currXmlFileString,*this->scriptEngines.at(0),begin,elapsed_secs,engineResult,
104 *this->jsFunctions.at(0),*this->getXmlDataFunctions.at(0),*this->setXmlDataFunctions.at(0),backupsEnabled,verboseEnabled);
105 }
106 }
107 }
108}
109
110void 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}
Note: See TracBrowser for help on using the repository browser.