Subversion Repositories public iLand

Rev

Rev 1182 | Rev 1217 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1182 Rev 1204
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 <QtDebug>
24
#include <QtDebug>
25
//#include <QKeyEvent>
25
//#include <QKeyEvent>
26
26
27
#include "global.h"
27
#include "global.h"
28
#include "model.h"
28
#include "model.h"
29
#include "modelcontroller.h"
29
#include "modelcontroller.h"
30
#include "version.h"
30
#include "version.h"
31
31
32
QTextStream *ConsoleShell::mLogStream = 0;
32
QTextStream *ConsoleShell::mLogStream = 0;
33
bool ConsoleShell::mFlushLog = false;
33
bool ConsoleShell::mFlushLog = false;
34
34
35
// a try to really get keyboard strokes in console mode...
35
// a try to really get keyboard strokes in console mode...
36
// did not work.
36
// did not work.
37
class KeyboardTaker : public QThread
37
class KeyboardTaker : public QThread
38
 {
38
 {
39
 public:
39
 public:
40
     void run();
40
     void run();
41
     bool stop;
41
     bool stop;
42
 };
42
 };
43
43
44
 void KeyboardTaker::run()
44
 void KeyboardTaker::run()
45
 {
45
 {
46
     stop = false;
46
     stop = false;
47
     QTextStream qin(stdin, QFile::ReadOnly);
47
     QTextStream qin(stdin, QFile::ReadOnly);
48
     while (!stop) {
48
     while (!stop) {
49
         QString input = qin.read(1);
49
         QString input = qin.read(1);
50
         if (!input.isNull()) {
50
         if (!input.isNull()) {
51
             // .. process input
51
             // .. process input
52
             qWarning() << "input:" << input;
52
             qWarning() << "input:" << input;
53
         }
53
         }
54
     }
54
     }
55
 }
55
 }
56
56
57
ConsoleShell::ConsoleShell()
57
ConsoleShell::ConsoleShell()
58
{
58
{
59
}
59
}
60
60
61
/*
61
/*
62
*/
62
*/
63
63
64
void ConsoleShell::run()
64
void ConsoleShell::run()
65
{
65
{
66
66
67
    QString xml_name = QCoreApplication::arguments().at(1);
67
    QString xml_name = QCoreApplication::arguments().at(1);
68
    // get the number of years to run...
68
    // get the number of years to run...
69
    bool ok;
69
    bool ok;
70
    int years = QCoreApplication::arguments().at(2).toInt(&ok);
70
    int years = QCoreApplication::arguments().at(2).toInt(&ok);
71
    if (years<0 || !ok) {
71
    if (years<0 || !ok) {
72
        qDebug() << QCoreApplication::arguments().at(2) << "is an invalid number of years to run!";
72
        qDebug() << QCoreApplication::arguments().at(2) << "is an invalid number of years to run!";
73
        QCoreApplication::quit();
73
        QCoreApplication::quit();
74
        return;
74
        return;
75
    }
75
    }
76
76
77
    if (!QFile::exists(xml_name)) {
77
    if (!QFile::exists(xml_name)) {
78
        qDebug() << "invalid XML project file: " << xml_name;
78
        qDebug() << "invalid XML project file: " << xml_name;
79
        QCoreApplication::quit();
79
        QCoreApplication::quit();
80
        return;
80
        return;
81
    }
81
    }
82
    try {
82
    try {
83
83
84
        ModelController iland_model;
84
        ModelController iland_model;
85
        GlobalSettings::instance()->setModelController( &iland_model );
85
        GlobalSettings::instance()->setModelController( &iland_model );
86
        QObject::connect(&iland_model, SIGNAL(year(int)),SLOT(runYear(int)));
86
        QObject::connect(&iland_model, SIGNAL(year(int)),SLOT(runYear(int)));
87
        iland_model.setFileName(xml_name);
87
        iland_model.setFileName(xml_name);
88
        if (iland_model.hasError()) {
88
        if (iland_model.hasError()) {
89
            qWarning() << "!!!! ERROR !!!!";
89
            qWarning() << "!!!! ERROR !!!!";
90
            qWarning() << iland_model.lastError();
90
            qWarning() << iland_model.lastError();
91
            qWarning() << "!!!! ERROR !!!!";
91
            qWarning() << "!!!! ERROR !!!!";
92
            QCoreApplication::quit();
92
            QCoreApplication::quit();
93
            return;
93
            return;
94
        }
94
        }
95
95
96
        mParams.clear();
96
        mParams.clear();
97
        if (QCoreApplication::arguments().count()>3) {
97
        if (QCoreApplication::arguments().count()>3) {
98
            qWarning() << "set command line values:";
98
            qWarning() << "set command line values:";
99
            for (int i=3;i<QCoreApplication::arguments().count();++i) {
99
            for (int i=3;i<QCoreApplication::arguments().count();++i) {
100
                QString line = QCoreApplication::arguments().at(i);
100
                QString line = QCoreApplication::arguments().at(i);
101
                line = line.remove(QChar('"')); // drop quotes
101
                line = line.remove(QChar('"')); // drop quotes
102
                mParams.append(line);
102
                mParams.append(line);
103
                //qDebug() << qPrintable(line);
103
                //qDebug() << qPrintable(line);
104
                QString key = line.left(line.indexOf('='));
104
                QString key = line.left(line.indexOf('='));
105
                QString value = line.mid(line.indexOf('=')+1);
105
                QString value = line.mid(line.indexOf('=')+1);
106
                const_cast<XmlHelper&>(GlobalSettings::instance()->settings()).setNodeValue(key, value);
106
                const_cast<XmlHelper&>(GlobalSettings::instance()->settings()).setNodeValue(key, value);
107
                qWarning() << QString("set '%1' to value '%2'. result: '%3'").arg(key).arg(value).arg(GlobalSettings::instance()->settings().value(key));
107
                qWarning() << QString("set '%1' to value '%2'. result: '%3'").arg(key).arg(value).arg(GlobalSettings::instance()->settings().value(key));
108
            }
108
            }
109
        }
109
        }
110
        setupLogging();
110
        setupLogging();
111
111
112
        qDebug() << "**************************************************";
112
        qDebug() << "**************************************************";
113
        qDebug() << "***********     iLand console session     ********";
113
        qDebug() << "***********     iLand console session     ********";
114
        qDebug() << "**************************************************";
-
 
115
        qDebug() << "started at: " << QDateTime::currentDateTime().toString("hh:mm:ss");
-
 
116
        qDebug() << "iLand " << currentVersion() << " (" << svnRevision() << ")";
-
 
117
        qDebug() << "**************************************************";
114
        qDebug() << "**************************************************";
118
115
119
        qWarning() << "*** creating model...";
116
        qWarning() << "*** creating model...";
120
        qWarning() << "**************************************************";
117
        qWarning() << "**************************************************";
121
118
122
        iland_model.create();
119
        iland_model.create();
123
        if (iland_model.hasError()) {
120
        if (iland_model.hasError()) {
124
            qWarning() << "!!!! ERROR !!!!";
121
            qWarning() << "!!!! ERROR !!!!";
125
            qWarning() << iland_model.lastError();
122
            qWarning() << iland_model.lastError();
126
            qWarning() << "!!!! ERROR !!!!";
123
            qWarning() << "!!!! ERROR !!!!";
127
            QCoreApplication::quit();
124
            QCoreApplication::quit();
128
            return;
125
            return;
129
        }
126
        }
130
        runJavascript("onCreate");
127
        runJavascript("onCreate");
131
        qWarning() << "**************************************************";
128
        qWarning() << "**************************************************";
132
        qWarning() << "*** running model for" << years << "years";
129
        qWarning() << "*** running model for" << years << "years";
133
        qWarning() << "**************************************************";
130
        qWarning() << "**************************************************";
134
131
135
        iland_model.run(years + 1);
132
        iland_model.run(years + 1);
136
        if (iland_model.hasError()) {
133
        if (iland_model.hasError()) {
137
            qWarning() << "!!!! ERROR !!!!";
134
            qWarning() << "!!!! ERROR !!!!";
138
            qWarning() << iland_model.lastError();
135
            qWarning() << iland_model.lastError();
139
            qWarning() << "!!!! ERROR !!!!";
136
            qWarning() << "!!!! ERROR !!!!";
140
            QCoreApplication::quit();
137
            QCoreApplication::quit();
141
            return;
138
            return;
142
        }
139
        }
143
        runJavascript("onFinish");
140
        runJavascript("onFinish");
144
141
145
        qWarning() << "**************************************************";
142
        qWarning() << "**************************************************";
146
        qWarning() << "*** model run finished.";
143
        qWarning() << "*** model run finished.";
147
        qWarning() << "**************************************************";
144
        qWarning() << "**************************************************";
148
145
149
    } catch (const IException &e) {
146
    } catch (const IException &e) {
150
        qWarning() << "*** An exception occured ***";
147
        qWarning() << "*** An exception occured ***";
151
        qWarning() << e.message();
148
        qWarning() << e.message();
152
    }
149
    }
153
    catch (const std::exception &e) {
150
    catch (const std::exception &e) {
154
        qWarning() << "*** An (std)exception occured ***";
151
        qWarning() << "*** An (std)exception occured ***";
155
        qWarning() << e.what();
152
        qWarning() << e.what();
156
    }
153
    }
157
    QCoreApplication::quit();
154
    QCoreApplication::quit();
158
155
159
156
160
}
157
}
161
158
162
void ConsoleShell::runYear(int year)
159
void ConsoleShell::runYear(int year)
163
{
160
{
164
    printf("%s: simulating year %d ...\n", QDateTime::currentDateTime().toString("hh:mm:ss").toLocal8Bit().data(), year-1);
161
    printf("%s: simulating year %d ...\n", QDateTime::currentDateTime().toString("hh:mm:ss").toLocal8Bit().data(), year-1);
165
}
162
}
166
163
167
static QMutex qdebug_mutex;
164
static QMutex qdebug_mutex;
168
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
165
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
169
 {
166
 {
170
    Q_UNUSED(context);
167
    Q_UNUSED(context);
171
    QMutexLocker m(&qdebug_mutex);
168
    QMutexLocker m(&qdebug_mutex);
172
169
173
    switch (type) {
170
    switch (type) {
174
    case QtDebugMsg:
171
    case QtDebugMsg:
175
        *ConsoleShell::logStream() << msg << endl;
172
        *ConsoleShell::logStream() << msg << endl;
176
        if (ConsoleShell::flush())
173
        if (ConsoleShell::flush())
177
            ConsoleShell::logStream()->flush();
174
            ConsoleShell::logStream()->flush();
178
        break;
175
        break;
179
    case QtWarningMsg:
176
    case QtWarningMsg:
180
        *ConsoleShell::logStream() << msg << endl;
177
        *ConsoleShell::logStream() << msg << endl;
181
        if (ConsoleShell::flush())
178
        if (ConsoleShell::flush())
182
            ConsoleShell::logStream()->flush();
179
            ConsoleShell::logStream()->flush();
183
        printf("%s: %s\n", QDateTime::currentDateTime().toString("hh:mm:ss").toLocal8Bit().data(), msg.toLocal8Bit().data());
180
        printf("%s: %s\n", QDateTime::currentDateTime().toString("hh:mm:ss").toLocal8Bit().data(), msg.toLocal8Bit().data());
184
        break;
181
        break;
185
// available from qt5.5
182
// available from qt5.5
186
//    case QtInfoMsg:
183
//    case QtInfoMsg:
187
//        *ConsoleShell::logStream() << msg << endl;
184
//        *ConsoleShell::logStream() << msg << endl;
188
//        if (ConsoleShell::flush())
185
//        if (ConsoleShell::flush())
189
//            ConsoleShell::logStream()->flush();
186
//            ConsoleShell::logStream()->flush();
190
//        printf("%s: %s\n", QDateTime::currentDateTime().toString("hh:mm:ss").toLocal8Bit().data(), msg.toLocal8Bit().data());
187
//        printf("%s: %s\n", QDateTime::currentDateTime().toString("hh:mm:ss").toLocal8Bit().data(), msg.toLocal8Bit().data());
191
188
192
//        break;
189
//        break;
193
    case QtCriticalMsg:
190
    case QtCriticalMsg:
194
        *ConsoleShell::logStream() << msg << endl;
191
        *ConsoleShell::logStream() << msg << endl;
195
        if (ConsoleShell::flush())
192
        if (ConsoleShell::flush())
196
            ConsoleShell::logStream()->flush();
193
            ConsoleShell::logStream()->flush();
197
        printf("Critical: %s\n", msg.toLocal8Bit().data());
194
        printf("Critical: %s\n", msg.toLocal8Bit().data());
198
        break;
195
        break;
199
    case QtFatalMsg:
196
    case QtFatalMsg:
200
        *ConsoleShell::logStream() << msg << endl;
197
        *ConsoleShell::logStream() << msg << endl;
201
        if (ConsoleShell::flush())
198
        if (ConsoleShell::flush())
202
            ConsoleShell::logStream()->flush();
199
            ConsoleShell::logStream()->flush();
203
        printf("Fatal: %s\n", msg.toLocal8Bit().data());
200
        printf("Fatal: %s\n", msg.toLocal8Bit().data());
204
    }
201
    }
205
 }
202
 }
206
203
207
204
208
void ConsoleShell::setupLogging()
205
void ConsoleShell::setupLogging()
209
{
206
{
210
    if (mLogStream) {
207
    if (mLogStream) {
211
        if (mLogStream->device())
208
        if (mLogStream->device())
212
            delete mLogStream->device();
209
            delete mLogStream->device();
213
        delete mLogStream;
210
        delete mLogStream;
214
        mLogStream = NULL;
211
        mLogStream = NULL;
215
    }
212
    }
216
213
217
    QString fname = GlobalSettings::instance()->settings().value("system.logging.logFile", "logfile.txt");
214
    QString fname = GlobalSettings::instance()->settings().value("system.logging.logFile", "logfile.txt");
218
    mFlushLog = GlobalSettings::instance()->settings().valueBool("system.logging.flush");
215
    mFlushLog = GlobalSettings::instance()->settings().valueBool("system.logging.flush");
219
    QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss");
216
    QString timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss");
220
    fname.replace("$date$", timestamp);
217
    fname.replace("$date$", timestamp);
221
    fname = GlobalSettings::instance()->path(fname, "log");
218
    fname = GlobalSettings::instance()->path(fname, "log");
222
    QFile *file = new QFile(fname);
219
    QFile *file = new QFile(fname);
223
220
224
    if (!file->open(QIODevice::WriteOnly)) {
221
    if (!file->open(QIODevice::WriteOnly)) {
225
        qDebug() << "cannot open logfile" << fname;
222
        qDebug() << "cannot open logfile" << fname;
226
    } else {
223
    } else {
227
        qDebug() << "Log output is redirected to logfile" << fname;
224
        qDebug() << "Log output is redirected to logfile" << fname;
228
        mLogStream = new QTextStream(file);
225
        mLogStream = new QTextStream(file);
229
    }
226
    }
230
    qInstallMessageHandler(myMessageOutput);
227
    qInstallMessageHandler(myMessageOutput);
231
228
232
229
233
}
230
}
234
231
235
void ConsoleShell::runJavascript(const QString key)
232
void ConsoleShell::runJavascript(const QString key)
236
{
233
{
237
    for (int i=0;i<mParams.count(); ++i) {
234
    for (int i=0;i<mParams.count(); ++i) {
238
        QString line=mParams[i];
235
        QString line=mParams[i];
239
        QString pkey = line.left(line.indexOf('='));
236
        QString pkey = line.left(line.indexOf('='));
240
        if (pkey == key) {
237
        if (pkey == key) {
241
            QString command = line.mid(line.indexOf('=')+1);
238
            QString command = line.mid(line.indexOf('=')+1);
242
            // execute the function
239
            // execute the function
243
            qWarning() << "executing trigger" << key;
240
            qWarning() << "executing trigger" << key;
244
            qWarning() << GlobalSettings::instance()->executeJavascript(command);
241
            qWarning() << GlobalSettings::instance()->executeJavascript(command);
245
        }
242
        }
246
    }
243
    }
247
244
248
245
249
}
246
}
250
247
251
 
248