Rev 1075 | Rev 1087 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1075 | Rev 1081 | ||
---|---|---|---|
1 | Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/ilandc/consoleshell.cpp': |
1 | Redirecting to URL 'https://iland.boku.ac.at/svn/iland/tags/release_1.0/src/ilandc/consoleshell.cpp': |
2 | /********************************************************************************************
|
2 | /********************************************************************************************
|
3 | ** iLand - an individual based forest landscape and disturbance model
|
3 | ** iLand - an individual based forest landscape and disturbance model
|
4 | ** http://iland.boku.ac.at
|
4 | ** http://iland.boku.ac.at
|
5 | ** Copyright (C) 2009- Werner Rammer, Rupert Seidl
|
5 | ** Copyright (C) 2009- Werner Rammer, Rupert Seidl
|
6 | **
|
6 | **
|
7 | ** This program is free software: you can redistribute it and/or modify
|
7 | ** This program is free software: you can redistribute it and/or modify
|
8 | ** it under the terms of the GNU General Public License as published by
|
8 | ** it under the terms of the GNU General Public License as published by
|
9 | ** the Free Software Foundation, either version 3 of the License, or
|
9 | ** the Free Software Foundation, either version 3 of the License, or
|
10 | ** (at your option) any later version.
|
10 | ** (at your option) any later version.
|
11 | **
|
11 | **
|
12 | ** This program is distributed in the hope that it will be useful,
|
12 | ** This program is distributed in the hope that it will be useful,
|
13 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 | ** GNU General Public License for more details.
|
15 | ** GNU General Public License for more details.
|
16 | **
|
16 | **
|
17 | ** You should have received a copy of the GNU General Public License
|
17 | ** You should have received a copy of the GNU General Public License
|
18 | ** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18 | ** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19 | ********************************************************************************************/
|
19 | ********************************************************************************************/
|
20 | 20 | ||
21 | #include "consoleshell.h"
|
21 | #include "consoleshell.h"
|
22 | 22 | ||
23 | #include <QtCore>
|
23 | #include <QtCore>
|
24 | //#include <QKeyEvent>
|
24 | //#include <QKeyEvent>
|
25 | 25 | ||
26 | #include "global.h"
|
26 | #include "global.h"
|
27 | #include "model.h"
|
27 | #include "model.h"
|
28 | #include "modelcontroller.h"
|
28 | #include "modelcontroller.h"
|
29 | #include "../iland/version.h"
|
29 | #include "../iland/version.h"
|
30 | 30 | ||
31 | QTextStream *ConsoleShell::mLogStream = 0; |
31 | QTextStream *ConsoleShell::mLogStream = 0; |
32 | 32 | ||
33 | // a try to really get keyboard strokes in console mode...
|
33 | // a try to really get keyboard strokes in console mode...
|
34 | // did not work.
|
34 | // did not work.
|
35 | class KeyboardTaker : public QThread |
35 | class KeyboardTaker : public QThread |
36 | {
|
36 | {
|
37 | public: |
37 | public: |
38 | void run(); |
38 | void run(); |
39 | bool stop; |
39 | bool stop; |
40 | }; |
40 | }; |
41 | 41 | ||
42 | void KeyboardTaker::run() |
42 | void KeyboardTaker::run() |
43 | {
|
43 | {
|
44 | stop = false; |
44 | stop = false; |
45 | QTextStream qin(stdin, QFile::ReadOnly); |
45 | QTextStream qin(stdin, QFile::ReadOnly); |
46 | while (!stop) { |
46 | while (!stop) { |
47 | QString input = qin.read(1); |
47 | QString input = qin.read(1); |
48 | if (!input.isNull()) { |
48 | if (!input.isNull()) { |
49 | // .. process input
|
49 | // .. process input
|
50 | qWarning() << "input:" << input; |
50 | qWarning() << "input:" << input; |
51 | }
|
51 | }
|
52 | }
|
52 | }
|
53 | }
|
53 | }
|
54 | 54 | ||
55 | ConsoleShell::ConsoleShell() |
55 | ConsoleShell::ConsoleShell() |
56 | {
|
56 | {
|
57 | }
|
57 | }
|
58 | 58 | ||
59 | /*
|
59 | /*
|
60 | */
|
60 | */
|
61 | 61 | ||
62 | void ConsoleShell::run() |
62 | void ConsoleShell::run() |
63 | {
|
63 | {
|
64 | 64 | ||
65 | QString xml_name = QCoreApplication::arguments().at(1); |
65 | QString xml_name = QCoreApplication::arguments().at(1); |
66 | // get the number of years to run...
|
66 | // get the number of years to run...
|
67 | bool ok; |
67 | bool ok; |
68 | int years = QCoreApplication::arguments().at(2).toInt(&ok); |
68 | int years = QCoreApplication::arguments().at(2).toInt(&ok); |
69 | if (years<0 || !ok) { |
69 | if (years<0 || !ok) { |
70 | qDebug() << QCoreApplication::arguments().at(2) << "is an invalid number of years to run!"; |
70 | qDebug() << QCoreApplication::arguments().at(2) << "is an invalid number of years to run!"; |
71 | QCoreApplication::quit(); |
71 | QCoreApplication::quit(); |
72 | return; |
72 | return; |
73 | }
|
73 | }
|
74 | 74 | ||
75 | if (!QFile::exists(xml_name)) { |
75 | if (!QFile::exists(xml_name)) { |
76 | qDebug() << "invalid XML project file: " << xml_name; |
76 | qDebug() << "invalid XML project file: " << xml_name; |
77 | QCoreApplication::quit(); |
77 | QCoreApplication::quit(); |
78 | return; |
78 | return; |
79 | }
|
79 | }
|
80 | try { |
80 | try { |
81 | 81 | ||
82 | ModelController iland_model;
|
82 | ModelController iland_model;
|
- | 83 | GlobalSettings::instance()->setModelController( &iland_model ); |
|
83 | QObject::connect(&iland_model, SIGNAL(year(int)),SLOT(runYear(int))); |
84 | QObject::connect(&iland_model, SIGNAL(year(int)),SLOT(runYear(int))); |
84 | iland_model.setFileName(xml_name); |
85 | iland_model.setFileName(xml_name); |
85 | if (iland_model.hasError()) { |
86 | if (iland_model.hasError()) { |
86 | qWarning() << "!!!! ERROR !!!!"; |
87 | qWarning() << "!!!! ERROR !!!!"; |
87 | qWarning() << iland_model.lastError(); |
88 | qWarning() << iland_model.lastError(); |
88 | qWarning() << "!!!! ERROR !!!!"; |
89 | qWarning() << "!!!! ERROR !!!!"; |
89 | QCoreApplication::quit(); |
90 | QCoreApplication::quit(); |
90 | return; |
91 | return; |
91 | }
|
92 | }
|
92 | 93 | ||
93 | mParams.clear(); |
94 | mParams.clear(); |
94 | if (QCoreApplication::arguments().count()>3) { |
95 | if (QCoreApplication::arguments().count()>3) { |
95 | qWarning() << "set command line values:"; |
96 | qWarning() << "set command line values:"; |
96 | for (int i=3;i<QCoreApplication::arguments().count();++i) { |
97 | for (int i=3;i<QCoreApplication::arguments().count();++i) { |
97 | QString line = QCoreApplication::arguments().at(i); |
98 | QString line = QCoreApplication::arguments().at(i); |
98 | mParams.append(line); |
99 | mParams.append(line); |
99 | QString key = line.left(line.indexOf('=')); |
100 | QString key = line.left(line.indexOf('=')); |
100 | QString value = line.mid(line.indexOf('=')+1); |
101 | QString value = line.mid(line.indexOf('=')+1); |
101 | const_cast<XmlHelper&>(GlobalSettings::instance()->settings()).setNodeValue(key, value); |
102 | const_cast<XmlHelper&>(GlobalSettings::instance()->settings()).setNodeValue(key, value); |
102 | qWarning() << "set" << key << "to value:" << value << "(set:" << GlobalSettings::instance()->settings().value(key) << ")."; |
103 | qWarning() << "set" << key << "to value:" << value << "(set:" << GlobalSettings::instance()->settings().value(key) << ")."; |
103 | }
|
104 | }
|
104 | }
|
105 | }
|
105 | setupLogging(); |
106 | setupLogging(); |
106 | 107 | ||
107 | qDebug() << "**************************************************"; |
108 | qDebug() << "**************************************************"; |
108 | qDebug() << "*********** iLand console session ********"; |
109 | qDebug() << "*********** iLand console session ********"; |
109 | qDebug() << "**************************************************"; |
110 | qDebug() << "**************************************************"; |
110 | qDebug() << "started at: " << QDateTime::currentDateTime().toString(Qt::ISODate); |
111 | qDebug() << "started at: " << QDateTime::currentDateTime().toString(Qt::ISODate); |
111 | qDebug() << "iLand " << currentVersion() << " (" << svnRevision() << ")"; |
112 | qDebug() << "iLand " << currentVersion() << " (" << svnRevision() << ")"; |
112 | qDebug() << "**************************************************"; |
113 | qDebug() << "**************************************************"; |
113 | 114 | ||
114 | qWarning() << "*** creating model..."; |
115 | qWarning() << "*** creating model..."; |
115 | qWarning() << "**************************************************"; |
116 | qWarning() << "**************************************************"; |
116 | 117 | ||
117 | iland_model.create(); |
118 | iland_model.create(); |
118 | if (iland_model.hasError()) { |
119 | if (iland_model.hasError()) { |
119 | qWarning() << "!!!! ERROR !!!!"; |
120 | qWarning() << "!!!! ERROR !!!!"; |
120 | qWarning() << iland_model.lastError(); |
121 | qWarning() << iland_model.lastError(); |
121 | qWarning() << "!!!! ERROR !!!!"; |
122 | qWarning() << "!!!! ERROR !!!!"; |
122 | QCoreApplication::quit(); |
123 | QCoreApplication::quit(); |
123 | return; |
124 | return; |
124 | }
|
125 | }
|
125 | runJavascript("onCreate"); |
126 | runJavascript("onCreate"); |
126 | qWarning() << "**************************************************"; |
127 | qWarning() << "**************************************************"; |
127 | qWarning() << "*** running model for" << years << "years"; |
128 | qWarning() << "*** running model for" << years << "years"; |
128 | qWarning() << "**************************************************"; |
129 | qWarning() << "**************************************************"; |
129 | 130 | ||
130 | iland_model.run(years + 1); |
131 | iland_model.run(years + 1); |
131 | if (iland_model.hasError()) { |
132 | if (iland_model.hasError()) { |
132 | qWarning() << "!!!! ERROR !!!!"; |
133 | qWarning() << "!!!! ERROR !!!!"; |
133 | qWarning() << iland_model.lastError(); |
134 | qWarning() << iland_model.lastError(); |
134 | qWarning() << "!!!! ERROR !!!!"; |
135 | qWarning() << "!!!! ERROR !!!!"; |
135 | QCoreApplication::quit(); |
136 | QCoreApplication::quit(); |
136 | return; |
137 | return; |
137 | }
|
138 | }
|
138 | runJavascript("onFinish"); |
139 | runJavascript("onFinish"); |
139 | 140 | ||
140 | qWarning() << "**************************************************"; |
141 | qWarning() << "**************************************************"; |
141 | qWarning() << "*** model run finished."; |
142 | qWarning() << "*** model run finished."; |
142 | qWarning() << "*** " << QDateTime::currentDateTime(); |
143 | qWarning() << "*** " << QDateTime::currentDateTime(); |
143 | qWarning() << "**************************************************"; |
144 | qWarning() << "**************************************************"; |
144 | 145 | ||
145 | } catch (const IException &e) { |
146 | } catch (const IException &e) { |
146 | qWarning() << "*** An exception occured ***"; |
147 | qWarning() << "*** An exception occured ***"; |
147 | qWarning() << e.message(); |
148 | qWarning() << e.message(); |
148 | }
|
149 | }
|
149 | catch (const std::exception &e) { |
150 | catch (const std::exception &e) { |
150 | qWarning() << "*** An (std)exception occured ***"; |
151 | qWarning() << "*** An (std)exception occured ***"; |
151 | qWarning() << e.what(); |
152 | qWarning() << e.what(); |
152 | }
|
153 | }
|
153 | QCoreApplication::quit(); |
154 | QCoreApplication::quit(); |
154 | 155 | ||
155 | 156 | ||
156 | }
|
157 | }
|
157 | 158 | ||
158 | void ConsoleShell::runYear(int year) |
159 | void ConsoleShell::runYear(int year) |
159 | {
|
160 | {
|
160 | printf("simulating year %d ...\n", year-1); |
161 | printf("simulating year %d ...\n", year-1); |
161 | }
|
162 | }
|
162 | 163 | ||
163 | QMutex qdebug_mutex;
|
164 | QMutex qdebug_mutex;
|
164 | void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) |
165 | void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) |
165 | {
|
166 | {
|
166 | Q_UNUSED(context); |
167 | Q_UNUSED(context); |
167 | QMutexLocker m(&qdebug_mutex); |
168 | QMutexLocker m(&qdebug_mutex); |
168 | 169 | ||
169 | switch (type) { |
170 | switch (type) { |
170 | case QtDebugMsg: |
171 | case QtDebugMsg: |
171 | *ConsoleShell::logStream() << msg << endl; |
172 | *ConsoleShell::logStream() << msg << endl; |
172 | break; |
173 | break; |
173 | case QtWarningMsg: |
174 | case QtWarningMsg: |
174 | *ConsoleShell::logStream() << msg << endl; |
175 | *ConsoleShell::logStream() << msg << endl; |
175 | printf("Warning: %s\n", msg.toLocal8Bit().data()); |
176 | printf("Warning: %s\n", msg.toLocal8Bit().data()); |
176 | 177 | ||
177 | break; |
178 | break; |
178 | case QtCriticalMsg: |
179 | case QtCriticalMsg: |
179 | *ConsoleShell::logStream() << msg << endl; |
180 | *ConsoleShell::logStream() << msg << endl; |
180 | printf("Critical: %s\n", msg.toLocal8Bit().data()); |
181 | printf("Critical: %s\n", msg.toLocal8Bit().data()); |
181 | break; |
182 | break; |
182 | case QtFatalMsg: |
183 | case QtFatalMsg: |
183 | *ConsoleShell::logStream() << msg << endl; |
184 | *ConsoleShell::logStream() << msg << endl; |
184 | printf("Fatal: %s\n", msg.toLocal8Bit().data()); |
185 | printf("Fatal: %s\n", msg.toLocal8Bit().data()); |
185 | }
|
186 | }
|
186 | }
|
187 | }
|
187 | 188 | ||
188 | 189 | ||
189 | void ConsoleShell::setupLogging() |
190 | void ConsoleShell::setupLogging() |
190 | {
|
191 | {
|
191 | if (mLogStream) { |
192 | if (mLogStream) { |
192 | if (mLogStream->device()) |
193 | if (mLogStream->device()) |
193 | delete mLogStream->device(); |
194 | delete mLogStream->device(); |
194 | delete mLogStream; |
195 | delete mLogStream; |
195 | mLogStream = NULL; |
196 | mLogStream = NULL; |
196 | }
|
197 | }
|
197 | 198 | ||
198 | QString fname = GlobalSettings::instance()->settings().value("system.logging.logFile", "logfile.txt"); |
199 | QString fname = GlobalSettings::instance()->settings().value("system.logging.logFile", "logfile.txt"); |
199 | QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss"); |
200 | QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss"); |
200 | fname.replace("$date$", timestamp); |
201 | fname.replace("$date$", timestamp); |
201 | fname = GlobalSettings::instance()->path(fname, "log"); |
202 | fname = GlobalSettings::instance()->path(fname, "log"); |
202 | QFile *file = new QFile(fname); |
203 | QFile *file = new QFile(fname); |
203 | 204 | ||
204 | if (!file->open(QIODevice::WriteOnly)) { |
205 | if (!file->open(QIODevice::WriteOnly)) { |
205 | qDebug() << "cannot open logfile" << fname; |
206 | qDebug() << "cannot open logfile" << fname; |
206 | } else { |
207 | } else { |
207 | qDebug() << "Log output is redirected to logfile" << fname; |
208 | qDebug() << "Log output is redirected to logfile" << fname; |
208 | mLogStream = new QTextStream(file); |
209 | mLogStream = new QTextStream(file); |
209 | }
|
210 | }
|
210 | qInstallMessageHandler(myMessageOutput); |
211 | qInstallMessageHandler(myMessageOutput); |
211 | 212 | ||
212 | 213 | ||
213 | }
|
214 | }
|
214 | 215 | ||
215 | void ConsoleShell::runJavascript(const QString key) |
216 | void ConsoleShell::runJavascript(const QString key) |
216 | {
|
217 | {
|
217 | for (int i=0;i<mParams.count(); ++i) { |
218 | for (int i=0;i<mParams.count(); ++i) { |
218 | QString line=mParams[i]; |
219 | QString line=mParams[i]; |
219 | QString pkey = line.left(line.indexOf('=')); |
220 | QString pkey = line.left(line.indexOf('=')); |
220 | if (pkey == key) { |
221 | if (pkey == key) { |
221 | QString command = line.mid(line.indexOf('=')+1); |
222 | QString command = line.mid(line.indexOf('=')+1); |
222 | // execute the function
|
223 | // execute the function
|
223 | qWarning() << "executing trigger" << key; |
224 | qWarning() << "executing trigger" << key; |
224 | qWarning() << GlobalSettings::instance()->executeJavascript(command); |
225 | qWarning() << GlobalSettings::instance()->executeJavascript(command); |
225 | }
|
226 | }
|
226 | }
|
227 | }
|
227 | 228 | ||
228 | 229 | ||
229 | }
|
230 | }
|
230 | 231 | ||
231 | 232 |